Creating table in canvas / Phaser 3 (Priority) - html5-canvas

Can any body help with How to create Tables in Phaser-3(Priority) / Canvas.
Table like this.
Without styling is also ok. Just I want to know how we can create table in Phaser-3(Priority) / Canvas.

You can try to Rex UI Plugin
Here you can find a DEMO
Other demos (scrolling, fix-width-sizer and so on..) available HERE.
HTML
<footer><div id=version></div></footer>
CSS
html, body {
height: 100%;
}
body {
margin: 0;
padding: 0;
background: #222;
color: #eee;
font: caption;
}
#version {
position: absolute;
left: 5px;
top: 605px;
}
JS
const Random = Phaser.Math.Between;
const COLOR_PRIMARY = 0x4e342e;
const COLOR_LIGHT = 0x7b5e57;
const COLOR_DARK = 0x260e04;
class Demo extends Phaser.Scene {
constructor() {
super({
key: 'examples'
})
}
preload() {
this.load.scenePlugin({
key: 'rexuiplugin',
url: 'https://raw.githubusercontent.com/rexrainbow/phaser3-rex-notes/master/plugins/dist/rexuiplugin.min.js',
sceneKey: 'rexUI'
});
}
create() {
this.print = this.add.text(0, 0, '');
var db = createDataBase(400);
var tabs = this.rexUI.add.tabs({
x: 400,
y: 300,
panel: this.rexUI.add.gridTable({
background: this.rexUI.add.roundRectangle(0, 0, 20, 10, 10, COLOR_PRIMARY),
table: {
width: 250,
height: 400,
cellWidth: 120,
cellHeight: 60,
columns: 2,
mask: {
padding: 2,
},
},
slider: {
track: this.rexUI.add.roundRectangle(0, 0, 20, 10, 10, COLOR_DARK),
thumb: this.rexUI.add.roundRectangle(0, 0, 0, 0, 13, COLOR_LIGHT),
},
// scroller: true,
createCellContainerCallback: function (cell) {
var scene = cell.scene,
width = cell.width,
height = cell.height,
item = cell.item,
index = cell.index;
return scene.rexUI.add.label({
width: width,
height: height,
background: scene.rexUI.add.roundRectangle(0, 0, 20, 20, 0).setStrokeStyle(2, COLOR_DARK),
icon: scene.rexUI.add.roundRectangle(0, 0, 20, 20, 10, item.color),
text: scene.add.text(0, 0, item.id),
space: {
icon: 10,
left: 15
}
});
},
}),
leftButtons: [
createButton(this, 2, 'AA'),
createButton(this, 2, 'BB'),
createButton(this, 2, 'CC'),
createButton(this, 2, 'DD'),
],
rightButtons: [
createButton(this, 0, '+'),
createButton(this, 0, '-'),
],
space: {
leftButtonsOffset: 20,
rightButtonsOffset: 30,
leftButton: 1,
},
})
.layout()
//.drawBounds(this.add.graphics(), 0xff0000);
tabs
.on('button.click', function (button, groupName, index) {
switch (groupName) {
case 'left':
// Highlight button
if (this._prevTypeButton) {
this._prevTypeButton.getElement('background').setFillStyle(COLOR_DARK)
}
button.getElement('background').setFillStyle(COLOR_PRIMARY);
this._prevTypeButton = button;
if (this._prevSortButton === undefined) {
return;
}
break;
case 'right':
// Highlight button
if (this._prevSortButton) {
this._prevSortButton.getElement('background').setFillStyle(COLOR_DARK)
}
button.getElement('background').setFillStyle(COLOR_PRIMARY);
this._prevSortButton = button;
if (this._prevTypeButton === undefined) {
return;
}
break;
}
// Load items into grid table
var items = db
.chain()
.find({
type: this._prevTypeButton.text
})
.simplesort('id', {
desc: (this._prevSortButton.text === '-') // sort descending
})
.data();
this.getElement('panel').setItems(items).scrollToTop();
}, tabs);
// Grid table
tabs.getElement('panel')
.on('cell.click', function (cellContainer, cellIndex) {
this.print.text += cellIndex + ': ' + cellContainer.text + '\n';
}, this)
.on('cell.over', function (cellContainer, cellIndex) {
cellContainer.getElement('background')
.setStrokeStyle(2, COLOR_LIGHT)
.setDepth(1);
}, this)
.on('cell.out', function (cellContainer, cellIndex) {
cellContainer.getElement('background')
.setStrokeStyle(2, COLOR_DARK)
.setDepth(0);
}, this);
tabs.emitButtonClick('left', 0).emitButtonClick('right', 0);
}
update() {}
}
var createDataBase = function (count) {
var TYPE = ['AA', 'BB', 'CC', 'DD'];
// Create the database
var db = new loki();
// Create a collection
var items = db.addCollection('items');
// Insert documents
for (var i = 0; i < count; i++) {
items.insert({
type: TYPE[i % 4],
id: i,
color: Random(0, 0xffffff)
});
}
return items;
};
var createButton = function (scene, direction, text) {
var radius;
switch (direction) {
case 0: // Right
radius = {
tr: 20,
br: 20
}
break;
case 2: // Left
radius = {
tl: 20,
bl: 20
}
break;
}
return scene.rexUI.add.label({
width: 50,
height:40,
background: scene.rexUI.add.roundRectangle(0, 0, 50, 50, radius, COLOR_DARK),
text: scene.add.text(0, 0, text, {
fontSize: '18pt'
}),
space: {
left: 10
}
});
}
var config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
scene: Demo
};
var game = new Phaser.Game(config);

