Add description in column chart by Google Charts? - javascript

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

Related

Adding an HTML rendered title in Google Charts

I'm trying to create an HTML rendered title in Google Charts. I want to create a string variable that contains HTML code and then pass it on as the title of the chart. Here's a jsFiddle. Here's what I'm trying to do:
HTML
<div id="chart_div" style="width: 900px; height: 500px;"></div>
JS
google.load("visualization", "1", {
packages: ["corechart"]
});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Task', 'Hours per Day'],
['Work', 11],
['Eat', 2],
['Commute', 2],
['Watch TV', 2],
['Sleep', 7]
]);
var ch = "<span>Hello World!</span>";
ch = $($.parseHTML(ch));
var options = {
title: ch
};
var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
When I try outputting the string as a title, I get [object object]. I tried doing $($.parseHTML(ch)).html(); but it looks like this strips the HTML tags because when I add styling to the span element it doesn't style the title. What should I do to get an HTML string to be displayed as a title with styling?
the titleTextStyle option applies to the entire chart title,
it is not possible using standard config options to style only part of the title
it will also not accept html, since it is drawn using svg
you could use an adjacent <div> and leave the title out of the options,
or change the title's svg once the chart's 'ready' event fires...
the title will be in a svg <text> element,
to separate the title from the other <text> elements on the chart,
use an initial value that can be used to find it...
var options = {
title: 'chartTitle'
};
in the ready handler, find the element...
google.visualization.events.addListener(chart, 'ready', function () {
var chartTitle = $('#chart text').filter(':contains("chartTitle")')[0];
});
use the <tspan> element to style different parts of the <text> element
result may look something like this...
<text><tspan style="font-weight: bold;">Chart</tspan> Title</text>
see following working snippet...
google.charts.load('current', {
callback: function () {
var data = new google.visualization.DataTable({
cols: [
{label: 'x', type: 'string'},
{label: 'y0', type: 'number'},
],
rows: [
{c:[{v: 'row 0'}, {v: 10}]},
{c:[{v: 'row 1'}, {v: 5}]},
{c:[{v: 'row 2'}, {v: 1}]},
{c:[{v: 'row 3'}, {v: 2}]},
{c:[{v: 'row 4'}, {v: 8}]}
]
});
var options = {
title: 'chartTitle'
};
var container = document.getElementById('chart');
var chart = new google.visualization.LineChart(container);
google.visualization.events.addListener(chart, 'ready', function () {
var svgNS = $('#chart svg')[0].namespaceURI;
var chartTitle = $('#chart text').filter(':contains("chartTitle")')[0];
$(chartTitle).text('');
var textStyle = document.createElementNS(svgNS, 'tspan');
$(textStyle).attr('fill', '#ff0000');
$(textStyle).attr('font-weight', 'bold');
$(textStyle).text('Chart ');
$(chartTitle).append(textStyle);
var textStyle = document.createElementNS(svgNS, 'tspan');
$(textStyle).attr('fill', '#0000ff');
$(textStyle).attr('font-weight', 'normal');
$(textStyle).text('Title');
$(chartTitle).append(textStyle);
});
chart.draw(data, options);
},
packages: ['corechart']
});
<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>
I'm not sure about editing it with HTML/CSS but you can use something that google-charts offers with titleTextStyle
var options = {
titleTextStyle: {
color: <string>, // any HTML string color ('red', '#cc00cc')
fontName: <string>, // i.e. 'Times New Roman'
fontSize: <number>, // 12, 18 whatever you want (don't specify px)
bold: <boolean>, // true or false
italic: <boolean> // true of false
}
}
Comes from this stack answer: Stack
Google Documentation here: Chart Customization

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

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>

Google visualization set column dock

