how to fix this google charts bar chart error - google-visualization

same data are used to draw line chart and bar chart. it works fine for drawing line. but there is an error for drawing bar chart. the error is "a.getTime is not a function×". any suggestions are appreciated.
here is my code:
datasource.addColumn('date', 'Date');
datasource.addColumn('number', 'quantity');
datasource.addColumn('number', 'quantity');
datasource.addColumn('number', 'quantity');
for (n = 0; n < tem.length; n++) {
datasource.addRows([[new Date(tem[n][0]), tem[n][1], tem[n][2], tem[n][3]]]);
}
*********line chart ***********
chart = new google.visualization.LineChart(document.getElementById('chart_div'));
var options = {
actions: ['dragToZoom', 'rightClickToReset'],
interpolateNulls: true, //bypass null
legend: 'none',
crosshair: { trigger: 'both', opacity: 0.5 }, // Display crosshairs on focus and selection.
title: 'Company Performance',
hAxis: { title: 'Year', titleTextStyle: { color: 'red' }, format: "YY.MM.dd", slantedText: true, slantedTextAngle: 30 },
vAxis: {
viewWindowMode: 'explicit',
viewWindow: {
max: maxy,
min: 0
}
},
explorer: { axis: 'horizontal', maxZoomOut: 1 } //wheel zoom
};
chart.draw(datasource, options);
***********bar chart*************
chart = new google.visualization.BarChart(document.getElementById('chart_div'));
var options = {
title: 'Company Performance',
hAxis: { title: 'Number', titleTextStyle: { color: 'red' } },
vAxis: { minValue: 0 },
explorer: { axis: 'horizontal', maxZoomOut: 1 }
};
chart.draw(datasource, options);*

Related

ChartJs - width scale of chart area and label area

I created a donut chart but its width of data area and label area is not what I intended.
How can I increase the width of data(chart) area - i.e. 60% and decrease the width of label area proportionately?
image link as below
https://i.stack.imgur.com/dsoT3.png
<div style="text-align: center;" class='sector-exposure'>
<canvas
baseChart
[data]="sectorChartData"
[labels]="sectorChartLabels"
[chartType]="exposureChartType"
[options]="exposureChartOptions"
>
</canvas>
</div>
public exposureChartOptions: ChartOptions = {
legend: {
position: right,
labels: {
fontColor: '#d5d6d6',
fontSize: this.isMobileWidth ? 10 : 16,
},
},
};
[1]: https://i.stack.imgur.com/dsoT3.png
May be following settings will work for you. Set responsive to true and maintainAspectRatio to false in the chart options and set style as like as max-height: 300px (more or less); width: auto; in canvas.
...
var config = {
type: 'doughnutLabels',
data: {
...
},
options: {
...
responsive: true, //IMPORTANT
maintainAspectRatio: false, //IMPORTANT
...
legend: {
...
position: 'right',
...
labels: {
...
fontColor: '#d5d6d6',
fontSize: this.isMobileWidth ? 10 : 16,
...
}
},
animation: {
animateScale: true,
animateRotate: true
}
}
};
...

How to compute x,y values from a click event using x,y pixel coordinates in ChartJS?