Related

Phaser 3.17 doesn't setect collision between tilemap layer and player sprite

No collisions between map layer and player sprite. But collisions between world bounds work. What is wrong?
I tried different workarounds that could find online and none of them worked.
Game config
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: "#f",
physics: {
default: 'arcade',
arcade: {
gravity: { y: gameState.gravity },
debug: true
}
},
scene: {
preload,
create,
update
}
};
Code in create() regarding the tilemap and its layers and the character
gameState.map = this.add.tilemap('map');
gameState.dungeonTileset = gameState.map.addTilesetImage('dungeon', 'dungeonTiles');
gameState.backgroundLayer = gameState.map.createStaticLayer('Background', gameState.dungeonTileset);
gameState.mapLayer = gameState.map.createStaticLayer('Map', gameState.dungeonTileset);
gameState.miscLayer = gameState.map.createStaticLayer('Misc', gameState.dungeonTileset);
gameState.mapLayer.setCollisionByExclusion([-1]);
this.physics.world.bounds.width = gameState.mapLayer.width;
this.physics.world.bounds.height = gameState.mapLayer.height;
gameState.player = this.physics.add.sprite(73, 398, 'player', 0);
gameState.player.setCollideWorldBounds(true);
this.physics.add.collider(gameState.player, gameState.mapLayer);
No warning and no errors are coming up in the console. I don't know what to do anymore.
Thanks in advance!
I have addited a little bit the original example so you can see how it looks, I think the problem in your code is the line concerning gameState.mapLayer.setCollisionByExclusion([-1]); but am not sure because I can't see how the tilemap is created
var config = {
type: Phaser.WEBGL,
width: 800,
height: 576,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
loader: {
baseURL: 'https://labs.phaser.io',
crossOrigin: 'anonymous'
},
pixelArt: true,
physics: {
default: 'arcade',
arcade: { gravity: { y: 300 } }
},
scene: {
preload: preload,
create: create,
update: update
}
};
var game = new Phaser.Game(config);
var map;
var cursors;
var player;
var groundLayer;
function preload ()
{
this.load.image('ground_1x1', 'assets/tilemaps/tiles/ground_1x1.png');
this.load.tilemapTiledJSON('map', 'assets/tilemaps/maps/tile-collision-test.json');
this.load.image('player', 'assets/sprites/phaser-dude.png');
}
function create ()
{
map = this.make.tilemap({ key: 'map' });
var groundTiles = map.addTilesetImage('ground_1x1');
map.createDynamicLayer('Background Layer', groundTiles, 0, 0);
groundLayer = map.createDynamicLayer('Ground Layer', groundTiles, 0, 0);
groundLayer.setCollisionBetween(1, 25);//here
player = this.physics.add.sprite(80, 70, 'player')
.setBounce(0.1);
this.physics.add.collider(player, groundLayer);
cursors = this.input.keyboard.createCursorKeys();
this.cameras.main.setBounds(0, 0, map.widthInPixels, map.heightInPixels);
this.cameras.main.startFollow(player);
}
function update ()
{
player.body.setVelocityX(0);
if (cursors.left.isDown)
{
player.body.setVelocityX(-200);
}
else if (cursors.right.isDown)
{
player.body.setVelocityX(200);
}
if (cursors.up.isDown && player.body.onFloor())
{
player.body.setVelocityY(-300);
}
}
<script src="//cdn.jsdelivr.net/npm/phaser#3.17.0/dist/phaser.min.js"></script>

dc.js clicking on one chart not filtering the other (different dimensions)

