Hierarchies graphs in google charts - javascript

How can I build something like this (with subcategories on the one of the axis)

although the requested layout is not available via standard configuration options,
it is possible to achieve, if you're ok with modifying the svg manually
when the chart's 'ready' event fires, add the category labels and group lines
see following working snippet, which is just an example to show the possibility
several assumptions are made based on the size and placement of the chart...
google.charts.load('current', {
callback: drawChart,
packages: ['corechart']
});
function drawChart() {
var data = google.visualization.arrayToDataTable([
['State', 'Store', 'Sales'],
['California', 'Donald\'s Market', 1560],
['California', 'Alexei\'s Specialties', 1090],
['California', '24-Seven', 345],
['Texas', 'Albert Market', 245],
['Texas', 'Jim\'s Market', 245],
['Texas', 'International Food Store', 82]
]);
var options = {
bars: 'horizontal',
chartArea: {
left: 204
},
height: 400,
vAxis: {
textStyle: {
fontSize: 10
}
}
};
var chartDiv = document.getElementById('chart_div');
var chart = new google.visualization.BarChart(chartDiv);
var view = new google.visualization.DataView(data);
view.setColumns([1, 2, {
calc: 'stringify',
sourceColumn: 2,
type: 'string',
role: 'annotation'
}]);
google.visualization.events.addListener(chart, 'ready', function () {
var rowIndex = -1;
var stateValue = '';
var svgParent = chartDiv.getElementsByTagName('svg')[0];
Array.prototype.forEach.call(chartDiv.getElementsByTagName('text'), function(text) {
var groupLabel;
if ((text.getAttribute('text-anchor') === 'end') &&
(parseFloat(text.getAttribute('x')) < 200)) {
rowIndex++;
if (stateValue !== data.getValue(rowIndex, 0)) {
stateValue = data.getValue(rowIndex, 0);
groupLabel = text.cloneNode(true);
groupLabel.setAttribute('x', '60');
groupLabel.innerHTML = stateValue;
svgParent.appendChild(groupLabel);
addGroupLine(groupLabel, -24);
}
if (rowIndex === (data.getNumberOfRows() - 1)) {
addGroupLine(text, 16);
}
}
});
function addGroupLine(text, yOffset) {
var groupLine = chartDiv.getElementsByTagName('rect')[0].cloneNode(true);
groupLine.setAttribute('y', parseFloat(text.getAttribute('y')) + yOffset);
groupLine.setAttribute('x', '16');
groupLine.setAttribute('height', '0.8');
groupLine.setAttribute('width', '188');
groupLine.setAttribute('stroke', 'none');
groupLine.setAttribute('stroke-width', '0');
groupLine.setAttribute('fill', '#000000');
svgParent.appendChild(groupLine);
}
});
chart.draw(view, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

Related

How to place an icon inside Google ColumnChart

I have columnchart bar which has one column and I wanna place an icon top of the bar.This bar is dynamically changing as randomly.I checked some sources on the internet and Google Chart API but couldn't find a solution.Is there any way to do that?Below you can see the code belongs to my chart
Here it's demo to give you idea about my Grid and Chart also
https://stackblitz.com/edit/angular-pt2kha?file=app/grid-list-overview-example.html
Here what I expect to see
What I tried below to generate this Column Chart below
TS File
title= 'Temperature';
type = 'ColumnChart';
data= [['',25]];
columnNames= ['Element', 'Temperature'];
options= {
backgroundColor: '#fafafa',
legend: {position: 'none'},
animation: {
duration: 250,
easing: 'ease-in-out',
startup: true,
},
bar: {
groupWidth: 50
},
hAxis: {
baselineColor: 'none',
ticks: []
},
vAxis: {
baselineColor: 'none',
ticks: [],
viewWindow: {
max:40,
min:0
}
}
}
width=100;
height=300;
ngOnInit()
{
interval(2000).subscribe(()=>{
this.data = [
['', (Math.random() * 41)],
];
});
}
HTML File
<div style="border-style:solid;border-width:1px;">
<google-chart #chart
[title]="title"
[type]="type"
[data]="data"
[columnNames]="columnNames"
[options]="options"
[width]="width"
[height]="height"
>
</google-chart>
</div>
you can add icons using chart methods getChartLayoutInterface() & getBoundingBox()
on the chart's 'ready' event, find the position of the bar,
then place the image.
although not angular, it will work the same,
see following working snippet...
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
var data = new google.visualization.DataTable();
data.addColumn('string', 'X');
data.addColumn('number', 'Y');
data.addRows([
[{v: 'a', p: {thumb: 'clone_old.png'}}, 20],
[{v: 'b', p: {thumb: 'boba_fett.png'}}, 15],
[{v: 'c', p: {thumb: 'jango_fett.png'}}, 30],
[{v: 'd', p: {thumb: 'clone_3.png'}}, 5],
[{v: 'e', p: {thumb: 'clone_2.png'}}, 25]
]);
var options = {
legend: 'none'
};
var container = document.getElementById('chart_div');
var containerBounds = container.getBoundingClientRect();
var chart = new google.visualization.ColumnChart(container);
google.visualization.events.addListener(chart, 'ready', function () {
var chartLayout = chart.getChartLayoutInterface();
for (var i = 0; i < data.getNumberOfRows(); i++) {
var barBounds = chartLayout.getBoundingBox('bar#0#' + i);
var path = 'http://findicons.com/files/icons/512/star_wars/32/';
var thumb = container.appendChild(document.createElement('img'));
thumb.src = path + data.getProperty(i, 0, 'thumb');
thumb.style.position = 'absolute';
thumb.style.top = (barBounds.top + containerBounds.top - 40) + 'px';
thumb.style.left = (barBounds.left + containerBounds.left + (barBounds.width / 2) - 16) + 'px';
}
});
chart.draw(data, options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
`

Google Charts: Problem handling a 'click' event

I have a Google Chart, a bar chart, that I recently extended so that selecting one of the bars will open a new page, showing the data corresponding to that bar. I used the guidelines for basic interactivity, using a selectHandler to process the event.
I then decided to do the same thing when clicking on one of the labels, but I have not been able to get this to work. I looked pretty carefully at the docs, and at this older question (which is, in fact, my actual question: how do I make a hyperlink out of the chart's labels?) for guidance. I added a Listener for click events, and a handler for this, but my chart is not responding to them.
My basic setup is:
google.charts.load('current', {
callback: drawChart,
packages: ['bar']
});
var books = [
['2018-07', 5, 98.0],
['2018-08', 5, 100.0], // etc.
];
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Date');
data.addColumn('number', 'Number Purchased');
data.addColumn('number', 'Price Paid');
data.addRows(books);
var options = {
chart: {
title: 'Book Purchases',
},
width: 800,
height: 800,
bars: 'horizontal',
series: {
0: {
axis: 'purchased'
},
1: {
axis: 'price_paid'
}
},
axes: {
x: {
purchased: {
side: 'top',
label: 'Number Purchased'
},
price_paid: {
label: 'Price Paid'
}
}
}
};
function selectHandler() {
var selectedItem = chart.getSelection()[0];
if (selectedItem) {
var date = data.getValue(selectedItem.row, 0);
var query_string = '?date=' + date;
var path = window.location.pathname;
path = path.replace("bookgraph", "");
path = path + "search" + query_string;
var newURL = window.location.protocol + "//" + window.location.host + path;
window.open(newURL, '_blank');
}
}
function clickHandler(e) {
alert('The user has clicked on ' + e.targetID);
}
var chart = new google.charts.Bar(document.getElementById('bookgraph_material'));
google.visualization.events.addListener(chart, 'click', clickHandler);
google.visualization.events.addListener(chart, 'select', selectHandler);
chart.draw(data, options);
The selectHandler works fine. But I can't even get the clickHandler to show the alert (after this works, I'll actually code the rest of it); it's apparently never fired, regardless of where I click. What am I doing wrong?
I set up a JS Fiddle page for this, to experiment with, with an HTML frame so it'll actually work; this shows the working select (albeit to a 404, of course) and the nonworking click.
Thanks.
the 'click' event is not supported by Material charts,
see issue #: 2257...
and there are several configuration options that are not supported as well,
see issue #: 2143...
Material = google.charts.Bar -- packages: ['bar']
Classic = google.visualization.BarChart -- packages: ['corechart']
one work around would be to use a Classic chart with option --> theme: 'material'
or register your own click event,
see following working snippet...
google.charts.load('current', {
callback: drawChart,
packages: ['bar']
});
var books = [
['2016-01', 3, 45.0],
['2016-02', 3, 56.0],
['2016-03', 1, 23.0],
['2016-04', 4, 60.0],
['2016-05', 1, 0],
['2016-06', 3, 14.0],
['2016-07', 4, 65.0],
['2016-08', 1, 15.0],
['2016-09', 13, 234.0],
['2016-10', 20, 834.0],
['2016-11', 5, 115.0],
['2016-12', 5, 58.0],
['2017-01', 6, 122.0],
['2017-02', 4, 84.0],
['2017-03', 1, 0],
['2017-04', 1, 30.0],
['2017-05', 2, 38.0],
['2017-06', 1, 11.0],
['2017-07', 0, 0],
['2017-08', 4, 88.0],
['2017-09', 5, 89.0],
['2017-10', 4, 73.0],
['2017-11', 5, 79.0],
['2017-12', 2, 37.0],
['2018-01', 1, 22.0],
['2018-02', 5, 98.0],
['2018-03', 5, 132.0],
['2018-04', 3, 56.0],
['2018-05', 14, 272.0],
['2018-06', 4, 88.0],
['2018-07', 5, 98.0],
['2018-08', 5, 100.0],
];
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Date');
data.addColumn('number', 'Number Purchased');
data.addColumn('number', 'Price Paid');
data.addRows(books);
var options = {
chart: {
title: 'Book Purchases',
},
width: 800,
height: 800,
bars: 'horizontal',
series: {
0: {
axis: 'purchased'
},
1: {
axis: 'price_paid'
}
},
axes: {
x: {
purchased: {
side: 'top',
label: 'Number Purchased'
},
price_paid: {
label: 'Price Paid'
}
}
}
};
function selectHandler() {
var selectedItem = chart.getSelection()[0];
if (selectedItem) {
var date = data.getValue(selectedItem.row, 0);
var query_string = '?date=' + date;
var path = window.location.pathname;
path = path.replace("bookgraph", "");
path = path + "search" + query_string;
var newURL = window.location.protocol + "//" + window.location.host + path;
window.open(newURL, '_blank');
}
}
function clickHandler(e) {
if (e.target.tagName === 'text') {
console.log(e.target.textContent);
}
}
var container = document.getElementById('bookgraph_material');
var chart = new google.charts.Bar(container);
google.visualization.events.addListener(chart, 'select', selectHandler);
container.addEventListener('click', clickHandler);
chart.draw(data, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="bookgraph_material"></div>

Google chart stacked bar get key name when onclick

google.charts.load('current', { packages: ['corechart', 'bar'] });
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['DATA', 'L', 'P'],
['PCX', 18, 21],['PCG', 131, 34],['PCO', 9, 3],['PGD', 441, 269],['PAH', 1, 1],['POD', 8, 5],['PCT', 80, 180],['PDD', 1, 7],['PZZ', 3, 8],['PKK', 461, 580],['PBI', 494, 248],['PKI', 2, 5],['PKL', 5, 1] ]);
var options = {
isStacked: 'percent',
legend: { position: 'top' },
chartArea: {
left: 40,
width: '100%',
height: '75%'
},
vAxis: {
minValue: 0,
},
hAxis: {
textStyle: { fontSize: 7 }
}
};
var chart = new google.visualization.ColumnChart(document.getElementById('DataChart'));
chart.draw(data, options);
google.visualization.events.addListener(chart, 'select', selectHandler);
function selectHandler(e) {
var selection = chart.getSelection();
if (selection.length > 0) {
var mydata = data.getValue(selection[0].row,0);
alert(mydata);
//i want get key data L when klik stacked data L or P when klik stacked data P, because i want to send data
chart.setSelection([]);
}
}
}
$(window).resize(function () {
drawChart();
});
svg > g > g:last-child { pointer-events: none }
<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="DataChart" ></div>
Hello, i have a create stacked bar from google chart plugin, i want to get data when i'm click slice bar (red or blue) when i click red i get data "P" if i click blue get data "L" this demo in Js Fiddle
i'm already get data name data like PCX,PCG,PGD etc but i want get data "L" if click blue color and get data "P" when click red color. Help me thank's
to get the column label, use data table method --> getColumnLabel(colIndex)
pass the column property from the selection...
function selectHandler(e) {
var selection = chart.getSelection();
if (selection.length > 0) {
// get column label
var colLabel = data.getColumnLabel(selection[0].column);
var mydata = data.getValue(selection[0].row,0);
console.log(colLabel + ': ' + mydata);
chart.setSelection([]);
}
}
see following working snippet...
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
$(window).resize(drawChart);
drawChart();
});
function drawChart() {
var data = google.visualization.arrayToDataTable([
['DATA', 'L', 'P'],
['PCX', 18, 21],['PCG', 131, 34],['PCO', 9, 3],['PGD', 441, 269],['PAH', 1, 1],['POD', 8, 5],['PCT', 80, 180],['PDD', 1, 7],['PZZ', 3, 8],['PKK', 461, 580],['PBI', 494, 248],['PKI', 2, 5],['PKL', 5, 1] ]);
var options = {
isStacked: 'percent',
legend: { position: 'top' },
chartArea: {
left: 40,
width: '100%',
height: '75%'
},
vAxis: {
minValue: 0,
},
hAxis: {
textStyle: { fontSize: 7 }
}
};
var chart = new google.visualization.ColumnChart(document.getElementById('DataChart'));
chart.draw(data, options);
google.visualization.events.addListener(chart, 'select', selectHandler);
function selectHandler(e) {
var selection = chart.getSelection();
if (selection.length > 0) {
var colLabel = data.getColumnLabel(selection[0].column);
var mydata = data.getValue(selection[0].row,0);
console.log(colLabel + ': ' + mydata);
chart.setSelection([]);
}
}
}
<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="DataChart"></div>
In google charts document,
"If both row and column are specified, the selected element is a cell. If only row is specified, the selected element is a row. If only column is specified, the selected element is a column."
(https://developers.google.com/chart/interactive/docs/events)
In your demo, when clicking blueBar(L), selection[0].column will be 1 and the other(redBar(P)) will be 2.
Thus you can get P/L in selectHandler
var data = ['DATA', 'L', 'P']
function selectHandler(e) {
var selection = chart.getSelection();
if (selection.length > 0) {
var temp = selection[0].column
console.log(data[temp]) // temp = 1 will be 'L'; temp = 2 will be 'P'
}
}

Google Line Chart: Change color when line down

https://developers.google.com/chart/interactive/docs/gallery/linechart
Hello, guys, I would like to know that is there a way to change the color of the line when it is moving down. I have googled but I was not able to find anything.
like e.g the line graph is moving upwards it's ok as soon as the graph line tilts downward than that downward should only be red. If after that it moves upward then the upward line should not be red.
Here is a screenshot of what I'm trying to obtain:
http://imgur.com/a/GuWDx
If anybody knows this please help me
Here is my code of what am I doing right now:
function draw_chart(chart_data, id, action)
{
var url = base_url + "controller/function/" + id ;
statData = getAjax(url, '', false, 'json');
minimum = '';
maximum = '';
upside = '';
if (statData.min) {
minimum = statData.min;
}
if (statData.max) {
maximum = statData.max;
}
if (statData.upside == '1') {
upside = -1;
}
value = $("#value_" + id).val();
var name = $('#name_' + id).val();
var names = [];
if (value == 2) {
var names = name.split('/');
} else {
names[0] = name;
}
title = $("#name_" + id).val();
google.load('visualization', '1.1', {packages: ['line', 'corechart']});
format = $("#format-select_" + id + " option:selected").val();
if (statData.row[0].type == 'currency') {
format = '$#';
}
var options = {
title: title,
width: 820,
height: 500,
titlePosition: 'none',
legend: 'none',
lineWidth: 3,
annotation: {
0: { style: "line"},
1: { style: "line"}
},
series: {0: { style: "area"} , 1: {type: "area"}},
animation: {duration: 1000, easing: 'in'},
strictFirstColumnType: true,
fontColor: "#333333",
fontSize: "12px",
colors: ["#5AA023", "#3F5F9F" , ""],
pointSize: 6,
fontSize: 11,
enableEvents: true,
forceIFrame: false,
tooltip: {showColorCode: false, },
vAxis: {
gridlines:{color: "#E6E6E6"},
textStyle:{color: "#666666"},
baselineColor: "#CACACA",
format: format,
viewWindow:{
min: minimum,
max: maximum
},
direction: upside,
},
hAxis: {gridlines:{color: "#E6E6E6" , count:chart_data.length},
baselineColor: "#CACACA",
textStyle:{color: "#666666"},
format: "MMM dd yyyy",
textPosition: "out",
slantedText: true,
},
chartArea: {height: 420, width: 750, top: 14, left: 45, right: 0}
};
if (action && action == "update") {
//alert(action);
}
else {
var chart_div = document.getElementById('chart'+id);
var chart_div1 = document.getElementById('chart1'+id);
var chart = new google.visualization.LineChart(chart_div);
google.visualization.events.addListener(chart, 'select', clickHandler);
data = new google.visualization.DataTable();
data.addColumn('string', 'Season Start Date');
data.addColumn({type: 'string', role: 'annotation'});
data.addColumn('number', names[0].trim());
if (value == 2) {
data.addColumn('number', names[1].trim());
for (i = 0; i < chart_data.length; i++)
data.insertRows(0, [[new Date(chart_data[i].date), parseInt(chart_data[i].val), parseInt(chart_data[i].val1)]]);
}
else {
for (i = 0; i < chart_data.length; i++) {
if (!chart_data[i].quarter) {
date = chart_data[i].date.split('-');
month = getMonthName(date[1]);
day = date[2];
year = date[0];
data.insertRows(0, [[month+' '+day+' '+year , '.' , parseInt(chart_data[i].val) ]]);
} else {
data.insertRows(0, [[chart_data[i].quarter , '.' , parseInt(chart_data[i].val) ]]);
}
}
}
}
}
if (statData.row[0].type == 'currency') {
var formatter = new google.visualization.NumberFormat({prefix: '$'});
formatter.format(data, 1);
}
var dataView = new google.visualization.DataView(data);
dataView.setColumns([
// reference existing columns by index
0, 1,
// add function for line color
{
calc: function(data, row) {
console.log("ok world!");
var colorDown = '#0000FF';
var colorUp = 'green';
if ((row === 0) && (data.getValue(row, 1) < data.getValue(row + 1, 1))) {
return colorDown;
} else if ((row > 0) && (data.getValue(row - 1, 1) < data.getValue(row, 1))) {
return colorDown;
}
return colorUp;
},
type: 'string',
role: 'style'
}
]);
chart.draw(dataView, options);
use a DataView and setColumns to provide a function that determines line direction
and returns the appropriate line color
see following working snippet...
google.charts.load('current', {
callback: drawLineColors,
packages: ['corechart']
});
function drawLineColors() {
var data = new google.visualization.DataTable();
data.addColumn('number', 'X');
data.addColumn('number', 'Y');
data.addRows([
[0, 2000],
[3, 1700],
[6, 1400],
[9, 2500],
[12, 3000],
[15, 4700],
[18, 2200],
[21, 1500],
[24, 1200],
[27, 1800],
[30, 2600],
[33, 2800],
[36, 3000],
[39, 2300],
[42, 2000],
[45, 4000]
]);
var options = {
curveType: 'function',
height: 200,
legend: {
position: 'top'
}
};
var dataView = new google.visualization.DataView(data);
dataView.setColumns([
// reference existing columns by index
0, 1,
// add function for line color
{
calc: function(data, row) {
var colorDown = '#0000FF';
var colorUp = '#FF0000';
if ((row === 0) && (data.getValue(row, 1) < data.getValue(row + 1, 1))) {
return colorDown;
} else if ((row > 0) && (data.getValue(row - 1, 1) < data.getValue(row, 1))) {
return colorDown;
}
return colorUp;
},
type: 'string',
role: 'style'
}
]);
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(dataView, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

Google chart javascript

I'm using Google Charts for a small projects for myself, and I'm not very good with javascript so I thought I'd ask for some help.
Basically I want to change the current values of the chart by pressing a button.
This is the script:
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['', 'YES', 'NO'],
['', 5, 2],
]);
var options = {
title: 'Win / Loss ratio',
vAxis: {title: 'Chart', titleTextStyle: {color: 'red'}}
};
var chart = new google.visualization.BarChart(document.getElementById('chart'));
chart.draw(data, options);
}
The values 5 and 2 should be changed when clicking button_1 or button_2
All help is appreciated.
You can do something like this:
function drawChart() {
var data = google.visualization.arrayToDataTable([
['', 'YES', 'NO'],
['', 5, 2],
]);
var options = {
title: 'Win / Loss ratio',
vAxis: {title: 'Chart', titleTextStyle: {color: 'red'}}
};
var chart = new google.visualization.BarChart(document.getElementById('chart'));
chart.draw(data, options);
function incrementYes () {
data.setValue(0, 1, data.getValue(0, 1) + 1);
chart.draw(data, options);
}
function incrementNo () {
data.setValue(0, 2, data.getValue(0, 2) + 1);
chart.draw(data, options);
}
// assumes button_1 and button_2 have id's "button_1" and "button_2"
var btn1 = document.querySelector('#button_1');
var btn2 = document.querySelector('#button_2');
if (document.addEventListener) {
// add event listener in most browsers
btn1.addEventListener('click', incrementYes);
btn2.addEventListener('click', incrementNo);
}
else if (document.attachEvent) {
// add event listener in IE
btn1.attachEvent('onclick', incrementYes);
btn2.attachEvent('onclick', incrementNo);
}
else {
// add event listener in legacy browsers
btn1.onclick = incrementYes;
btn2.onclick = incrementNo;
}
}

Categories

Resources