Google Charts - Shared label for adjacent columns with the same value - javascript

I have a Google Chart that's showing repeated values for adjacent rows containing the same value. Is there a way to make adjacent columns share a label if the value they represent is the same?

there are no standard options to prevent annotations from repeating,
but these could be easily removed
1)
if the annotation values are loaded as part of the data,
and you don't want to change how the data is loaded
use a simple routine to set the annotations to null
see following working snippet...
google.charts.load('current', {
callback: drawChart,
packages:['corechart']
});
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Month', 'Members', {role: 'annotation'}],
['2015-09', 0, '0'],
['2015-10', 0, '0'],
['2015-11', 0, '0'],
['2015-12', 0, '0'],
['2016-01', 1, '1'],
['2016-02', 1, '1'],
['2016-03', 1, '1'],
['2015-04', 3, '3'],
['2016-05', 3, '3'],
['2016-06', 3, '3'],
['2016-07', 3, '3'],
['2016-08', 3, '3'],
['2016-09', 3, '3'],
['2016-10', 4, '4'],
['2016-11', 6, '6'],
['2016-12', 6, '6'],
['2017-01', 8, '8'],
['2017-02', 8, '8'],
['2017-03', 8, '8'],
]);
// remove repeated annotations
var annotationText = null;
for (var i = 0; i < data.getNumberOfRows(); i++) {
if (annotationText === data.getValue(i, 2)) {
data.setValue(i, 2, null);
} else {
annotationText = data.getValue(i, 2);
}
}
var options = {
annotations: {
alwaysOutside: true,
textStyle: {
bold: true,
fontSize: 20
}
},
colors: ['#0097A7'],
hAxis: {
slantedText: true,
textStyle: {
bold: true,
fontSize: 16
}
},
height: 400,
legend: {
position: 'none'
},
vAxis: {
title: data.getColumnLabel(1)
}
};
var container = document.getElementById('chart_div');
var chart = new google.visualization.ColumnChart(container);
chart.draw(data, options);
};
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
2)
if the annotation values are set using a DataView,
modify the calc function to not repeat annotations
see following working snippet...
google.charts.load('current', {
callback: drawChart,
packages:['corechart']
});
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Month', 'Members'],
['2015-09', 0],
['2015-10', 0],
['2015-11', 0],
['2015-12', 0],
['2016-01', 1],
['2016-02', 1],
['2016-03', 1],
['2015-04', 3],
['2016-05', 3],
['2016-06', 3],
['2016-07', 3],
['2016-08', 3],
['2016-09', 3],
['2016-10', 4],
['2016-11', 6],
['2016-12', 6],
['2017-01', 8],
['2017-02', 8],
['2017-03', 8],
]);
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, {
calc: function (dt, row) {
if (row > 0) {
if (dt.getValue(row, 1) === dt.getValue(row - 1, 1)) {
return null;
}
}
return dt.getFormattedValue(row, 1);
},
role: 'annotation',
type: 'string'
}]);
var options = {
annotations: {
alwaysOutside: true,
textStyle: {
bold: true,
fontSize: 20
}
},
colors: ['#0097A7'],
hAxis: {
slantedText: true,
textStyle: {
bold: true,
fontSize: 16
}
},
height: 400,
legend: {
position: 'none'
},
vAxis: {
title: data.getColumnLabel(1)
}
};
var container = document.getElementById('chart_div');
var chart = new google.visualization.ColumnChart(container);
chart.draw(view, options);
};
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

Related

How to display a small bar even when a value is zero in Google Charts?

