How to "group by" columns in Google charts? [duplicate] - javascript

I am trying to create a google chart from the below data.
Year Product Value
2015 A 10
2015 B 20
2016 C 30
2016 D 40
Is this the right data for my google chart, using arrayToDataTable function, but not getting the desired output.
I want Product as the legends, Year as the xAxis value and the value should define the bars.
Thanks

each chart type has a specific data format you can check
typically, for most chart types, all columns after the first should be a number
unless you're using annotations, tooltips, or some other role
as such, the data would need to look similar to...
['Year', 'A', 'B', 'C', 'D'],
['2015', 10, 20, null, null],
['2016', null, null, 30, 40],
see following working snippet...
google.charts.load('current', {
callback: function () {
var data = google.visualization.arrayToDataTable([
['Year', 'A', 'B', 'C', 'D'],
['2015', 10, 20, null, null],
['2016', null, null, 30, 40],
]);
var chart = new google.visualization.BarChart(document.getElementById('chart_div'));
chart.draw(data);
},
packages: ['corechart']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
EDIT
to transpose the data from sql server into the format preferred by the chart,
first create a data view, with calculated columns for each unique product
then aggregate the view, grouping on year, using the group() method
use the aggregated data table to draw the chart
see following working snippet...
google.charts.load('current', {
callback: function () {
// raw table data
var data = google.visualization.arrayToDataTable([
['Year', 'Product', 'Value'],
[2015, 'A', 10],
[2015, 'B', 20],
[2016, 'C', 30],
[2016, 'D', 40]
]);
// format year as string
var formatYear = new google.visualization.NumberFormat({
pattern: '0000'
});
formatYear.format(data, 0);
// create data view
var view = new google.visualization.DataView(data);
// init column arrays
var aggColumns = [];
// use formatted year as first column
var viewColumns = [{
calc: function (dt, row) {
return dt.getFormattedValue(row, 0);
},
label: data.getColumnLabel(0),
type: 'string'
}];
// build view & agg column for each product
data.getDistinctValues(1).forEach(function (product, index) {
// add view column
viewColumns.push({
calc: function (dt, row) {
if (dt.getValue(row, 1) === product) {
return dt.getValue(row, 2);
}
return null;
},
label: product,
type: 'number'
});
// add agg column
aggColumns.push({
aggregation: google.visualization.data.sum,
column: index + 1,
label: product,
type: 'number'
});
});
// set view columns
view.setColumns(viewColumns);
// agg view by year
var group = google.visualization.data.group(
view,
[0],
aggColumns
);
// draw chart
var chart = new google.visualization.BarChart(document.getElementById('chart_div'));
chart.draw(group);
},
packages: ['corechart']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

Related

Remove empty space in between hAxis on Google Charts

I have a "vertical" material designed bar chart that receives values like this:
[1, 10],
[580, 12],
[10000, 1]
So it renders the xAxis like this:
Is there any way for me to remove the empty values of the hAxis and just leave the numbers that have values (i.e. 5000, 10000 and the smaller ones).
try using string values for the x-axis, instead of numbers...
['1', 10],
['580', 12],
['10000', 1]
see following working snippet...
google.charts.load('current', {
packages:['bar']
}).then(function () {
var data = google.visualization.arrayToDataTable([
['1', 10],
['580', 12],
['10000', 1]
], true);
var options = {
bars: 'vertical',
chart: {
title: 'Number of payments by amount',
},
hAxis: {
title: 'Amount'
}
};
var chart = new google.charts.Bar(document.getElementById('chart'));
chart.draw(data, google.charts.Bar.convertOptions(options));
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart"></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>

Add description in column chart by Google Charts?

I would like to replace "Step 1" in the screenshot below with the actual text in the table.
I think tooltip probably could help, but just didn't figure it out yet... Here is my code:
initGoolgeChart : function() {
// Load the Visualization API and the corechart package.
google.charts.load("current", {"packages": ["bar"] });
// Set a callback to run when the Google Visualization API is loaded.
google.charts.setOnLoadCallback(MigrationMonitor.drawCharts);
},
drawCharts : function() {
if(MigrationMonitor.dynamicFields.chartData != null && MigrationMonitor.dynamicFields.chartData.length > 0) {
var data = google.visualization.arrayToDataTable(MigrationMonitor.dynamicFields.chartData);
// won't work, don't know how i can add steps here then...
// data.addColumn({type:"string", role: "tooltip"});
// // Set chart options
var options = {
chart : {
title : "Build: " + MigrationMonitor.dynamicFields.chartTitle[1] + " VS " + MigrationMonitor.dynamicFields.chartTitle[2]
}
};
var chart = new google.charts.Bar(document.getElementById('charDiv'));
chart.draw(data, options);
}
}
use object notation to provide the value (v:) and formatted value (f:)
for the first column
the tooltip will display the formatted value (f:) by default
see following working snippet...
google.charts.load('current', {
callback: function () {
var data = google.visualization.arrayToDataTable([
['Step', 'Build: 22850', 'Build: 22852'],
[{v: 'Step 1', f: 'Pre-migration tasks'}, {v: 66, f: '66 (s)'}, {v: 67, f: '67 (s)'}],
[{v: 'Step 2', f: 'Dropping SP, Triggers, Views, and Functions'}, {v: 6, f: '6 (s)'}, {v: 7, f: '7 (s)'}]
]);
var container = document.getElementById('chart_div');
var chart = new google.charts.Bar(container);
chart.draw(data);
},
packages: ['bar']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
if you're not able to provide the value using object notation, or it's just too inconvenient,
use the setFormattedValue method,
see following working snippet...
google.charts.load('current', {
callback: function () {
var data = google.visualization.arrayToDataTable([
['Step', 'Build: 22850', 'Build: 22852'],
['Step 1', 66, 67],
['Step 2', 6, 7]
]);
var formatNumber = new google.visualization.NumberFormat({
pattern: '0 (s)'
});
formatNumber.format(data, 1);
for (var i = 0; i < data.getNumberOfRows(); i++) {
switch (data.getValue(i, 0)) {
case 'Step 1':
data.setFormattedValue(i, 0, 'Pre-migration tasks');
break;
case 'Step 2':
data.setFormattedValue(i, 0, 'Dropping SP, Triggers, Views, and Functions');
break;
}
}
var container = document.getElementById('chart_div');
var chart = new google.charts.Bar(container);
chart.draw(data);
},
packages: ['bar']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
This can be easily accomplished if you could iterate the data and add to a blank google.visualization.DataTable
Simply initialize it like this:
var data = new google.visualization.DataTable()
Then you can add columns like this:
data.addColumn('number', 'time');
For the column that will be used for the ToolTip:
data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});
Then you can add rows to this blank DataTable as follows:
dataTable.addRows([[10, 'tooltip for 10'], [20, 'tooltip for 20']]);
Probably your MigrationMonitor.dynamicFields.chartData will fit in there without the need to iterate.
Also there is an option tooltip: { isHtml: true } if you want to make tooltips HTML.
This is fully documented on the following link
https://developers.google.com/chart/interactive/docs/customizing_tooltip_content

Google Bar Chart data preparation -- Group by Column

I am trying to create a google chart from the below data.
Year Product Value
2015 A 10
2015 B 20
2016 C 30
2016 D 40
Is this the right data for my google chart, using arrayToDataTable function, but not getting the desired output.
I want Product as the legends, Year as the xAxis value and the value should define the bars.
Thanks
each chart type has a specific data format you can check
typically, for most chart types, all columns after the first should be a number
unless you're using annotations, tooltips, or some other role
as such, the data would need to look similar to...
['Year', 'A', 'B', 'C', 'D'],
['2015', 10, 20, null, null],
['2016', null, null, 30, 40],
see following working snippet...
google.charts.load('current', {
callback: function () {
var data = google.visualization.arrayToDataTable([
['Year', 'A', 'B', 'C', 'D'],
['2015', 10, 20, null, null],
['2016', null, null, 30, 40],
]);
var chart = new google.visualization.BarChart(document.getElementById('chart_div'));
chart.draw(data);
},
packages: ['corechart']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
EDIT
to transpose the data from sql server into the format preferred by the chart,
first create a data view, with calculated columns for each unique product
then aggregate the view, grouping on year, using the group() method
use the aggregated data table to draw the chart
see following working snippet...
google.charts.load('current', {
callback: function () {
// raw table data
var data = google.visualization.arrayToDataTable([
['Year', 'Product', 'Value'],
[2015, 'A', 10],
[2015, 'B', 20],
[2016, 'C', 30],
[2016, 'D', 40]
]);
// format year as string
var formatYear = new google.visualization.NumberFormat({
pattern: '0000'
});
formatYear.format(data, 0);
// create data view
var view = new google.visualization.DataView(data);
// init column arrays
var aggColumns = [];
// use formatted year as first column
var viewColumns = [{
calc: function (dt, row) {
return dt.getFormattedValue(row, 0);
},
label: data.getColumnLabel(0),
type: 'string'
}];
// build view & agg column for each product
data.getDistinctValues(1).forEach(function (product, index) {
// add view column
viewColumns.push({
calc: function (dt, row) {
if (dt.getValue(row, 1) === product) {
return dt.getValue(row, 2);
}
return null;
},
label: product,
type: 'number'
});
// add agg column
aggColumns.push({
aggregation: google.visualization.data.sum,
column: index + 1,
label: product,
type: 'number'
});
});
// set view columns
view.setColumns(viewColumns);
// agg view by year
var group = google.visualization.data.group(
view,
[0],
aggColumns
);
// draw chart
var chart = new google.visualization.BarChart(document.getElementById('chart_div'));
chart.draw(group);
},
packages: ['corechart']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

Multiple Google Charts

I am attempting to create multiple Google Charts, but I can't get it to work. I've tried everything I could find on Stack Overflow. I most recently attempted this fix, but it didn't work. I think I may be missing something. Can anyone see anything wrong with the code as it stands now?
Expected Behavior:
Page displays bar graph. Then, a line graph is displayed underneath the bar graph.
Current Behavior:
Page displays bar graph. Line graph does not display.
Here is JSFiddle. On a side note, the JavaScript only seems to work inline on JSFiddle. If I moved it into the JavaScript section, it did not function properly. Maybe this has something to do with the external resource that was called?
Regardless, I am currently doing this all inline for this experiment.
HTML:
<!DOCTYPE html>
<html>
<head>
<script src="https://www.google.com/jsapi" type="text/javascript">
</script>
<script type="text/javascript">
// Load the Visualization API and the chart packages.
google.load('visualization', '1.1', {
packages: ['line', 'bar', 'corechart']
});
// Set a callback to run when the Google Visualization API is loaded.
google.setOnLoadCallback(drawChart);
// Callback that creates and populates a data table,
// instantiates the charts, passes in the data and
// draws them.
function drawChart() {
// Create the data table.
var BarData = new google.visualization.arrayToDataTable([
['', 'Customer', 'Segment Avg'],
['TTM Sales', 4, 2],
['TTM Orders', 5, 3],
['TTM Categories', 7, 4]
]);
// Create the data table.
var LineData = new google.visualization.arrayToDataTable([
['Year', 'Customer', 'Segment Avg'],
['2011', 4, 5],
['2012', 5, 3],
['2013', 4, 2]
]);
// Set chart options
var BarOptions = {
chart: {
title: 'Performance',
},
width: 900,
height: 500
};
// Set chart options
var LineOptions = {
chart: {
title: 'Sales History'
},
width: 900,
height: 500
};
// Instantiate and draw our chart, passing in some options.
var BarChart = new google.charts.Bar(document.getElementById(
'bar_chart'));
BarChart.draw(BarData, BarOptions);
var LineChart = new google.charts.Line(document.getElementById(
'line_chart'));
LineChart.draw(LineData, LineOptions);
};
</script>
<title>Test Chart Page</title>
</head>
<body>
<!--Divs that will hold the charts-->
<div id="bar_chart"></div>
<div id="line_chart"></div>
</body>
</html>
It seems some changes have been made in the latest version of Google Charts API that causes this behavior, but there is a reliable way to render multiple charts on a single page. The idea is to render the next chart once the previous one is rendered, for that purpose you could utilize ready event handler.
Having said that, replace
var barChart = new google.charts.Bar(document.getElementById('bar_chart'));
barChart.draw(barData, barOptions);
var lineChart = new google.charts.Line(document.getElementById('line_chart'));
lineChart.draw(lineData, lineOptions);
with
var barChart = new google.charts.Bar(document.getElementById('bar_chart'));
google.visualization.events.addOneTimeListener(barChart, 'ready', function () {
var lineChart = new google.charts.Line(document.getElementById('line_chart'));
lineChart.draw(lineData, lineOptions);
});
barChart.draw(barData, barOptions);
Working example
google.load('visualization', '1.1', {
packages: ['line', 'bar', 'corechart']
});
// Set a callback to run when the Google Visualization API is loaded.
google.setOnLoadCallback(drawCharts);
function drawCharts() {
// Create the data table.
var barData = new google.visualization.arrayToDataTable([
['', 'Customer', 'Segment Avg'],
['TTM Sales', 4, 2],
['TTM Orders', 5, 3],
['TTM Categories', 7, 4]
]);
// Create the data table.
var lineData = new google.visualization.arrayToDataTable([
['Year', 'Customer', 'Segment Avg'],
['2011', 4, 5],
['2012', 5, 3],
['2013', 4, 2]
]);
// Set chart options
var barOptions = {
chart: {
title: 'Performance',
},
width: 900,
height: 500
};
// Set chart options
var lineOptions = {
chart: {
title: 'Sales History'
},
width: 900,
height: 500
};
var barChart = new google.charts.Bar(document.getElementById('bar_chart'));
google.visualization.events.addOneTimeListener(barChart, 'ready', function () {
var lineChart = new google.charts.Line(document.getElementById('line_chart'));
lineChart.draw(lineData, lineOptions);
});
barChart.draw(barData, barOptions);
};
<script src="https://www.google.com/jsapi" type="text/javascript"></script>
<div id="bar_chart"></div>
<div id="line_chart"></div>
Works with setTimeout:
// Instantiate and draw our chart, passing in some options.
var BarChart = new google.charts.Bar(document.getElementById(
'bar_chart'));
setTimeout(function() {
BarChart.draw(BarData, BarOptions);
}, 0);
var LineChart = new google.charts.Line(document.getElementById(
'line_chart'));
setTimeout(function() {
LineChart.draw(LineData, LineOptions);
}, 1e3);
Updated JSFiddle
The code below works by creating the second chart inside of setTimeout.
I don't know what is causing the problem,
but at least you have a workaround.
fiddle
<script type="text/javascript">
// Load the Visualization API and the chart packages.
google.load('visualization', '1.1', {
packages: ['line', 'bar', 'corechart']
});
// Set a callback to run when the Google Visualization API is loaded.
google.setOnLoadCallback(drawChart);
// Callback that creates and populates a data table,
// instantiates the charts, passes in the data and
// draws them.
function drawChart() {
// Create the data table.
var BarData = new google.visualization.arrayToDataTable([
['', 'Customer', 'Segment Avg'],
['TTM Sales', 4, 2],
['TTM Orders', 5, 3],
['TTM Categories', 7, 4]
]);
// Create the data table.
var LineData = new google.visualization.arrayToDataTable([
['Year', 'Customer', 'Segment Avg'],
['2011', 4, 5],
['2012', 5, 3],
['2013', 4, 2]
]);
// Set chart options
var BarOptions = {
chart: {
title: 'Performance',
},
width: 900,
height: 500
};
// Set chart options
var LineOptions = {
chart: {
title: 'Sales History'
},
width: 900,
height: 500
};
// Instantiate and draw our chart, passing in some options.
var BarChart = new google.charts.Bar(document.getElementById(
'bar_chart'));
var LineChart = new google.charts.Line(document.getElementById(
'line_chart'));
LineChart.draw(LineData, LineOptions);
setTimeout(function(){
BarChart.draw(BarData, BarOptions);
},50);
};
</script>
<body>
<!--Divs that will hold the charts-->
<div id="bar_chart"></div>
<div id="line_chart"></div>
</body>
Google fixed this timing issue in a recent release, available with the frozen version loader: https://developers.google.com/chart/interactive/docs/library_loading_enhancements#frozen-versions
Relevant thread: https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!msg/google-visualization-api/KulpuT418cg/yZieM8buCQAJ

Categories