I've been happily using DC.js for some time. Today is the first time I've created two charts, from two dimensions, both running off the same crossfiltered variable, facts - and they don't filter each other. The bubble chart filters the bar chart but not vice versa. Am I making some obvious error? Very grateful for any pointers.
var facts = crossfilter(data);
var all = facts.groupAll();
print_filter(facts);
var appDimension = facts.dimension(function(d){ return d.ShortName; });
var appGroup = appDimension.group().reduce(
function(p,v){ p.count++; v.NumUsers==0?p.numUsers=1:p.numUsers=v.NumUsers; p.numClients=v.NumClients; p.lc=v.lc; p.LifeCycle=v.LifeCycle; p.fv=v.fv; p.FutureValue=v.FutureValue; return p; },
function(p,v){ p.count--; v.NumUsers==0?p.numUsers=1:p.numUsers=v.NumUsers; p.numClients=v.NumClients; p.lc=v.lc; p.LifeCycle=v.LifeCycle; p.fv=v.fv; p.FutureValue=v.FutureValue; return p; },
function(){ return { count:0, numUsers: 0, numClients: 0, lc: 0, LifeCycle: '', fv: 0, FutureValue: '' }; }
);
var lifeCycleDimension = facts.dimension(function(d){ return d.LifeCycle; });
var tempName='';
var lifeCycleGroup = lifeCycleDimension.group().reduce(
function(p,v){
if (tempName!=v.ShortName) {
p++;
tempName=v.ShortName;
}
return p;
},
function(p,v){
if (tempName!=v.ShortName) {
p--;
tempName=v.ShortName;
}
return p;
},
function(){ return 0; }
);
var yearlyBubbleChart = dc.bubbleChart('#col1')
.width(360)
.height(600)
.margins({top: 10, right: 100, bottom: 30, left: 40})
.dimension(appDimension)
.group(appGroup)
.clipPadding(200)
.yAxisLabel('Number of users')
.xAxisLabel('Number of clients')
// .ordinalColors(['#e41a1c','#377eb8','#4daf4a','#984ea3','#ff7f00','#ffff33','#a65628'])
.colorAccessor(function(p){
return p.value.lc;
})
.colors(colorbrewer.RdYlGn[9])
.colorDomain([1,6])
.keyAccessor(function (p) {
return p.value.numClients;
})
.valueAccessor(function (p) {
return p.value.numUsers;
})
.radiusValueAccessor(function (p) {
return p.value.fv;
})
.title(function(d){ return 'App: '+d.key + '\nNum users: '+d.value.numUsers+'\nNum clients: '+d.value.numClients+'\nLife cycle: '+d.value.LifeCycle+'\nFuture value: '+d.value.FutureValue; })
.maxBubbleRelativeSize(0.15)
.x(d3.scale.linear().domain([0, 608]))
.y(d3.scale.log().base(Math.E).domain([1, 120000]))
.r(d3.scale.linear().domain([0.5, 3]))
// .elasticY(true)
// .elasticX(true)
.yAxisPadding(100)
.xAxisPadding(500)
.renderHorizontalGridLines(true)
.renderVerticalGridLines(true);
yearlyBubbleChart.yAxis().tickFormat(function(d){ return Math.round(d); });
yearlyBubbleChart.xAxis().ticks(5);
var barAmountChart = dc.barChart('#barCount')
.width(530)
.height(200)
.margins({top: 10, right: 50, bottom: 30, left: 45})
.dimension(lifeCycleDimension)
.gap(1)
.group(lifeCycleGroup)
.title(function(d){ return d.value+' apps in '+d.key+' phase '; })
.x(d3.scale.ordinal().domain(['Idea','Plan 2017','New','Re-Newed','SunSet','Legacy']))
.xUnits(dc.units.ordinal);
barAmountChart.yAxis().ticks(4);

Pan and zoom in kendo boxplot chart