I have sometimes series where the values are all zero. When I apply a ColumnChart the figure is all empty, not showing that there are actually zero values.
How can I display the bars even when the values are zero?
I tried the following options:
{
type: options.type,
cssStyle: options.cssStyle,
data: {},
options: {
chartArea:{width:'80%'},
pointsVisible: true,
lineWidth: 4,
curveType: "none",
fontName: "Open Sans",
fontSize: 10,
colors: options.colors,
isStacked: "false",
fill: 10,
displayExactValues: true,
vAxis: {viewWindowMode:'explicit', minValue: -1, viewWindow: {min:0}, gridlines: {"color": "#f2f2f2", "count": 2}, baselineColor: "#f2f2f2", textStyle: options.textStyle},
hAxis: {gridlines: {"color": "#f2f2f2"}, baselineColor: "#f2f2f2", textStyle: options.textStyle},
legend: {position: 'bottom', alignment: 'center', textStyle: options.textStyle},
}
a bar will only be displayed if the value is not equal to zero
however, using object notation, we can provide the value (v:) and the formatted value (f:)
using the following, the bar will display, but when hovered, the tooltip shows a value of zero
{v: 0.1, f: '0'}
see following working snippet...
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
var data = google.visualization.arrayToDataTable([
['x', 'y'],
['A', {v: 0.1, f: '0'}],
['B', 2],
['C', 3],
['D', 4]
]);
google.visualization.events.addListener(chart, 'ready', function () {
chart.setSelection([{row: 0, column: 1}]);
});
chart.draw(data, {
tooltip: {
trigger: 'both'
}
});
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
In your code, test for zero values and convert that to .1 or whatever is appropriate for your scale.
function vAxisTest (vAxis) {
let scale = .1; //
if(vAxis === 0) {
vAxis = scale;
return scale;
}
else { return vAxis; }
}

Stepped Area Google charts wrong visualization

I'm using Google charts Stepped Area in my project, I have 2 data columns (datetime,state).
The problem is when the change in time is dynamic and not fixed the chart gets abnormal like this example, however when the data points are in fixed time change, the chart is drawn correctly for example in this code the points are one every 100 milliseconds.
Example 1 data
['Date', 'State'],
[new Date(1534078983500), 3],
[new Date(1534078983880), 1],
[new Date(1534080441460), 3],
[new Date(1534080441840), 1],
[new Date(1534080533960), 3],
[new Date(1534080534330), 1]
Example 2 data
['Date', 'State'],
[new Date(1534078983100), 3],
[new Date(1534078983200), 1],
[new Date(1534078983300), 3],
[new Date(1534078983400), 1],
[new Date(1534078983500), 3],
[new Date(1534078983600), 1]
according to the Data Format for the SteppedAreaChart,
the Data Type for the x-axis should be --> 'string'
although it may work with dates, the results may be inconsistent
instead, use the DateFormat class to convert the date to a timestamp string
see following working snippet...
here, a DataView is used to create a calculated column for the timestamp...
google.charts.load('current', {
packages:['corechart']
}).then(function () {
var data = google.visualization.arrayToDataTable([
['Date', 'State'],
[new Date(1534078983500), 3],
[new Date(1534078983880), 1],
[new Date(1534080441460), 3],
[new Date(1534080441840), 1],
[new Date(1534080533960), 3],
[new Date(1534080534330), 1]
]);
var formatTime = new google.visualization.DateFormat({
pattern: 'HH:ss.SSSS a'
});
var view = new google.visualization.DataView(data);
view.setColumns([{
calc: function (dt, row) {
return formatTime.formatValue(dt.getValue(row, 0));
},
label: data.getColumnLabel(0),
type: 'string'
}, 1]);
var options = {
title: 'The decline of \'The 39 Steps\'',
vAxis: {
title: 'Accumulated Rating',
ticks: [{ v: 0, f: '' }, { v: 1, f: 'Close' }, { v: 2, f: 'CLG/OPG' }, { v: 3, f: 'Open' }, { v: 4, f: '' }]
}
};
var chart = new google.visualization.SteppedAreaChart(document.getElementById('chart_div'));
chart.draw(view, options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
EDIT
if you need to use the explorer option,
you can use a number instead of a string
use the formatted value to display the actual dates,
and build custom ticks for the x-axis using the same approach...
see following working snippet...
google.charts.load('current', {
packages:['corechart']
}).then(function () {
var data = google.visualization.arrayToDataTable([
['Date', 'State'],
[new Date(1534078983500), 3],
[new Date(1534078983880), 1],
[new Date(1534080441460), 3],
[new Date(1534080441840), 1],
[new Date(1534080533960), 3],
[new Date(1534080534330), 1]
]);
var formatTime = new google.visualization.DateFormat({
pattern: 'HH:ss.SSSS a'
});
var view = new google.visualization.DataView(data);
view.setColumns([{
calc: function (dt, row) {
return {
v: row,
f: formatTime.formatValue(dt.getValue(row, 0))
};
},
label: data.getColumnLabel(0),
type: 'number'
}, 1]);
var xTicks = [];
for (var i = 0; i < view.getNumberOfRows(); i++) {
addTick(i);
}
function addTick(i) {
xTicks.push({
v: view.getValue(i, 0),
f: view.getFormattedValue(i, 0)
});
}
var options = {
explorer: {},
hAxis: {
ticks: xTicks
},
title: 'The decline of \'The 39 Steps\'',
vAxis: {
title: 'Accumulated Rating',
ticks: [{ v: 0, f: '' }, { v: 1, f: 'Close' }, { v: 2, f: 'CLG/OPG' }, { v: 3, f: 'Open' }, { v: 4, f: '' }]
}
};
var chart = new google.visualization.SteppedAreaChart(document.getElementById('chart_div'));
chart.draw(view, options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

How to add a custom axis line to a google chart?

I have a google scatter chart that has some significant thresholds in it. How do I visualise them?
Do I push some extra ticks on chart axis? If so how do I add just one and how do I style it?
I am aiming for something like this.
I am using React Google charts
add another column, or series, with the same value for all rows...
this can be added using a data view with calculated columns,
see following working snippet...
google.charts.load('current', {
callback: drawChart,
packages:['corechart']
});
function drawChart() {
var data = google.visualization.arrayToDataTable([
['x', 'y0'],
[0, 165],
[1, 175],
[2, 185]
]);
var view = new google.visualization.DataView(data);
view.setColumns([0, 1,
{
calc: function () {
return 150;
},
label: 'min',
type: 'number'
},
{
calc: function () {
return 175;
},
label: 'avg',
type: 'number'
},
{
calc: function () {
return 200;
},
label: 'max',
type: 'number'
}
]);
var options = {
vAxis: {
viewWindow: {
min: 125,
max: 225
}
}
};
var chart = new google.visualization.LineChart(document.getElementById('chart'));
chart.draw(view, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart"></div>
EDIT
here's another example...
add additional columns to the data table,
use getColumnRange for find the min and max x-axis values
google.charts.load('current', {
callback: drawChart,
packages:['corechart']
});
function drawChart() {
var data = google.visualization.arrayToDataTable([
['x', 'y0'],
[0, 165],
[1, 175],
[2, 185]
]);
var xAxisRange = data.getColumnRange(0);
data.addColumn({label: 'min', type: 'number'});
data.addColumn({label: 'avg', type: 'number'});
data.addColumn({label: 'max', type: 'number'});
data.addRows([
[xAxisRange.min, null, 150, 175, 200],
[xAxisRange.max, null, 150, 175, 200]
]);
var chart = new google.visualization.LineChart(document.getElementById('chart'));
chart.draw(data, {
series: {
1: {
color: 'cyan'
},
2: {
color: 'cyan'
},
3: {
color: 'cyan'
}
}
});
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart"></div>

Google Visualization highlight single grid line

how can I highlight a single grid line? I would like to set an optical temperature limit at 35 ° C.
Thanks! I have now added it to my code, but it does not work .... do you see my mistake? Or did I not understand something in your explanation?
Here is the edited version :
//Google Chart
google.charts.load('current', {
callback: function drawChart(peanut) {
const div = document.createElement('div');
div.id = peanut.color + peanut.mac.split(':').join('');
$('#charts').appendChild(div);
peanut.data = new google.visualization.DataTable();
peanut.data.addColumn('datetime', 'Time');
peanut.data.addColumn('number', '🥜 ' + peanut.label);
for (var i = 0, len = localStorage.length; i < len; i++) {
let dateTime = new Date(parseInt(localStorage.key(i)));
let item = JSON.parse(localStorage.getItem(localStorage.key(i)));
if (item.peanutMac === peanut.mac) {
if (item.temperatureCelsius) {
let temperature = parseFloat(item.temperatureCelsius);
peanut.data.addRows([ [dateTime, temperature] ]);
} else if (item.alert) {
let data = parseInt(item.alert);
peanut.data.addRows([ [dateTime, data] ]);
}
}
}
if (peanut.type == 'thermo') {
peanut.chart = new google.visualization.LineChart($('#' + div.id));
peanut.chartOptions = {
interpolateNulls: true,
fontName: 'Roboto',
curveType: 'function',
colors: [peanut.rgbColor],
width: document.body.clientWidth,
height: (window.innerHeight - 224) / 2,
legend: 'none',
lineWidth: 3,
vAxis: {
format: '#.## °C',
ticks: [15.00, 20.00, 25.00, 30.00, 35.00, 40.00]
},
hAxis: {
gridlines: {
color: '#fff'
}
}
};
peanut.viewColumns = [];
$.each(new Array(data.getNumberOfColumns()), function (colIndex) {
peanut.viewColumns.push(colIndex);
});
peanut.viewColumns.push({
calc: function () {
return 35;
},
label: 'optical temperature limit',
type: 'number'
});
}
peanut.view = new google.visualiation.DataView(data);
peanut.view.setColumns(viewColumns);
if (peanut.data.getNumberOfRows()) {
peanut.chart.draw(peanut.view, peanut.chartOptions);
}
}
packages:['corechart', 'table']
});
add another series with the value set to 35 for all rows
here, a data view is used to add a calculated column for the optical temperature limit
google.charts.load('current', {
callback: function () {
var data = new google.visualization.DataTable();
data.addColumn('number', 'x');
data.addColumn('number', 'y0');
data.addColumn('number', 'y1');
data.addColumn('number', 'y2');
data.addRows([
[1, 32.8, 20.8, 21.8],
[2, 30.9, 29.5, 32.4],
[3, 25.4, 27, 25.7],
[4, 21.7, 28.8, 20.5],
[5, 21.9, 27.6, 20.4]
]);
var options = {
interpolateNulls: true,
fontName: 'Roboto',
curveType: 'function',
legend: 'none',
lineWidth: 3,
vAxis: {
format: '#.## °C',
ticks: [20.00, 25.00, 30.00, 35.00, 40.00]
},
hAxis: {
gridlines: {
color: '#fff'
}
}
};
var viewColumns = [];
$.each(new Array(data.getNumberOfColumns()), function (colIndex) {
viewColumns.push(colIndex);
});
viewColumns.push({
calc: function () {
return 35;
},
label: 'optical temperature limit',
type: 'number'
});
var view = new google.visualization.DataView(data);
view.setColumns(viewColumns);
var chart = new google.visualization.LineChart($('#chart').get(0));
chart.draw(view, options);
},
packages:['corechart', 'table']
});
<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>
<div id="chart"></div>
Its not the best and safest way but I didnt find something on the google documentation:
You could use Jquery for it Ive tried it on the example from google docs and it works click
var line = $("svg g line")[4]
$(line).attr('stroke','red');
A simple way is to set the vAxis baseline to the value you want, say 35, and change the baselineColor. There is no option to change the width of this line, however, so if you need that, you should follow the suggestion above to add a series just to draw this line, and set its lineWidth.

Issue with vertical line (Google chart)

Folks,
I was trying to create a Column Chart using google chart API and I am having lots of issue in getting Y-AXIS line.
I understand x-axis is string that is why vertical grid line is not coming but Y-axis line must come. I am marking in RED as of now this line is not coming.
I have following code.
function drawChartSecond(resp) {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Activity');
data.addColumn('number', 'Hours');
data.addRows([
['Work', 11],
['Eat', 2 ],
['Commute', 2 ],
['Watch TV', 2],
['Sleep', 7]
]);
var options = {
title : '',
legend: {
position: 'right',
alignment: 'center'
},
tooltip: {
isHtml: true
},
hAxis: {
title: 'Activity',
titleTextStyle: {
color: 'Black',
fontSize : '12',
fontName : 'Arial'
},
baselineColor: '#CCCCCC'
},
chartArea : {
left: '8%',
top: '8%',
height:'70%',
width:'100%'
}
};
var chart = new google.visualization.ColumnChart(document.getElementById('chartdivsecond'));
chart.draw(data, options);
}
The only way to get that baseline is to use a chart with a continuous axis. You can use a DataView to convert your data to appropriately formatted numbers, and use the hAxis.ticks option to re-label the axis tick marks so it looks correct:
function drawChartSecond(resp) {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Activity');
data.addColumn('number', 'Hours');
data.addRows([
['Work', 11],
['Eat', 2 ],
['Commute', 2 ],
['Watch TV', 2],
['Sleep', 7]
]);
var view = new google.visualization.DataView(data);
view.setColumns([{
type: 'number',
label: data.getColumnLabel(0),
calc: function (dt, row) {
return {v: row + 1, f: dt.getValue(row, 0)};
}
}, 1]);
var ticks = [];
for (var i = 0; i < data.getNumberOfRows(); i++) {
ticks.push({v: i + 1, f: data.getValue(i, 0)});
}
var options = {
title : '',
legend: {
position: 'right',
alignment: 'center'
},
tooltip: {
isHtml: true
},
hAxis: {
title: 'Activity',
titleTextStyle: {
color: 'Black',
fontSize : '12',
fontName : 'Arial'
},
baselineColor: '#CCCCCC',
ticks: ticks
},
chartArea : {
left: '8%',
top: '8%',
height:'70%',
width:'100%'
}
};
var chart = new google.visualization.ColumnChart(document.getElementById('chartdivsecond'));
chart.draw(view, options);
}
see working example: http://jsfiddle.net/asgallant/6mXkv/

Categories