I would like to receive the x,y values from a line chart in ChartJS, when the user clicks on the Chart.
Die difficulty compared to usually discusses techniques is, that I need to receive x,y values from any position in the chart and not just when I click on some samples in the dataset.
So when I click on some empty place, I need to know its x and y axis values.
Got some example with a comment therein, where I sutck:
var randomInt = function() {
return (Math.random() * 100) - 50;
};
//needs it for the test
var labels = ["Management", "Finance", "Human Resources", "Business Development and Marketing", "Information Technology", "Professional Development and Training", "Knowledge Management", "Logistics", "Support", "Business Services", "Other"];
var datas = [{
x: randomInt(),
y: randomInt(),
}, {
x: randomInt(),
y: randomInt(),
}, {
x: randomInt(),
y: randomInt(),
}, {
x: randomInt(),
y: randomInt(),
}, {
x: randomInt(),
y: randomInt(),
}, {
x: randomInt(),
y: randomInt(),
}, {
x: randomInt(),
y: randomInt(),
}];
var scatterChartData = {
labels: labels,
datasets: [{
label: "My First dataset",
data: datas
}]
};
var ctx = document.getElementById("canvas").getContext("2d");
var myScatter = new Chart.Scatter(ctx, {
data: scatterChartData,
options: {
title: {
display: true,
text: 'Chart.js Scatter Chart'
},
scales: {
xAxes: [{
position: 'bottom',
gridLines: {
zeroLineColor: "rgba(0,255,0,1)"
},
scaleLabel: {
display: true,
labelString: 'x axis'
}
}],
yAxes: [{
position: 'right',
gridLines: {
zeroLineColor: "rgba(0,255,0,1)"
},
scaleLabel: {
display: true,
labelString: 'y axis'
}
}]
}
}
});
//
canvas.onclick = function(evt){
//HERE I have the x,y pixel coordinates inside the evt object.
//How to get the x,y values from the x and y axis??
//this works only if I click on one of the samples...
var activePoints = myScatter.getElementsAtEvent(evt);
var firstPoint = activePoints[0];
if(firstPoint !== undefined){
var label = myScatter.data.labels[firstPoint._index];
var value = myScatter.data.datasets[firstPoint._datasetIndex].data[firstPoint._index];
alert(label + ": " + value.x);
alert(label + ": " + value.y);
}
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.12.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.0.0-beta2/Chart.min.js"></script>
<div>
<div>
<canvas id="canvas"></canvas>
</div>
</div>
I found at least a way to extract the y-axis value. The computation of the x-axis value should be similar:
//inside the click callback...
var scaler=that.chart.scales['y-axis-0'];
var chart_height_px=scaler.bottom+scaler.top;
var y=evt.clientY-that.canvas[0].getBoundingClientRect().top-scaler.top;
var yval=scaler.max-y/scaler.height*(scaler.max-scaler.min);
console.log("value clicked: %o, ypx: %o", yval, y);
that.trigger("onTickerYClick", yval);

Google chart vAxis title being cut off and needs to move closer to axis

I'm trying to use Google charts to display the results of a survey. All seems fine, apart from the title of the vAxis is being cut off slightly and I can't work out how to move it closer to the axis.
This is the code:
google.load("visualization", "1.0", {packages:["bar"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Question title goes here', 'Percentage Score'],
['Always', 40],
['Usually', 30],
['Rarely', 10],
['Never', 20]
]);
var options = {
chart: {
title: 'Section Title',
subtitle: 'Section subtitle',
},
legend: { position: "none" },
vAxis: {
title: 'Percentage',
viewWindowMode:'explicit',
viewWindow: {
max:100,
min:0
}
},
bars: 'vertical', // Required for Material Bar Charts.
width: 600,
height: 500
};
var chart = new google.charts.Bar(document.getElementById('barchart_material'));
chart.draw(data, google.charts.Bar.convertOptions(options));
};
I have a fiddle here:
https://jsfiddle.net/SBComms/pa4yLcb3/
With a Core Chart, you can adjust the size of the chartArea to allow room for the title.
However, this doesn't appear to work for a Material Chart.
Also, I would recommend loading with loader.js vs. the older library jsapi.
See following example...
google.charts.load('current', {
callback: drawChart,
packages: ['bar', 'corechart']
});
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Question title goes here', 'Percentage Score'],
['Always', 40],
['Usually', 30],
['Rarely', 10],
['Never', 20]
]);
var options = {
chart: {
title: 'Section Title',
subtitle: 'Section subtitle',
},
chartArea: {
backgroundColor: 'cyan',
height: 400,
left: 60,
top: 20,
width: 500
},
legend: {
position: "none"
},
vAxis: {
title: 'Percentage',
viewWindowMode:'explicit',
viewWindow: {
max:100,
min:0
}
},
bars: 'vertical',
width: 600,
height: 500
};
var chart = new google.charts.Bar(document.getElementById('barchart_material'));
chart.draw(data, google.charts.Bar.convertOptions(options));
var chart2 = new google.visualization.ColumnChart(document.getElementById('barchart_core'));
chart2.draw(data, options);
};
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div>========MATERIAL========</div>
<div id="barchart_material"></div>
<div>==========CORE==========</div>
<div id="barchart_core"></div>
I managed to find a real fiddle to the problem. I have updated the chart script so that the vAxis fontSize is 18:
google.load("visualization", "1.0", {packages:["bar"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['', 'Percentage'],
['Always', 40],
['Usually', 30],
['Rarely', 10],
['Never', 20]
]);
var options = {
chart: {
title: 'Company Performance'
},
legend: { position: "none" },
vAxis: {
title: 'Percentage',
titleTextStyle: {
fontSize: '18',
},
viewWindowMode:'explicit',
viewWindow: {
max:100,
min:0
}
},
bars: 'vertical', // Required for Material Bar Charts.
width: 400,
height: 400
};
var chart = new google.charts.Bar(document.getElementById('barchart_material'));
chart.draw(data, google.charts.Bar.convertOptions(options));
};
I have then added a CSS setting to force the font size back to normal:
#barchart_material g text {
font-size: 12px !important;
}
I have updated the fiddle here: https://jsfiddle.net/SBComms/pa4yLcb3/1/

