I am trying to label xaxis lable range in uniform format. currently I am getting the xaxis labels as below.
But I want this to be represented in format like "20:00 21:00 23:00 'next day Date' 01:00 03:00 ..." and so on based on data available.
Also I want to display mouse over xaxis value in legend. What code change I need to do as part of this change ?
Here is the code snippet
new Dygraph(
this.$.chart,
data,
{
title: this.chartData.response.chartDataSet.xAxisHeading,
labels: data_labels,
axisLabelWidth: 60,
ylabel: this.chartData.response.chartDataSet.yAxisHeading,
height: 300,
width: setWidth,
hideOverlayOnMouseOut: false,
legend: 'follow',
fillGraph: true,
pixelsPerLabel: pixelsPerLabelXaxis,
legendFormatter: legendFormatter,
axes: {
x: {
axisLabelFormatter: function(d) {
this.value = in_data.chartDataSet.xCoordinates[d];
if(this.value!==undefined){
if(historicalPeriod === 21 || historicalPeriod === 22 || historicalPeriod === 23){
return moment(this.value, 'MM-DD-YYYY_HH:mm:ss').format('DD - MMM');
}
else if(historicalPeriod === 24){
return moment(this.value, 'MM-DD-YYYY').format('MMM-YYYY');
}else{
return moment(this.value, 'HH:mm:ss').format('HH:mm');
}
}
return in_data.chartDataSet.xCoordinates[d];
}
}
},
}
);
Related
I am trying to build a line chart using highchart.js that uses the color green and black. The data is pulled from an SQL database and if the value is higher than the previous value it is green. If the value is less than the previous value than the color is black.
I am new at this and have been searching and searching but the only things I find is using zones to change the colors.
Can anyone help me on this?
I created this example, it should help you :
series: [{
name: 'Random data',
colorByPoint: true,
data: (function() {
// generate an array of random data
var time = (new Date()).getTime(),
i,
yValue;
for (i = -19; i <= 0; i += 1) {
yValue = Math.random();
if (i > -19 && yValue > data[data.length - 1].y) { // Green point
zones.push({
color: "#5f9",
value: time + i * 1000,
});
} else if (i > -19 && yValue <= data[data.length - 1].y) { // black point
zones.push({
color: "#000",
value: time + i * 1000,
});
} else { // first point alway green
zones.push({
color: "#5f9",
value: time + i * 1000,
});
}
data.push({
x: time + i * 1000,
y: yValue
});
}
return data;
}()),
zoneAxis: "x",
zones: zones
}]
Fiddle
I am working on google column chart. I have created 3 columns while generating charts. Here are those columns.
var dtblData = new google.visualization.DataTable();
dtblData.addColumn('string', 'Names');
dtblData.addColumn('datetime', 'Intime');
dtblData.addColumn('datetime', 'Outtime');
I am using following data to show on graph.
[{"display_name":"Aditi Badurkar
","in_time":{"year":2017,"month":6,"day":22,"hours":11,"minutes":7,"seconds":8,"miliseconds":470},"out_time":{"year":2017,"month":6,"day":22,"hours":12,"minutes":45,"seconds":44,"miliseconds":237}}]
Here is my code :-
google.charts.load('current', { 'packages': ['corechart', 'bar'] });
google.charts.setOnLoadCallback(drawStuff);
function drawStuff() {
var chartDiv = document.getElementById('chart_div');
var dtblData = new google.visualization.DataTable();
dtblData.addColumn('string', 'Names');
dtblData.addColumn('datetime', 'Intime');
dtblData.addColumn('datetime', 'Outtime');
for (var i = 0; i < data.length; i++) {
if (data[i].out_time.year == 0) {
dtblData.addRow([data[i].display_name, new Date(data[i].in_time.year, data[i].in_time.month, data[i].in_time.day, data[i].in_time.hours, data[i].in_time.minutes, data[i].in_time.seconds, data[i].in_time.miliseconds), null]);
}
else {
dtblData.addRow([data[i].display_name, new Date(data[i].in_time.year, data[i].in_time.month, data[i].in_time.day, data[i].in_time.hours, data[i].in_time.minutes, data[i].in_time.seconds, data[i].in_time.miliseconds), new Date(data[i].out_time.year, data[i].out_time.month, data[i].out_time.day, data[i].out_time.hours, data[i].out_time.minutes, data[i].out_time.seconds, data[i].out_time.miliseconds)]);
}
}
var dateinFormat = new google.visualization.DateFormat({ formatType: 'long', pattern: "dd/MM/yyyy HH:mm:ss ZZZZ" });
dateinFormat.format(dtblData, 1);
var dateOutFormat = new google.visualization.DateFormat({ formatType: 'long', pattern: "dd/MM/yyyy HH:mm:ss ZZZZ" });
dateOutFormat.format(dtblData, 2);
var materialOptions = {
//width: 900,
chart: {
title: '',
subtitle: 'Intime, Outime of your kids or staff'
},
series: {
0: { axis: 'In Time' }, // Bind series 0 to an axis named 'In Time'.
1: { axis: 'Out time' } // Bind series 1 to an axis named 'Out Time'.
},
axes: {
y: {
distance: { label: 'In Time' }, // Left y-axis.
brightness: { side: 'right', label: 'Out Time' }, // Right y-axis.
}
},
};
function drawMaterialChart() {
var materialChart = new google.charts.Bar(chartDiv);
materialChart.draw(dtblData, google.charts.Bar.convertOptions(materialOptions));
}
drawMaterialChart();
}
My problem is, on graph it is showing month as July but in data it is June. I am not getting why it is showing wrong month when I scroll mouse pointer on bar? Can someone help me to solve this? I think it might be time zone issue.
Please see screenshot.
The Month in JavaScript is Zero Based, so ranges from 0 to 11 (0 meaning January and 11 meaning December).
For your code, you may decrement the month value by 1 to solve this.
Something that may be useful:
Why does the month argument range from 0 to 11 in JavaScript's Date constructor?
> handsontable.full.js?v=1.2:10476 Uncaught TypeError: Cannot read property 'classList' of undefined
> at _removeClass (handsontable.full.js?v=1.2:10476)
> at removeClass (handsontable.full.js?v=1.2:10531)
> at handsontable.full.js?v=1.2:5426
> at done (handsontable.full.js?v=1.2:5502)
> at handsontable.full.js?v=1.2:5517
> at handsontable.full.js?v=1.2:23966
> at ColumnSettings.Handsontable.AutocompleteValidator [as validator] (handsontable.full.js?v=1.2:23949)
It's working fine when i am pasting 4 to 5 columns but when i trying more than 7 getting above error.previously i tested in tab it's works fine there but when i moved handsontable grid to bootstrap modal getting this error.please help i am trying to understand.
please find below how i created handsontable
manualHot = new Handsontable(container, {
rowHeaders: true,
colHeaders: true,
startRows: 100,
startCols: 125,
// columns: columns,
dropdownMenu: true,
contextMenu: true,
filters:true,
manualColumnResize: true,
height: 500,
wordWrap:false,
colWidths: 100,
rowHeights: 23,
autoColumnSize: true,
columnSorting: true,
fixedRowsTop:1,
copyable:true,
sortFunction: function(sortOrder, columnMeta) {
return function(a, b) {
var plugin = manualHot.getPlugin('columnSorting');
var sortFunction;
if (a[0] === 0) {
return -1;
}
switch (columnMeta.type) {
case 'date':
sortFunction = plugin.dateSort;
break;
case 'numeric':
sortFunction = plugin.numericSort;
break;
default:
sortFunction = plugin.defaultSort;
}
return sortFunction(sortOrder, columnMeta)(a, b);
};
},
trimDropdown :false,
formulas: true,
cells: function (row, col, prop) {
var cellProperties = {};
if (row === 0) {
cellProperties.type = 'dropdown';
cellProperties.source= colHeaderArr;
cellProperties.allowInvalid = false;
}
return cellProperties;
},
afterValidate: function (isValid, value, row, prop, source) {
if (source === 'loadData' || source === 'internal' ) {
return;
}
if (!isValid ) {
errorHeader[prop]=headerCols[prop];
}
},
});
manualHot.addHook('beforeChange', function(changes, source) {
dupheaders=[]
dupheaders.length=0;
if (source === 'loadData' || source === 'internal' || changes.length > 1) {
return;
}
var row = changes[0][0];
var prop = changes[0][1];
var newVal = changes[0][3];
var oldVal=changes[0][2];
if ( row ===0) {
headerCols[prop]=newVal;
var sorted_head = headerCols.slice().sort();
for (var i = 0; i < headerCols.length - 1; i++) {
if (sorted_head[i + 1] == sorted_head[i]) {
if(sorted_head[i]){dupheaders.push(sorted_head[i]);}
}
}
if(dupheaders.length>0){
var errMsg='Duplicate Headers :<br>'+dupheaders;
setTimeout(function(){$('#manualDataOnlinePrep-Tab').unblock();},1000);
common.showMessage(errMsg, false, "error", "middle-center");
}
errorHeader.splice(prop, 1);
setColumnType(colProp,prop,newVal, this,txnTypeArr);
}
});
manualHot.init();
}
function setColumnType(columnProp,col,newVal, instance,ddValue) {
if(newVal === 'Reporting Code Description' ) {
columnProp[col].type='dropdown';
columnProp[col].source=ddValue;
}
else{
if(newVal.match(/^.*Date$/)){
columnProp[col].type='date';
columnProp[col].dateFormat=document.getElementById("dateFormat_2").value;
columnProp[col].allowInvalid=true;
}
else if (newVal.match(/^.*Amount$/)){
columnProp[col].type='numeric';
columnProp[col].format= '[00,00,000].00';
columnProp[col].allowInvalid=false;
}
else if (newVal.match(/^.*Rate$/)){
columnProp[col].type='numeric';
columnProp[col].format= '0.[000000]';
columnProp[col].allowInvalid=false;
}
else{
columnProp[col].type='text';
}
}
instance.updateSettings({columns: columnProp},{contextMenu:true});
instance.validateCells(function() {
instance.render();
});
}
I am trying to pause between levels in this game but the pause feature wont work. Any help would be great. Currently the code just keeps getting stuck in a loop and prints out Next Level.
The level system is supposed to work when this.p.levelData.nextLevel is true but it keeps looping.
Any help would be great.
Quintus.ZombiesGameplay = function(Q) {
//game level
Q.Sprite.extend('Level', {
init: function(p) {
this._super(p, {
asset: '/assets/images/background.png',
type: Q.SPRITE_GROUND,
x: 90 + 1024/2,
y: 768/2,
w: 1024,
h: 768,
sunFrequency: {min: 3,max: 10}, //min and max number of seconds for sun to appear
});
this.timeNextSun = this.getTimeNextSun(); //time for the next sun to appear
//level data
this.zombieIndex = 0; //current index from zombies array
this.numZombies = this.p.levelData.zombies.length;
this.levelTime = 0; //keep track of the level duration
//save the position of each plant in a grid
this.plantsGrid = new Array(new Array(7), new Array(7), new Array(7), new Array(7), new Array(7), new Array(7));
this.on('touch');
Q.audio.play('/assets/audio/ZombiesOnYourLawn.mp3');
},
step: function(dt) {
//update level duration
this.levelTime += dt;
//check for level passed
if(this.p.levelData.duration < this.levelTime) {
if(this.p.levelData.nextLevel) {
// Q.stageScene("level", {levelData: Q.assets[this.p.levelData.nextLevel]});
// Q.stage().pause();
// Q.stage().unpause();
// debugger;
nextLevel();
// pauseGame();
// unPauseGame();
}else {
endGame();
// Q.stageScene('level', {levelData: Q.assets['/assets/data/level1.json']});
// Q.stage().pause();
// Q.stage().unpause();
}
}
//create zombies at the defined times
if(this.zombieIndex < this.numZombies) {
var currentZombie = this.p.levelData.zombies[this.zombieIndex];
if(this.levelTime >= currentZombie.time) {
var zombieData = Q.zombieTypes[currentZombie.type];
var newZombie = new Q.Zombie(
Q._extend(zombieData, {y: currentZombie.row * 120 + 60})
);
this.stage.insert(newZombie);
this.zombieIndex++;
}
}
//update sun generation timing
this.timeNextSun -= dt;
if(this.timeNextSun <= 0) {
this.timeNextSun = this.getTimeNextSun();
//create sun in the sun stage
Q.stage(1).insert(new Q.Sun());
}
},
touch: function(touch) {
//if a plant is selected
if(Q.state.get('currentPlant')) {
//get plantsGrid coordinates
var row = Math.floor((touch.y)/120);
var col = Math.floor((touch.x - 240)/120);
if(row >= 0 && row < this.plantsGrid.length && col >= 0 && col < this.plantsGrid[0].length) {
if(!this.plantsGrid[row][col] && Q.state.get('sun') >= Q.state.get('currentPlant').cost) {
Q.state.dec('sun', Q.state.get('currentPlant').cost);
var newPlant = new Q.Plant(Q._extend({x: 240 + 60 + col*120, y: 60 + row*120}, Q.state.get('currentPlant')));
this.stage.insert(newPlant);
this.plantsGrid[row][col] = newPlant;
newPlant.p.gridRow = row;
newPlant.p.gridCol = col;
}
}
}
},
getTimeNextSun: function() {
return this.p.sunFrequency.min + Math.random()*(this.p.sunFrequency.max - this.p.sunFrequency.min);
},
});
}
function nextLevel(){
console.log('NEXT LEVEL');
Q.stageScene("nextLevel",1, { label: "LEVEL COMPLETED!" });
Q.scene('nextLevel',function(stage) {
var container = stage.insert(new Q.UI.Container({
x: Q.width/2, y: Q.height/2, fill: "rgba(0,0,0,0.5)"
}));
var nextLevelButton = container.insert(new Q.UI.Button({ x: 0, y: 0, fill: "#CCCCCC",
label: "Next Level" }))
var label = container.insert(new Q.UI.Text({x:10, y: -10 - nextLevelButton.p.h, fill: "#FFFFFF",
label: stage.options.label }));
nextLevelButton.on("click",function() {
alert("test");
Q.stageScene("level", {levelData: Q.assets[this.p.levelData.nextLevel] });
});
container.fit(20);
});
pauseGame();
};
function endGame(){
console.log('YOU WON!');
Q.stageScene("endGame",1, { label: "You Have Won The Game!" });
Q.scene('endGame',function(stage) {
var container = stage.insert(new Q.UI.Container({
x: Q.width/2, y: Q.height/2, fill: "rgba(0,0,0,0.5)"
}));
var button = container.insert(new Q.UI.Button({ x: 0, y: 0, fill: "#CCCCCC",
label: "Play Again" }))
var label = container.insert(new Q.UI.Text({x:10, y: -10 - button.p.h, fill: "#FFFFFF",
label: stage.options.label }));
button.on("click",function() {
Q.clearStages();
Q.stageScene('level', {levelData: Q.assets['/assets/data/level1.json']});
});
container.fit(20);
});
// pauseGame();
};
function pauseGame(){
console.log("Game Paused");
Q.stage().pause()
};
function unPauseGame(){
Q.stage().unpause()
};
in my grid,i should have the ability to have check boxes and String data based on the statuses returned from the webservice.Now i am writing custom renderer function given below :
function customcolumn1(value, metadata, record) {
var completedTime = record.get('nccompletedTime');
var completedByLastName = record.get('nccompletedByLastName');
var completedByFirstName = record.get('nccompletedByFirstName');
if (value == 'Completed') {
return completedTime + " " + completedByLastName + "," + completedByFirstName;
} else if (value == 'Pending') {
return "<input type='checkbox' disabled>";
} else if (value == 'Assigned') {
return "<input type='checkbox'>";
}
}
And the grid is
var SAFjobgrid = Ext.create('Ext.grid.Panel', {
store: store,
columns: [
{
text: "",
width: 30,
renderer: customSeqNumber,
dataIndex: 'sequenceNumber'},
{
text: "Task",
width: 350,
renderer: customTask,
dataIndex: 'label'},
{
text: "Complete",
width: 160,
renderer: customcolumn2,
dataIndex: 'stampActionStatus'},
{
text: "Verified",
width: 160,
renderer: customcolumn,
dataIndex: 'verifyActionStatus'},
{
text: "Non Compliance",
flex: 1,
renderer: customcolumn1,
dataIndex: 'ncActionStatus'}
]
});
Now i want to check the check boxes and capture the stampIds for those records.And when i click on update button which is oustside of the grid,i should be able to call the webservice with the captured stampId's.I tried to put onclick event on checkbox while returning from the renderer function.But how should i access the stampId for that record.if i select multiple checkboxes,multiple stampid's should go to webservice and if i uncheck the checkbox,the corresponding stampid should be removed from stampId's.
Could anyone help on this one..
You can look at CheckColumn user extension http://docs.sencha.com/ext-js/4-1/#!/api/Ext.ux.CheckColumn But in your case you have to override renderer method like this
renderer : function(value, meta, record){
var cssPrefix = Ext.baseCSSPrefix,
cls = [cssPrefix + 'grid-checkheader'],
completedTime = record.get('nccompletedTime'),
completedByLastName = record.get('nccompletedByLastName'),
completedByFirstName = record.get('nccompletedByFirstName');
if (value == 'Completed') {
//render string instead of checkbox
return Ext.String.format('{0} {1},{2}', completedTime, completedByLastName, completedByFirstName);
}
if (value === 'Assigned') {
cls.push(cssPrefix + 'grid-checkheader-checked');
}
//render checkbox stub,
//it is actually a div element with special css classes to simulate checkbox
return '<div class="' + cls.join(' ') + '"> </div>';
}
To collect al checked/unchecked rows you can use this store method http://docs.sencha.com/ext-js/4-1/#!/api/Ext.data.AbstractStore-method-getUpdatedRecords
It returns array of models which were updated by checking/unchecking this column