I am struggling with google charts. I want bars to be displayed from bottom, rather than from top. Currently they are "hanging" like on the image below:
I don't see proper setting in docs, if it is there, please correct me. This is the code responsible for handling the display:
function parseInterval(value) {
var result = new Date(1,1,1);
result.setMilliseconds(value*1000);
return result;
}
(function($) {
$(document).ready(function(){
var loading = $('#loading');
$.getJSON("/api/v1/users", function(result) {
var dropdown = $("#user_id");
$.each(result, function(item) {
dropdown.append($("<option />").val(this.user_id).text(this.name));
});
dropdown.show();
loading.hide();
});
$('#user_id').change(function(){
var selected_user = $("#user_id").val();
var chart_div = $('#chart_div');
if(selected_user) {
loading.show();
chart_div.hide();
$.getJSON("/api/v1/mean_time_month/"+selected_user, function(result) {
$.each(result, function(index, value) {
value[1] = parseInterval(value[1]);
});
var data = new google.visualization.DataTable();
data.addColumn('string', 'Month');
data.addColumn('datetime', 'Mean time (h:m:s)');
data.addRows(result);
var options = {
hAxis: {
title: 'Month'
},
vAxis: {
title: 'Mean presence time',
minValue: new Date(1, 1, 1, 0, 0)
},
};
var formatter = new google.visualization.DateFormat({pattern: 'HH:mm:ss'});
formatter.format(data, 1);
chart_div.show();
loading.hide();
var chart = new google.visualization.ColumnChart(chart_div[0]);
chart.draw(data, options);
});
}
});
});
})(jQuery);
try using option vAxis.direction...
The direction in which the values along the vertical axis grow. Specify -1 to reverse the order of the values.
vAxis: {
direction: -1
}
see following working snippet...
google.charts.load('current', {
callback: drawChart,
packages:['corechart']
});
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Month');
data.addColumn('datetime', 'Mean time (h:m:s)');
data.addRows([
['Jan', new Date(1, 1, 1, 8, 16, 13)],
['Feb', new Date(1, 1, 1, 9, 24, 45)],
['Mar', new Date(1, 1, 1, 7, 36, 56)],
['Apr', new Date(1, 1, 1, 4, 20, 42)],
['May', new Date(1, 1, 1, 6, 51, 16)]
]);
var options = {
hAxis: {
title: 'Month'
},
vAxis: {
direction: -1,
title: 'Mean presence time',
minValue: new Date(1, 1, 1, 0, 0)
}
};
var formatter = new google.visualization.DateFormat({pattern: 'HH:mm:ss'});
formatter.format(data, 1);
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
but i think the real problem lies within the data
notice the y-axis values the chart displays in the example above,
the order doesn't seem right, as well as the range (10am - 12am)
it appears you're only interested in the time values
as such, recommend using 'timeofday' vs. 'datetime'
(see --> working with timeofday)
The DataTable 'timeofday' column data type takes an array of either 3 or 4 numbers, representing hours, minutes, seconds, and optionally milliseconds, respectively. Using timeofday is different than using date and datetime in that the values are not specific to a date, whereas date and datetime always specify a date.
For example, the time 8:30am would be: [8, 30, 0, 0], with the 4th value being optional ([8, 30, 0] would output the same 'timeofday' value).
see following working snippet for example using 'timeofday'...
google.charts.load('current', {
callback: drawChart,
packages:['corechart']
});
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Month');
data.addColumn('timeofday', 'Mean time (h:m:s)');
data.addRows([
['Jan', [8, 16, 13]],
['Feb', [9, 24, 45]],
['Mar', [7, 36, 56]],
['Apr', [4, 20, 42]],
['May', [6, 51, 16]]
]);
var options = {
hAxis: {
title: 'Month'
},
vAxis: {
title: 'Mean presence time',
minValue: [0, 0, 0]
}
};
var formatter = new google.visualization.DateFormat({pattern: 'HH:mm:ss'});
formatter.format(data, 1);
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

Google Charts fetching from Json

I'm trying to create charts using Google Charts Api. My data is stored as a json file as shown.
{
"1":[{"a":0,"d":0}],
"2":[{"a":0,"d":0}],
"3":[{"a":6,"d":62.92}],
"4":[{"a":1.57,"d":75.32}],
"5":[{"a":1.67,"d":66.45}],
"6":[{"a":1.25,"d":76}],
"7":[{"a":1.36,"d":75.08}],
"8":[{"a":1.59,"d":69.27}],
...
}
I'm fetching json file, pushing the objects to a javascript array. It works with no problem. I added these lines to understand what's happening. However Google Api doesn't accept my values and shows only
dots.push([5, 50]);
dots.push([7,60]);
Here's my code
function drawDots()
{
var data = new google.visualization.DataTable();
data.addColumn('number', 'a');
data.addColumn('number', 'd');
dots = new Array;
dots.push([5, 50]);
dots.push([7,60]);
$.getJSON("/graph/graph.json", function(json)
{
$.each(json, function(id, num)
{
$.each(num, function(i, e)
{
dots.push([e.a, e.d]);
});
});
});
data.addRows(dots);
var options = {
title: '',
hAxis: {title: 'Data 1', minValue: 0, maxValue: 100},
vAxis: {title: 'Data 2', minValue: 0, maxValue: 100},
legend: 'none'
};
var chart = new google.visualization.ScatterChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
Data type of the values are number, I also tried eval() to. In console, values are seems in array. Can't understand what's wrong.
Here's the console log of dots and data with a screen shot.
The problem is with the asynchronous getJSON call. The getJSON call happens but while it's still retrieving the contents of graph.json, the rest of the code executes. This means that the getJSON callback runs after the chart has been drawn.
Solution: Move the chart drawing code into the getJSON callback:
function drawDots()
{
var data = new google.visualization.DataTable();
data.addColumn('number', 'a');
data.addColumn('number', 'd');
dots = new Array;
dots.push([5, 50]);
dots.push([7,60]);
$.getJSON("/graph/graph.json", function(json)
{
$.each(json, function(id, num)
{
$.each(num, function(i, e)
{
dots.push([e.a, e.d]);
});
});
data.addRows(dots);
var options = {
title: '',
hAxis: {title: 'Data 1', minValue: 0, maxValue: 100},
vAxis: {title: 'Data 2', minValue: 0, maxValue: 100},
legend: 'none'
};
var chart = new google.visualization.ScatterChart(document.getElementById('chart_div'));
chart.draw(data, options);
});
}

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>

Categories