Related
I've got the following column chart and I'd like to position annotations for positive values above and for negative ones bellow columns. How to do that?
Additional question for values and annotation formatting - how to achieve the formatting of annotations (values above and bellow columns) like vAxis?
google.charts.load('current',{callback:drawChart,'packages':['corechart'],'language':'hr'});
function drawChart()
{
var data = new google.visualization.DataTable();
data.addColumn('date','Datum');
data.addColumn('number','Vrijednost');
data.addColumn('number','Pred. prema preth. 5 dana');
data.addColumn('number','Pred. prema preth. 10 dana');
data.addColumn('number','Relativna promjena');
data.addRows([
[new Date('2017-08-03'),12.10260,12.09797,12.148753333333,0.3199602122016],
[new Date('2017-08-02'),12.06400,12.16005,12.176186666667,-0.69882870054079],
[new Date('2017-08-01'),12.14890,12.12988,12.160606666667,0.3129386508133],
[new Date('2017-07-31'),12.11100,12.13091,12.14988,-0.001651364026678],
[new Date('2017-07-28'),12.11120,12.1175,12.116093333333,0.11821210392746],
[new Date('2017-07-27'),12.09690,12.10942,12.079293333333,0.24113757271416],
[new Date('2017-07-26'),12.06780,12.10184,12.040733333333,0],
[new Date('2017-07-25'),12.06780,12.06525,11.992986666667,0.28753781205331],
[new Date('2017-07-24'),12.03320,12.02595,11.95908,0.18983547592086],
[new Date('2017-07-21'),12.01040,11.95357,11.932006666667,0.41468798073707],
[new Date('2017-07-20'),11.96080,11.9183,11.9194,0.1951832460733],
[new Date('2017-07-19'),11.93750,11.89151,11.914186666667,0.21154604904174],
[new Date('2017-07-18'),11.91230,11.89439,11.937766666667,0.1235543302851],
[new Date('2017-07-17'),11.89760,11.93811,11.967046666667,-0.36595680537295],
[new Date('2017-07-14'),11.94130,11.95136,11.972373333333,0.068716427416171],
[new Date('2017-07-13'),11.93310,11.96335,11.975713333333,-0.1848567987152],
[new Date('2017-07-12'),11.95520,11.94968,11.96142,-0.070212979370754],
[new Date('2017-07-11'),11.96360,11.95871,11.944226666667,0.19429834846403],
[new Date('2017-07-10'),11.94040,11.9698,11.93224,0.099761076413629],
[new Date('2017-07-07'),11.92850,11.96977,11.934313333333,-0.13478894228354],
[new Date('2017-07-06'),11.94460,11.93426,11.931026666667,-0.10036297944233],
[new Date('2017-07-05'),11.95660,11.86036,11.91198,0.66342251932174],
[new Date('2017-07-04'),11.87780,11.86771,11.918093333333,0.048011724968622],
[new Date('2017-07-03'),11.87210,11.88418,11.919446666667,-0.078273604120727],
[new Date('2017-06-30'),11.88140,11.92094,11.907506666667,-0.076531684958581]
]);
var ColumnOpt = {
height: 300,
title: 'Relativna promjena vrijednosti [%]',
annotations: {textStyle: {fontName: 'Tahoma', fontSize: 9}},
vAxis: {textStyle: {fontName: 'Tahoma', fontSize: 9}, format: "#.#'%'",
viewWindow: {min: data.getColumnRange(4).min-0.5}},
hAxis: {textStyle: {fontName: 'Tahoma', fontSize: 9}, showTextEvery: 5},
chartArea: {width: '80%', height: '80%'},
legend: {position: 'none'},
colors: ['purple']
};
var view2 = new google.visualization.DataView(data);
view2.setColumns([0,4,{calc:'stringify',sourceColumn:4,type:'string',role:'annotation'}]);
var container = document.getElementById('Chart2');
var chart2=new google.visualization.ColumnChart(container);
var observer = new MutationObserver(function () {
$.each($('text[text-anchor="start"]'), function (index, label) {
var labelValue = parseFloat($(label).text());
if (labelValue < 0 && $(label).attr('font-height') !== 'bold') {
var bounds = label.getBBox();
var chartLayout = container.getChartLayoutInterface();
$(label).attr('y',chartLayout.getYLocation(labelValue) - bounds.height - 8);
}
});
});
observer.observe(container,{childList: true,subtree: true});
chart2.draw(view2,ColumnOpt);
}
<div id="Chart2"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://www.gstatic.com/charts/loader.js"></script>
several issues to deal with here
on this chart, the annotations have attribute --> text-anchor="middle"
vs. text-anchor="start" on the other
to format the annotations, use a number formatter
var formatAnnotation = new google.visualization.NumberFormat({
pattern: ColumnOpt.vAxis.format
});
use a custom function on the view, vs. predefined "stringify" function
var view2 = new google.visualization.DataView(data);
view2.setColumns([0,4,{
calc: function (dt, row) {
return formatAnnotation.formatValue(dt.getValue(row, 4));
},
type: 'string',
role: 'annotation'
}]);
this poses a problem with commas in the number
need to replace with decimal for parseFloat to handle ok
there is also an issue with annotations overlapping
but this snippet should get you closer...
google.charts.load('current',{callback:drawChart,'packages':['corechart'],'language':'hr'});
function drawChart()
{
var data = new google.visualization.DataTable();
data.addColumn('date','Datum');
data.addColumn('number','Vrijednost');
data.addColumn('number','Pred. prema preth. 5 dana');
data.addColumn('number','Pred. prema preth. 10 dana');
data.addColumn('number','Relativna promjena');
data.addRows([
[new Date('2017-08-03'),12.10260,12.09797,12.148753333333,0.3199602122016],
[new Date('2017-08-02'),12.06400,12.16005,12.176186666667,-0.69882870054079],
[new Date('2017-08-01'),12.14890,12.12988,12.160606666667,0.3129386508133],
[new Date('2017-07-31'),12.11100,12.13091,12.14988,-0.001651364026678],
[new Date('2017-07-28'),12.11120,12.1175,12.116093333333,0.11821210392746],
[new Date('2017-07-27'),12.09690,12.10942,12.079293333333,0.24113757271416],
[new Date('2017-07-26'),12.06780,12.10184,12.040733333333,0],
[new Date('2017-07-25'),12.06780,12.06525,11.992986666667,0.28753781205331],
[new Date('2017-07-24'),12.03320,12.02595,11.95908,0.18983547592086],
[new Date('2017-07-21'),12.01040,11.95357,11.932006666667,0.41468798073707],
[new Date('2017-07-20'),11.96080,11.9183,11.9194,0.1951832460733],
[new Date('2017-07-19'),11.93750,11.89151,11.914186666667,0.21154604904174],
[new Date('2017-07-18'),11.91230,11.89439,11.937766666667,0.1235543302851],
[new Date('2017-07-17'),11.89760,11.93811,11.967046666667,-0.36595680537295],
[new Date('2017-07-14'),11.94130,11.95136,11.972373333333,0.068716427416171],
[new Date('2017-07-13'),11.93310,11.96335,11.975713333333,-0.1848567987152],
[new Date('2017-07-12'),11.95520,11.94968,11.96142,-0.070212979370754],
[new Date('2017-07-11'),11.96360,11.95871,11.944226666667,0.19429834846403],
[new Date('2017-07-10'),11.94040,11.9698,11.93224,0.099761076413629],
[new Date('2017-07-07'),11.92850,11.96977,11.934313333333,-0.13478894228354],
[new Date('2017-07-06'),11.94460,11.93426,11.931026666667,-0.10036297944233],
[new Date('2017-07-05'),11.95660,11.86036,11.91198,0.66342251932174],
[new Date('2017-07-04'),11.87780,11.86771,11.918093333333,0.048011724968622],
[new Date('2017-07-03'),11.87210,11.88418,11.919446666667,-0.078273604120727],
[new Date('2017-06-30'),11.88140,11.92094,11.907506666667,-0.076531684958581]
]);
var ColumnOpt = {
height: 300,
title: 'Relativna promjena vrijednosti [%]',
annotations: {alwaysOutside: true, textStyle: {fontName: 'Tahoma', fontSize: 9}, stem: {length: 4, color: 'transparent'}},
vAxis: {textStyle: {fontName: 'Tahoma', fontSize: 9}, format: "#.#'%'",
viewWindow: {min: data.getColumnRange(4).min-0.5}},
hAxis: {textStyle: {fontName: 'Tahoma', fontSize: 9}, showTextEvery: 5},
chartArea: {width: '80%', height: '80%'},
legend: {position: 'none'},
colors: ['purple']
};
var formatAnnotation = new google.visualization.NumberFormat({
pattern: ColumnOpt.vAxis.format
});
var view2 = new google.visualization.DataView(data);
view2.setColumns([0,4,{
calc: function (dt, row) {
return formatAnnotation.formatValue(dt.getValue(row, 4));
},
type: 'string',
role: 'annotation'
}]);
var container = document.getElementById('Chart2');
var chart2=new google.visualization.ColumnChart(container);
var observer = new MutationObserver(function () {
$.each($('text[text-anchor="middle"]'), function (index, label) {
var labelValue = parseFloat($(label).text().replace(',', '.'));
if (labelValue < 0 && $(label).attr('fill') === '#800080') {
var bounds = label.getBBox();
var chartLayout = chart2.getChartLayoutInterface();
$(label).attr('y',chartLayout.getYLocation(labelValue) + bounds.height);
}
});
});
observer.observe(container,{childList: true,subtree: true});
chart2.draw(view2,ColumnOpt);
}
<div id="Chart2"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://www.gstatic.com/charts/loader.js"></script>
To change the point size, I set pointsize to 10 (for example).
options: {
pointSize: 10,
}
I would like to add a border to this point. Any idea ?
using a data view, you can apply a style to all the rows using a column role...
here, the view will include columns 0, 1 from the data,
and add a third calculated column for the style...
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, {
calc: function (dt, row) {
return 'point {stroke-color: #F00; stroke-width: 2;}';
},
role: 'style',
type: 'string'
}]);
then you must use the view when drawing the dashboard...
dashboard.draw(view);
see following working snippet...
google.charts.load('current', {packages: ['corechart', 'controls'],'language': 'fr'});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var query = new google.visualization.Query('https://docs.google.com/spreadsheets/d/1AOVg0jYaDvoHQeXBcDtJ6HdkBkkcQhEBi9Xo_crOvlk/edit?usp=sharing');
query.send(drawDashboard);
}
function drawDashboard(response) {
var data = response.getDataTable();
var chart = new google.visualization.ChartWrapper({
chartType: 'AreaChart',
containerId: 'chart_div',
options: {
// width and chartArea.width should be the same for the filter and chart
height: 400,
colors: ['#4aadde'],
curveType: 'function',
pointSize: 5,
chartArea: {
width: '75%'
},
title: 'Company Performance',
hAxis: {title: 'Year', titleTextStyle: {color: '#333'},format: 'd MMM yyyy' },
vAxis: {minValue: 0}
}
});
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, {
calc: function (dt, row) {
return 'point {stroke-color: #F00; stroke-width: 2;}';
},
role: 'style',
type: 'string'
}]);
var control = new google.visualization.ControlWrapper({
controlType: 'ChartRangeFilter',
containerId: 'control_div',
options: {
filterColumnIndex: 0,
ui: {
'chartType': 'AreaChart',
chartOptions: {
height: 50,
areaOpacity: 0.9,
colors: ['#5dade0'],
chartArea: {
width: '75%'
}
},
minRangeSize: 86400000, // 86400000ms = 1 day
snapToData: true
}
},
state: {
range: {
// set the starting range to January 2012
start: new Date(2017, 05, 15),
}
}
});
var dashboard = new google.visualization.Dashboard(document.querySelector('#dashboard_div'));
dashboard.bind([control], [chart]);
dashboard.draw(view);
function zoomLastDay () {
var range = data.getColumnRange(0);
control.setState({
range: {
start: new Date(range.max.getFullYear(), range.max.getMonth(), range.max.getDate() - 1),
end: range.max
}
});
control.draw();
}
function zoomLastWeek () {
var range = data.getColumnRange(0);
control.setState({
range: {
start: new Date(range.max.getFullYear(), range.max.getMonth(), range.max.getDate() - 7),
end: range.max
}
});
control.draw();
}
function zoomLastMonth () {
// zoom here sets the month back 1, which can have odd effects when the last month has more days than the previous month
// eg: if the last day is March 31, then zooming last month will give a range of March 3 - March 31, as this sets the start date to February 31, which doesn't exist
// you can tweak this to make it function differently if you want
var range = data.getColumnRange(0);
control.setState({
range: {
start: new Date(range.max.getFullYear(), range.max.getMonth() - 1, range.max.getDate()),
end: range.max
}
});
control.draw();
}
var runOnce = google.visualization.events.addListener(dashboard, 'ready', function () {
google.visualization.events.removeListener(runOnce);
if (document.addEventListener) {
document.querySelector('#lastDay').addEventListener('click', zoomLastDay);
document.querySelector('#lastWeek').addEventListener('click', zoomLastWeek);
document.querySelector('#lastMonth').addEventListener('click', zoomLastMonth);
}
else if (document.attachEvent) {
document.querySelector('#lastDay').attachEvent('onclick', zoomLastDay);
document.querySelector('#lastWeek').attachEvent('onclick', zoomLastWeek);
document.querySelector('#lastMonth').attachEvent('onclick', zoomLastMonth);
}
else {
document.querySelector('#lastDay').onclick = zoomLastDay;
document.querySelector('#lastWeek').onclick = zoomLastWeek;
document.querySelector('#lastMonth').onclick = zoomLastMonth;
}
});
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="dashboard_div">
<input id="lastDay" type="button" value="Hier" />
<input id="lastWeek" type="button" value="Dernière semaine" />
<input id="lastMonth" type="button" value="Dernier mois" />
<div id="chart_div"></div>
<div id="control_div"></div>
</div>
note: the following line (last in the fiddle) is for the old jsapi library
it isn't needed and should be removed...
google.load('visualization', '1', {packages:['controls'], callback: drawChart});
I created a google chart dashboard with different data for each donut chart but only data_2 returns, instead of data_1 for the first chart <div> and data_2 for the second chart <div>. Source document for multi chart w/ different data requires separate functions, but is there a way to use two datasets in the first function drawStuff_1?
I ultimately want one dashboard, one ControlWrapper (one-to-many), multiple data sets (carlos, josh, etc.) and multiple donut charts (<div> for carlos, <div> for josh, whoever else).
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', {'packages':['corechart', 'controls']});
google.charts.setOnLoadCallback(drawStuff_1);
google.charts.setOnLoadCallback(drawStuff_2);
function drawStuff_1() {
var dashboard = new google.visualization.Dashboard(
document.getElementById('programmatic_dashboard_div'));
programmaticFilter_1 = new google.visualization.ControlWrapper({
'controlType': 'CategoryFilter',
'containerId': 'programmatic_control_div_1',
'options': {
'filterColumnLabel': 'Status',
'ui': {'labelStacking': 'vertical'}
}
});
// First dataset
var data_1 = new google.visualization.arrayToDataTable([
['Status', 'Count'],
['Dual Approved' , 5],
['Approved', 7],
['Review', 3],
['Draft', 2],
['Not In', 6],
['Edit Rerun', 1],
]);
programmaticChart_1 = new google.visualization.ChartWrapper({
'chartType': 'PieChart',
'containerId': 'programmatic_chart_div_1',
'options': {
'width': 290,
'height': 220,
'chartArea': {'left': 20, 'top': 20, 'right': 0, 'bottom': 0},
'pieSliceText': 'value', //percentage' 'value' 'label''none'
'pieHole': 0.4,
'legend': {position: 'left', textStyle: {color: 'black', fontSize: 9, fontName: 'Garamond' }},
'pieSliceBorderColor': 'Black',
'title': 'Josh',
}
});
dashboard.bind(programmaticFilter_1, programmaticChart_1);
dashboard.draw(data_1);
}
function drawStuff_2() {
var dashboard = new google.visualization.Dashboard(
document.getElementById('programmatic_dashboard_div'));
// second dataset
var data_2 = new google.visualization.arrayToDataTable([
['Status', 'Count'],
['Dual Approved' , 1],
['Approved', 10],
['Review', 2],
['Draft', 9],
['Not In', 10],
['Edit Rerun', 4],
]);
programmaticChart_2 = new google.visualization.ChartWrapper({
'chartType': 'PieChart',
'containerId': 'programmatic_chart_div_2',
'options': {
'width': 250,
'height': 220,
'legend': 'none',
'chartArea': {'left': 20, 'top': 20, 'right': 0, 'bottom': 0},
'pieSliceText': 'value', //percentage' 'value' 'label''none'
'pieHole': 0.4,
'pieSliceBorderColor': 'Black',
'title': 'Carlos',
}
});
dashboard.bind(programmaticFilter_1, programmaticChart_2);
dashboard.draw(data_2);
}
</script>
<body>
<div id="programmatic_dashboard_div" style="border: 1px solid #ccc">
<td>
<div id="programmatic_control_div_1" style="padding-left: 2em; min-width: 250px"></div>
</td>
<table class="columns">
<tr>
<td>
<div id="programmatic_chart_div_1"></div>
</td>
<td>
<div id="programmatic_chart_div_2"></div>
</td>
</tr>
</table>
</div>
</body>
first, setOnLoadCallback should only be used once per page
but it's an easy work around, and you can include the callback directly in the load statement
google.charts.load('current', {
callback: drawStuff,
packages:['corechart', 'controls']
});
next, you can only have one dataset per Dashboard
however, you can use the view property on the ChartWrapper
to control which columns, or rows, apply to the chart
the view property is also available on the ControlWrapper
see following working snippet, which includes one dashboard, one control,
and two charts (one for each Carlos and Josh)
google.charts.load('current', {
callback: drawStuff,
packages:['corechart', 'controls']
});
function drawStuff() {
var dashboard = new google.visualization.Dashboard(
document.getElementById('dashboard_div')
);
// Combined dataset
var data = new google.visualization.arrayToDataTable([
['Status', 'Carlos', 'Josh'],
['Dual Approved', 5, 1],
['Approved', 7, 10],
['Review', 3, 2],
['Draft', 2, 9],
['Not In', 6, 10],
['Edit Rerun', 1, 3]
]);
var programmaticFilter = new google.visualization.ControlWrapper({
controlType: 'CategoryFilter',
containerId: 'control_div',
options: {
filterColumnLabel: 'Status',
ui: {
labelStacking: 'vertical'
}
}
});
var programmaticChart_Carlos = new google.visualization.ChartWrapper({
chartType: 'PieChart',
containerId: 'chart_div_Carlos',
options: {
width: 290,
height: 220,
chartArea: {'left': 20, 'top': 20, 'right': 0, 'bottom': 0},
pieSliceText: 'value',
pieHole: 0.4,
legend: {position: 'left', textStyle: {color: 'black', fontSize: 9, fontName: 'Garamond' }},
pieSliceBorderColor: 'Black'
},
view: {
columns: [0, 1]
}
});
programmaticChart_Carlos.setOption('title', 'Carlos');
var programmaticChart_Josh = new google.visualization.ChartWrapper({
chartType: 'PieChart',
containerId: 'chart_div_Josh',
options: {
width: 290,
height: 220,
chartArea: {'left': 20, 'top': 20, 'right': 0, 'bottom': 0},
pieSliceText: 'value',
pieHole: 0.4,
legend: {position: 'left', textStyle: {color: 'black', fontSize: 9, fontName: 'Garamond' }},
pieSliceBorderColor: 'Black'
},
view: {
columns: [0, 2]
}
});
programmaticChart_Josh.setOption('title', 'Josh');
dashboard.bind(
programmaticFilter,
[programmaticChart_Carlos, programmaticChart_Josh]
);
dashboard.draw(data);
}
.ggl-dashboard {
border: 1px solid #ccc;
}
.ggl-control (
min-width: 250px;
padding-left: 2em;
)
.ggl-chart (
display: inline-block;
)
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div class="ggl-dashboard" id="dashboard_div">
<div class="ggl-control" id="control_div"></div>
<div class="ggl-chart" id="chart_div_Carlos"></div>
<div class="ggl-chart" id="chart_div_Josh"></div>
</div>
I have a page that displays data using LineChart with a ChartRangeFilter control.
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load('visualization', '1', {packages: ['controls', 'charteditor']});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('date', 'X');
data.addColumn('number', 'Y1');
data.addColumn('number', 'Y2');
for (var i = 0; i < 12; i++) {
data.addRow([new Date(2016, i,1), Math.floor(Math.random() * 200), Math.floor(Math.random() * 200)]);
}
var dash = new google.visualization.Dashboard(document.getElementById('dashboard'));
var control = new google.visualization.ControlWrapper({
controlType: 'ChartRangeFilter',
containerId: 'control_div',
options: {
filterColumnIndex: 0,
ui: {
chartOptions: {
height: 50,
width: 600,
chartArea: {
width: '80%'
}
},
chartView: {
columns: [0, 1]
}
}
}
});
var chart = new google.visualization.ChartWrapper({
chartType: 'LineChart',
containerId: 'chart_div'
});
function setOptions (wrapper) {
wrapper.setOption('width', 620);
wrapper.setOption('chartArea.width', '80%');
}
setOptions(chart);
dash.bind([control], [chart]);
dash.draw(data);
google.visualization.events.addListener(control, 'statechange', function () {
var v = control.getState();
document.getElementById('dbgchart').innerHTML = v.range.start+ ' to ' +v.range.end;
return 0;
});
}
</script>
<div id="dashboard">
<div id="chart_div"></div>
<div id="control_div"></div>
<p><span id='dbgchart'></span></p>
</div>
And here's a working JSFiddle.
Here the control starts from Jan 1. When I change start range to Jan 2, the graph date starts to show from Feb. I could not identify the reason for this. Can anyone help me in this? In the end range it is working fine it seems.
In this example, on 'statechange' -- the value for the begin and end months, for the selected chart range, are modified to ensure data points are plotted.
The chart is then redrawn with updated options.
google.charts.load('44', {
callback: drawChart,
packages: ['controls', 'corechart']
});
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('date', 'X');
data.addColumn('number', 'Y1');
data.addColumn('number', 'Y2');
data.addRow([new Date(2016, 0, 1), 1,123]);
data.addRow([new Date(2016, 1, 1), 6,42 ]);
data.addRow([new Date(2016, 2, 1), 4,49 ]);
data.addRow([new Date(2016, 3, 1), 23,486 ]);
data.addRow([new Date(2016, 4, 1), 89,476 ]);
data.addRow([new Date(2016, 5, 1), 46,444 ]);
data.addRow([new Date(2016, 6, 1), 178,442 ]);
data.addRow([new Date(2016, 7, 1), 12,274 ]);
data.addRow([new Date(2016, 8, 1), 123,4934 ]);
data.addRow([new Date(2016, 9, 1), 144,4145 ]);
data.addRow([new Date(2016, 10, 1), 135,946 ]);
data.addRow([new Date(2016, 11, 1), 178,747 ]);
var control = new google.visualization.ControlWrapper({
controlType: 'ChartRangeFilter',
containerId: 'control_div',
options: {
filterColumnIndex: 0,
ui: {
chartOptions: {
height: 50,
width: 600,
chartArea: {
width: '80%'
}
}
}
}
});
var chart = new google.visualization.ChartWrapper({
chartType: 'LineChart',
containerId: 'chart_div',
options: {
width: 620,
chartArea: {
width: '80%'
},
hAxis: {
format: 'MMM',
slantedText: false,
maxAlternation: 1
}
}
});
function setOptions() {
var firstDate;
var lastDate;
var v = control.getState();
if (v.range) {
document.getElementById('dbgchart').innerHTML = v.range.start + ' to ' + v.range.end;
firstDate = new Date(v.range.start.getTime() + 1);
lastDate = new Date(v.range.end.getTime() - 1);
data.setValue(v.range.start.getMonth(), 0, firstDate);
data.setValue(v.range.end.getMonth(), 0, lastDate);
} else {
firstDate = data.getValue(0, 0);
lastDate = data.getValue(data.getNumberOfRows() - 1, 0);
}
var ticks = [];
for (var i = firstDate.getMonth(); i <= lastDate.getMonth(); i++) {
ticks.push(data.getValue(i, 0));
}
chart.setOption('hAxis.ticks', ticks);
chart.setOption('hAxis.viewWindow.min', firstDate);
chart.setOption('hAxis.viewWindow.max', lastDate);
if (dash) {
chart.draw();
}
}
setOptions();
google.visualization.events.addListener(control, 'statechange', setOptions);
var dash = new google.visualization.Dashboard(document.getElementById('dashboard'));
dash.bind([control], [chart]);
dash.draw(data);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="dashboard">
<div id="chart_div"></div>
<div id="control_div"></div>
<p><span id='dbgchart'></span></p>
</div>
It is because you only have one value for January (1st the jan) and when you set the start range to jan 2 the next value in your data if for Feb 1st.
The month value for month in the data object is zero-based.
i am trying to create a line chart using google charts libraries.
The data contains, date (x axis), number (col 1), number (col 2), float (col 3).
I want to display two decimals on the 3rd column tooltip while keeping its y axis 0 to 100, this is my current code (running here https://jsfiddle.net/uqh56hsu/1/):
google.charts.load('current', {'packages':['line']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('datetime', 'Hours');
data.addColumn('number', 'col1');
data.addColumn('number', 'col2');
data.addColumn('number', 'percent');
data.addRows([
[new Date(1454950800*1000),0,0,0],[new Date(1454947200*1000),0,0,0],[new Date(1454943600*1000),2,0,0.00],[new Date(1454940000*1000),24,1,4.17],[new Date(1454936400*1000),12,1,8.33],[new Date(1454932800*1000),64,4,6.25],[new Date(1454929200*1000),176,11,6.25],[new Date(1454925600*1000),142,7,4.93],[new Date(1454922000*1000),114,7,6.14],[new Date(1454918400*1000),0,0,0],[new Date(1454914800*1000),0,0,0],[new Date(1454911200*1000),0,0,0],[new Date(1454907600*1000),0,0,0],[new Date(1454904000*1000),0,0,0],[new Date(1454900400*1000),0,0,0],[new Date(1454896800*1000),0,0,0],[new Date(1454893200*1000),0,0,0],[new Date(1454889600*1000),0,0,0],[new Date(1454886000*1000),0,0,0],[new Date(1454882400*1000),0,0,0],[new Date(1454878800*1000),0,0,0],[new Date(1454875200*1000),0,0,0],[new Date(1454871600*1000),180,10,5.56], ]);
var formatter = new google.visualization.NumberFormat({
fractionDigits: 2,
suffix: '%'
});
formatter.format(data, 3);
var options = {
width: 900,
height: 500,
backgroundColor: '#f1f1f1',
colors: ['#ff851b', '#03a9f4', '#8dc859'],
dateFormat: 'H',
vAxes:[
{ titleTextStyle: {color: '#FF0000'}},
{ titleTextStyle: {color: '#FF0000'}, minValue: 0, maxValue: 100, format: '#\'%\'', viewWindowMode : 'explicit', viewWindow:{
max:100,
min:0
}}
],
series:[
{targetAxisIndex:0},
{targetAxisIndex:0},
{targetAxisIndex:1}
]
};
var chart = new google.charts.Line(document.getElementById('linechart_material'));
chart.draw(data, google.charts.Line.convertOptions(options));
}
I've tried adding the formatter code earlier and later in the code, trying to apply it to other columns, etc, nothing seem to work. The 3rd column tooltip always gets the decimals removed.
What am I doing wrong?
The format is being set in the vAxes option, which was overriding the formatter...
Just set the format to --> format: '#,##0.00\'%\''
No need for a formatter here...
google.charts.load('current', {'packages':['line']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('datetime', 'Hours');
data.addColumn('number', 'col1');
data.addColumn('number', 'col2');
data.addColumn('number', 'percent');
data.addRows([
[new Date(1454950800*1000),0,0,0],
[new Date(1454947200*1000),0,0,0],
[new Date(1454943600*1000),2,0,0.00],
[new Date(1454940000*1000),24,1,4.17],
[new Date(1454936400*1000),12,1,8.33],
[new Date(1454932800*1000),64,4,6.25],
[new Date(1454929200*1000),176,11,6.25],
[new Date(1454925600*1000),142,7,4.93],
[new Date(1454922000*1000),114,7,6.14],
[new Date(1454918400*1000),0,0,0],
[new Date(1454914800*1000),0,0,0],
[new Date(1454911200*1000),0,0,0],
[new Date(1454907600*1000),0,0,0],
[new Date(1454904000*1000),0,0,0],
[new Date(1454900400*1000),0,0,0],
[new Date(1454896800*1000),0,0,0],
[new Date(1454893200*1000),0,0,0],
[new Date(1454889600*1000),0,0,0],
[new Date(1454886000*1000),0,0,0],
[new Date(1454882400*1000),0,0,0],
[new Date(1454878800*1000),0,0,0],
[new Date(1454875200*1000),0,0,0],
[new Date(1454871600*1000),180,10,5.56]
]);
var options = {
width: 900,
height: 500,
backgroundColor: '#f1f1f1',
colors: ['#ff851b', '#03a9f4', '#8dc859'],
dateFormat: 'H',
vAxes:[
{
titleTextStyle: {color: '#FF0000'}
},
{
titleTextStyle: {
color: '#FF0000'
},
minValue: 0,
maxValue: 100,
format: '#,##0.00\'%\'', // set format here -- formatter not needed
viewWindowMode : 'explicit',
viewWindow: {
max:100,
min:0
}
}
],
series:[
{targetAxisIndex:0},
{targetAxisIndex:0},
{targetAxisIndex:1}
]
};
var chart = new google.charts.Line(document.getElementById('linechart_material'));
chart.draw(data, google.charts.Line.convertOptions(options));
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="linechart_material"></div>