I am trying to use the pan and zoom functionality in kendo box plot chart, can this be achieved for box plot chart.
http://demos.telerik.com/kendo-ui/bar-charts/pan-and-zoom
You can apply the exact same methods to the boxplot.
DEMO
CODE:
// Minimum/maximum number of visible items
var MIN_SIZE = 6;
var MAX_SIZE = 18;
// Optional sort expression
// var SORT = { field: "val", dir: "asc" };
var SORT = {};
// Minimum distance in px to start dragging
var DRAG_THR = 50;
// State variables
var viewStart = 0;
var viewSize = MIN_SIZE;
var newStart;
// Drag handler
function onDrag(e) {
var chart = e.sender;
var ds = chart.dataSource;
var delta = Math.round(e.originalEvent.x.initialDelta / DRAG_THR);
if (delta != 0) {
newStart = Math.max(0, viewStart - delta);
newStart = Math.min(data.length - viewSize, newStart);
ds.query({
skip: newStart,
page: 0,
pageSize: viewSize,
sort: SORT
});
}
}
function onDragEnd() {
viewStart = newStart;
}
// Zoom handler
function onZoom(e) {
var chart = e.sender;
var ds = chart.dataSource;
viewSize = Math.min(Math.max(viewSize + e.delta, MIN_SIZE), MAX_SIZE);
ds.query({
skip: viewStart,
page: 0,
pageSize: viewSize,
sort: SORT
});
// Prevent document scrolling
e.originalEvent.preventDefault();
}
$("#chart").kendoChart({
dataSource: {
data: data,
pageSize: viewSize,
page: 0,
sort: { }
},
title: {
text: "Ozone Concentration (ppm)"
},
legend: {
visible: false
},
series: [{
type: "boxPlot",
lowerField: "lower",
q1Field: "q1",
medianField: "median",
q3Field: "q3",
upperField: "upper",
meanField: "mean",
outliersField: "outliers"
}],
categoryAxis: {
field: "year",
majorGridLines: {
visible: false
}
},
transitions: false,
drag: onDrag,
dragEnd: onDragEnd,
zoom: onZoom
});

Calendar doesn't render any events after $scope.splice(0) and $scope.push(event)