Google Visualization - Specify Type from Query

I am creating a dashboard that queries a published google spreadsheet as the dataTable. The charts (column, table, and candlestick) show up just fine. However, I have added a listener event for 'sort' on the table and would like this to sort the corresponding data in the column and candlestick charts. However, when I sort the table by clicking on the header, the charts show the following error in red:
"All data columns of the same series must be of the same data type".
My spreadsheet contains a string for the first column and numbers for the other columns. However, I assume that I am getting this error message because the query is not returning the data as 'string' in the first column and 'number' in the other columns. Can I specify this? If so, how? Thanks.
EDIT: Here is my code...the addListener event at the bottom is causing the issue:
var query = new google.visualization.Query('https://docs.google.com/spreadsheet/pub?key=0AukymWvA6LlzdHpwblVtSmU3ZXJOMGhUVFZiV3NnSkE&single=true&gid=0&output=html');
query.setQuery('SELECT A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T');
query.send(function (response) {
if (response.isError()) {
alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
var data = response.getDataTable();
// CategoryFilter for Grade
var gradeFilter = new google.visualization.ControlWrapper({
controlType: 'CategoryFilter',
containerId: 'gradeFilter_div',
options: {
filterColumnIndex: 3
}
});
// CategoryFilter for School
var schoolFilter = new google.visualization.ControlWrapper({
controlType: 'CategoryFilter',
containerId: 'schoolFilter_div',
options: {
filterColumnIndex: 16
}
});
// CategoryFilter for Teacher
var teacherFilter = new google.visualization.ControlWrapper({
controlType: 'CategoryFilter',
containerId: 'teacherFilter_div',
options: {
filterColumnIndex: 17
}
});
// CategoryFilter for Entity
var entityFilter = new google.visualization.ControlWrapper({
controlType: 'CategoryFilter',
containerId: 'entityFilter_div',
options: {
filterColumnIndex: 18
}
});
var numberSlider = new google.visualization.ControlWrapper({
controlType: 'NumberRangeFilter',
containerId: 'rNumberRangeFilter_div',
options: {
filterColumnIndex: 19
}
});
// create a Table visualization
var rBubbleChart = new google.visualization.ChartWrapper({
chartType: 'BubbleChart',
containerId: 'rBubble_div',
options: {
title: 'Comparison of Percentiles',
height: 500,
width: 500,
chartArea:{left:"10%",top:"10%",width:"80%",height:"80%"},
backgroundColor: 'transparent',
bubble: {opacity: 0.6, stroke: 'transparent', textStyle: {fontSize: 8, color: 'transparent'}},
hAxis: {minValue: 0, maxValue: 100, gridlines: {count: 11, color: '#EEEEEE'}, title: '2013 Percentile', titleTextStyle: {fontSize:10}, textStyle: {fontSize:10}},
vAxis: {minValue: 0, maxValue: 100, gridlines: {count: 11, color: '#EEEEEE'}, title: '2014 Percentile', titleTextStyle: {fontSize:10}, textStyle: {fontSize:10}},
colors: ['#a4c2f4','#89B0F0','#6d9eeb','#558BE2','#3c78d8','#2767D2','#1155cc'],
legend: {position: 'in', alignment: 'center', textStyle: {fontSize:10}},
animation: {duration:1500, easing:'out'},
sizeAxis: {minSize: 2, minValue: 5, maxSize: 30, maxValue: 500}
},
view: {columns: [0, 1, 2, 3, 4]}
});
//Draw chart with y=x line
var hackChart = new google.visualization.ChartWrapper({
chartType: 'LineChart',
containerId: 'hack_chart_div',
dataTable: [['x', 'y'],[0, 0], [100, 100]],
options: {
height: 500,
width: 500,
chartArea:{left:"10%",top:"10%",width:"80%",height:"80%"},
hAxis: {minValue: 0, maxValue: 100, textPosition: 'none', gridlines: {count: 0}, baselineColor: 'none'},
vAxis: {minValue: 0, maxValue: 100, textPosition: 'none', gridlines: {count: 0}, baselineColor: 'none'},
colors: ['black'],
pointSize: 0,
lineWidth: 1,
enableInteractivity: false,
legend: {position: 'none'},
}
});
hackChart.draw();
var rCandlestickChart = new google.visualization.ChartWrapper({
chartType: 'CandlestickChart',
containerId: 'rCandle_div',
options: {
title: 'Distribution of Performance (Interquartile Range)',
height: 250,
width: 500,
chartArea:{left:"10%",top:"10%",width:"80%",height:"60%"},
hAxis: {textStyle: {fontSize:10}},
vAxis: {minValue: 0, maxValue: 100, title: 'Percentile', titleTextStyle: {fontSize:10}, textStyle: {fontSize:10}},
legend: {position: 'in'},
animation: {duration:1500, easing:'out'},
colors: ['#a4c2f4','#3c78d8']
},
view: {columns:[5, 6, 7, 8, 9, 10, 11, 12, 13]}
});
var rColumnChart = new google.visualization.ChartWrapper({
chartType: 'ColumnChart',
containerId: 'rColumn_div',
options: {
title: 'Percent Satisfactory',
height: 250,
width: 500,
chartArea:{left:"10%",top:"10%",width:"80%",height:"60%"},
hAxis: {textStyle: {fontSize:10}},
vAxis: {minValue: 0, maxValue: 100, title: '% Satisfactory', titleTextStyle: {fontSize:10}, textStyle: {fontSize:10}},
legend: {position: 'in'},
animation: {duration:1500, easing:'out'},
colors: ['#a4c2f4','#3c78d8']
},
view: {columns:[5, 14, 15]}
});
var rTableChart = new google.visualization.ChartWrapper({
chartType: 'Table',
containerId: 'rTable_div',
options: {
width: '300px',
height: '500px',
allowHtml: true,
cssClassNames: {tableCell: 'styleRows', headerRow: 'styleHeader'}
},
view: {columns: [16, 5, 19]}
});
var formatter = new google.visualization.BarFormat({width: 100, drawZeroLine: true, min: -20, max: 20});
formatter.format(data, 19);
// Create the dashboard.
var dashboard = new google.visualization.Dashboard(document.getElementById('dashboard')).
bind(entityFilter, [rBubbleChart, rCandlestickChart, rColumnChart, rTableChart]).
bind(schoolFilter, gradeFilter).bind(gradeFilter, teacherFilter).
bind(teacherFilter, [rBubbleChart, rCandlestickChart, rColumnChart, rTableChart]).
bind(numberSlider, [rBubbleChart, rCandlestickChart, rColumnChart, rTableChart]).
draw(data);
google.visualization.events.addListener(rTableChart, 'ready', function() {
google.visualization.events.addListener(rTableChart.getChart(), 'sort', function(event) {
data.sort([{column: event.column, desc: !event.ascending}]);
boxchartObject = rCandlestickChart.getChart();
boxchartObject.draw(data);
columnChartObject = rColumnChart.getChart();
columnChartObject.draw(data);
});
});
The problem is in the way you redraw the charts. By calling the ChartWrapper#getChart#draw method, you are bypassing all of the ChartWrapper's parameters - including the view parameter which specifies the columns to use. This is why you get the data type error. You need to redraw the Dashboard (to avoid a clash between the sorting and the filters). Use this:
var dashboard = new google.visualization.Dashboard(document.getElementById('dashboard'));
google.visualization.events.addListener(rTableChart, 'ready', function() {
google.visualization.events.addListener(rTableChart.getChart(), 'sort', function(event) {
// set the sorting options in the table so they are preserved on redraw
rTableChart.setOption('sortColumn', event.column);
rTableChart.setOption('sortAscending', event.ascending);
// convert the Table view column to a DataTable column
var col = rTableChart.getView().columns[event.column];
// sort the DataTable
data.sort([{column: col, desc: !event.ascending}]);
// redraw the dashboard
dashboard.draw(data);
});
});
dashboard.bind(schoolFilter, gradeFilter)
.bind(gradeFilter, teacherFilter)
.bind([entityFilter, teacherFilter, numberSlider], [rBubbleChart, rCandlestickChart, rColumnChart, rTableChart])
.draw(data);
To ensure that the sort event handler is set up properly, you should set up the Table wrapper's ready event before calling the Dashboard's draw method.
Update working example: http://jsfiddle.net/asgallant/t5rkJ/4/

Google Charts Column width in pixels

I have set the width of my bar chart to 580px. The problem that the chart overflows the area in the view window. Would it be possible to reduce the size of the columns in the chart area to reduce the overall chart size? I mean would it be possible to change the scale for the numbers per pixel for each column so that for example the 280 number is shown in less pixel space?
You can use responsive BarChart.
var options = {
width: "100%", //adjusts according to the screen size
height: 500,
bar: { groupWidth: "75%" },
legend: { position: 'right', textStyle: { color: 'black' } },
isStacked: true,
vAxis: { textStyle: { color: 'black' } },
hAxis: { textStyle: { color: 'black' }, format: ' #,##0.00' },
chartArea: { width: "50%", height: "70%" }};
function resizeCharts() {
// redraw charts, dashboards, etc here
chart.draw(dadosGrafico, options);}
$(window).resize(resizeCharts);