Hi I have problem with angular ui-calendar(angular wrapper for arshaw's fullcalendar).
In the first state I load the events immediately through a $http call. The calendar renders as expected.
In the second step, I load unapproved or approved events according to result of showNeschvaleneTerminyFunction(). After this load however, calendar renders, but does not have any events. I verified that the object on scope has events and is being updated correctly by echoing the object on the screen. However the calendar does not ever show the events.
Could you please help me, how can I properly load and reload events with ajax from php driven storage?
Here is my code
$scope.events = [];
$scope.getTermins = function(){
if($scope.showNeschvaleneTerminy == true){
$http.get(plutanium.ajaxurl + '?action=terminy_read').success(function (data, status, headers, config) {
$scope.events.splice(0, $scope.events.length);
$className = '';
for (var i = 0; i < data.length; i++) {
if (data[i].status == 0) {
$className = 'b-danger';
} else {
$className = 'b-info';
}
$scope.events.push({
id: data[i].id,
title: data[i].jmeno,
start: moment(data[i].date).toDate(),
end: moment(data[i].date).add('hours', 1).toDate(),
allDay: false,
className: ['b-l b-2x ' + $className]
});
}
});
}else{
$http.get(plutanium.ajaxurl + '?action=terminy_approved').success(function (data, status, headers, config) {
$scope.events.splice(0, $scope.events.length);
$className = '';
for (var i = 0; i < data.length; i++) {
$scope.events.push({
id: data[i].id,
title: data[i].jmeno,
start: moment(data[i].date).toDate(),
end: moment(data[i].date).add('hours', 1).toDate(),
allDay: false,
className: ['b-l b-2x b-info']
});
}
});
}
}
$scope.getTermins();
$scope.showNeschvaleneTerminyFunction = function () {
if ($scope.showNeschvaleneTerminy == false) {
$scope.showNeschvaleneTerminy = true
} else {
$scope.showNeschvaleneTerminy = false
}
$scope.getTermins();
}
/* config object */
$scope.uiConfig = {
calendar1:{
defaultView: 'agendaDay',
height: $window.innerHeight-200,
firstDay: 1,
firstHour: 7,
slotMinutes: 60,
defaultEventMinutes: 120,
minTime: 7,
maxTime: 15,
editable: true,
header:{
left: '',
center: 'title',
right: ''
},
dayClick: $scope.AgendaOnDayClick,
eventClick: $scope.alertOnEventClick,
eventDrop: $scope.alertOnDrop,
//eventResize: $scope.alertOnResize,
//eventMouseover: $scope.alertOnMouseOver,
},
calendar2: {
editable: true,
header: {
left: 'prev',
center: 'title',
right: 'next'
},
height: $window.innerHeight - 200,
firstDay: 1,
minTime: 7,
maxTime: 15,
dayClick: $scope.MonthOnDayClick,
eventClick: $scope.alertOnEventClick,
eventDrop: $scope.alertOnDrop,
//eventResize: $scope.alertOnResize,
//eventMouseover: $scope.alertOnMouseOver,
dayRender: $scope.setDay
},
calendar3: {
defaultView: 'agendaDay',
editable: true,
header: {
left: '',
center: 'title',
right: ''
},
height: $window.innerHeight - 200,
firstDay: 1,
firstHour: 7,
slotMinutes: 60,
defaultEventMinutes: 120,
minTime: 7,
maxTime: 15,
dayClick: $scope.AgendaOnDayClick,
eventClick: $scope.alertOnEventClick,
eventDrop: $scope.alertOnDrop,
//eventResize: $scope.alertOnResize,
//eventMouseover: $scope.alertOnMouseOver,
}
};
$scope.eventSources = [$scope.events];
So I didn't find any solution to my problem, that's why I disabled ui-calendar wrapper and now I am calling fullcalendar refreshevents function manually after loading events to array. It works now like a charm.

jqplot tooltipContentEditor displays wrong x and y values

I have a jqplot line graph with this line:
`var line = [[1,0.493],
[1,1.286],
[2,0.305],
[2,0.516],
[2,0.551],
[2,0.595],
[2,0.609],
[2,0.644],
[2,0.65],
[2,1.249],
[2,1.265],
[4,0.443],
[5,0.288],
[5,0.477],
[5,0.559],
[5,0.562],
[6,0.543],
[7,0.513],
[7,0.549],
[8,0.442],
[8,0.467],
[8,0.468],
[8,0.597],
[8,0.857]];`
Im using tooltipContentEditor to display the x and y values of the point on hover. I need the values displayed to be exact.
Here is the code Im using: http://jsfiddle.net/ZQh38/1/
The problem:
Sometimes, the x and y values displayed are incorrect. For example, the last points at (6, 0.5) and (7, 0.5)
The values are only displayed with 1 decimal, which needs to be 3.
So, the question is, how do I get the exact y values?
Ive also tried to use the pointIndex, which does NOT match with the values in the line.
Thanks for your help!
Here is the solution to your problem: jsFiddle example
I made changes to your highlighter option.
/*
Drawing graphs
*/
var Statistics = {
scatter: false,
trendline: false,
enableLabels: true,
showAverage: false,
colour: null,
//Graph properties
scatterPlot: function(on){
Statistics.scatter = on;
},
showTrendline: function(on){
$.jqplot.config.enablePlugins = on;
Statistics.trendline = on;
},
disableLabels: function(yes){
Statistics.enableLabels = (!yes);
},
shouldDrawScatter: function(){
return (!Statistics.scatter);
},
useLabels: function(){
return Statistics.enableLabels;
},
getTrendline: function(){
return Statistics.trendline;
},
//Drawing
drawLabels: function(){
document.getElementById('ylabel').innerHTML = Statistics.ylabel;
document.getElementById('xlabel').innerHTML = Statistics.xlabel;
},
generateGraph: function(){
var line = [[1,0.493],
[1,1.286],
[2,0.305],
[2,0.516],
[2,0.551],
[2,0.595],
[2,0.609],
[2,0.644],
[2,0.65],
[2,1.249],
[2,1.265],
[4,0.443],
[5,0.288],
[5,0.477],
[5,0.559],
[5,0.562],
[6,0.543],
[7,0.513],
[7,0.549],
[8,0.442],
[8,0.467],
[8,0.468],
[8,0.597],
[8,0.857]];
var plot = $.jqplot('chart', [line], {
animate: true,
grid:{backgroundColor: 'white'},
axes: {
xaxis: {
renderer: $.jqplot.CategoryAxisRenderer,
ticks: [1, 2, 3, 4, 5, 6, 7],
tickOptions: {
fontFamily: '"Helvetica", cursive',
fontSize: '12pt'
}
},
yaxis: {
tickOptions: {
fontFamily: '"Helvetica", cursive',
fontSize: '12pt'
},
max: 2,
min: 0
}
},
series:[{
color: "#594A42",
lineWidth: 2.5,
shadow: false,
fillColor: "#594A42",
markerOptions: {
style:'filledCircle',
color: "#594A42",
shadow: false,
size: 10
},
showLine: false,
trendline: {
color: '#999'
},
rendererOptions:{
animation: {
speed: 2000 //Speeding up animation
}
}
}],
highlighter: {
show: true,
fadeTooltip: true,
sizeAdjust: 6,
tooltipContentEditor: function(str, pointIndex, index, plot){
var splitted = plot._plotData[1][index];
var x = splitted[0];
var y = splitted[1];
return x + ", " + y;
}
}
});
},
//Checks if the graph will be a straight line
straightLine: function(lineArray){
if(typeof lineArray != 'undefined' && lineArray.length > 0) {
for(var i = 1; i < lineArray.length; i++)
{
if(lineArray[i] !== lineArray[0])
return false;
}
}
return true;
},
};
Statistics.generateGraph();

Resources