Adding an HTML rendered title in Google Charts - javascript

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

Related

How can I create a column chart with dynamic data

I am using google charts, and I would like to get a column chart with a fixed period, but dynamic values.
This is an example of a column chart, with fixed values, I would like to use the variables that are in the code after the comment (variables i would like to use) taking into account that columns and values are not always the same size.
function drawChart() {
// Simple example
var data = google.visualization.arrayToDataTable(
[ ['Year', 'Example 1', 'Example 2', 'Example 3'],
['2004', 1000, 400, 100],
['2005', 1170, 460, 500],
]);
// variables i would like to use
// These variables are fixed
var periodOne = '2004';
var periodTwo = '2005';
// non-fixed variables, variables that I will receive and that will not always be the same size.
var columns = ['Example 1', 'Example 2', 'Example 3'];
var valuesP1 = [1000, 400, 100];
var valuesP2 = [1170, 460, 500];
var options = {
title: 'Company Performance',
hAxis: {title: 'Year', titleTextStyle: {color: 'red'}},
tooltip: {legend:'none',isHtml:true, textStyle: {color: '#FF0000'}, showColorCode: true}
};
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div" style="width: 900px; height: 500px;"></div>
to build dynamically, start with a blank data table...
// create blank data table
var data = new google.visualization.DataTable();
add a column for the period / year...
// add period column
data.addColumn('string', 'Year');
add the dynamic columns...
// add columns
columns.forEach(function (label) {
data.addColumn('number', label);
});
add the period / year to the row values...
// add period to data
valuesP1.splice(0, 0, periodOne);
valuesP2.splice(0, 0, periodTwo);
add the row values to the data table...
// add data
data.addRow(valuesP1);
data.addRow(valuesP2);
see following working snippet...
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
// These variables are fixed
var periodOne = '2004';
var periodTwo = '2005';
// non-fixed variables, variables that I will receive and that will not always be the same size.
var columns = ['Example 1', 'Example 2', 'Example 3'];
var valuesP1 = [1000, 400, 100];
var valuesP2 = [1170, 460, 500];
// create blank data table
var data = new google.visualization.DataTable();
// add period column
data.addColumn('string', 'Year');
// add columns
columns.forEach(function (label) {
data.addColumn('number', label);
});
// add period to data
valuesP1.splice(0, 0, periodOne);
valuesP2.splice(0, 0, periodTwo);
// add data
data.addRow(valuesP1);
data.addRow(valuesP2);
// draw chart
var options = {
title: 'Company Performance',
hAxis: {title: 'Year', titleTextStyle: {color: 'red'}},
tooltip: {legend:'none',isHtml:true, textStyle: {color: '#FF0000'}, showColorCode: true}
};
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
window.addEventListener('resize', function () {
chart.draw(data, options);
});
chart.draw(data, options);
});
html, body {
height: 100%;
margin: 0px 0px 0px 0px;
padding: 0px 0px 0px 0px;
}
#chart_div {
height: 100%;
min-height: 400px;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

1 Event Handler for 2 Google Charts

So, I have two Google bar charts displayed on the same page.I tried creating one event handler for both of them and passing in the chart and data into the selectHandler. Can someone tell me what I'm doing wrong?
google.charts.load('current', {packages: ['corechart', 'bar']});
google.charts.setOnLoadCallback(drawBasic);
function drawBasic() {
var data1 = google.visualization.arrayToDataTable([
['Condition', 'Frequency'],
['Dementia', 6081],
['Hypertension', 6055],
['Hypercholesterolemia', 6035],
]);
var data2 = google.visualization.arrayToDataTable([
['Medication', 'Frequency'],
['Naproxen', 7632],
['Plavix', 7486]
]);
var options1 = {
title: 'Medical Conditions',
};
var options2 = {
title: 'Medications',
};
var conditionbarchart = new google.charts.Bar(
document.getElementById('conditions_chart'));
conditionbarchart.draw(data1, options1);
var medchart = new google.visualization.ColumnChart(
document.getElementById('medications_chart'));
medchart.draw(data2, options2);
google.visualization.events.addListener(conditionbarchart, 'select', selectHandler(conditionbarchart, data1));
google.visualization.events.addListener(medchart, 'select', selectHandler());
}
function selectHandler(mychart, mydata){
var selectedItem = mychart.getSelection()[0];
if(selectedItem){
var selection = mydata.getValue(selectedItem.row, 0);
alert('The user selected' + selection);
}
}
Here's the complete solution to answer my question:
<html>
<head>
<!--Load the AJAX API-->
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
// Load the Visualization API and the piechart package.
google.charts.load('current', {'packages':['corechart']});
// Set a callback to run when the Google Visualization API is loaded.
google.charts.setOnLoadCallback(drawChart);
// Callback that creates and populates a data table,
// instantiates the pie chart, passes in the data and
// draws it.
function drawChart() {
// Create the data table.
var data = new google.visualization.DataTable();
data.addColumn('string', 'Condition');
data.addColumn('number', 'Frequency');
data.addRows([
['Dementia', 3],
['Hypertension', 1],
['Hypercholesterolemia', 1],
['Coronary artery disease', 1],
['Heaches', 2]
]);
// Create the data table.
var data2 = new google.visualization.DataTable();
data2.addColumn('string', 'Medication');
data2.addColumn('number', 'Frequency');
data2.addRows([
['Naproxen', 3],
['Plavix', 1],
['Lasix', 1],
['Insulin', 1],
['Neurontin', 2]
]);
// Set chart options
var options = {
bars: 'vertical', // Required for Material Bar Charts.
hAxis: {
slantedText:true,
slantedTextAngle:90
},
height: 400,
backgroundColor: {fill: 'transparent'},
legend: {position: 'none'},
colors: ['#1b9e77']
};
// Set chart options
var options2 = {
bars: 'vertical', // Required for Material Bar Charts.
hAxis: {
slantedText:true,
slantedTextAngle:90
},
height: 400,
backgroundColor: {fill: 'transparent'},
legend: {position: 'none'},
colors: ['#1b9e77']
};
// Instantiate and draw our chart, passing in some options.
var conditionsbarchart = new google.visualization.ColumnChart(document.getElementById('conditions_chart'));
var medchart = new google.visualization.ColumnChart(document.getElementById('medications_chart'));
function selectHandler(mychart, mydata) {
var selectedItem = mychart.getSelection()[0];
if (selectedItem) {
var topping = mydata.getValue(selectedItem.row, 0);
alert('The user selected ' + topping);
}
}
google.visualization.events.addListener(conditionsbarchart, 'select', function(){
selectHandler(conditionsbarchart, data);
});
conditionsbarchart.draw(data, options);
google.visualization.events.addListener(medchart, 'select', function(){
selectHandler(medchart, data2);
});
medchart.draw(data2, options2);
}
</script>
</head>
<body>
<!--Div that will hold the pie chart-->
<div id="conditions_chart" style="width:400; height:300"></div>
<div id="medications_chart" style="width: 400; height: 300"></div>
</body>
</html>

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

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

Uncaught Error: Invalid value in 0,0

I'm having a really weird issue while trying to visualize this scatter plot using the google visualization API.
Basically, if I put the first data point as [0,0] everything will be fine, but if remove [0,0] as the first point, the chart won't produce. I checked the console and this is what it said:
"Uncaught SyntaxError: Unexpected token <
Uncaught Error: Invalid value in 0,0"
Why exactly does the first point need to be [0,0]?
<html>
<head>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Camera','Avg Rating'],
[ {v:6000, f: 'Canon EOS-1Ds Mark III'}, 60],
[ {v:5000, f: 'Canon EOS-1Ds Mark II'}, 50],
[ {v:4000, f: 'Canon EOS-1D Mark IV'}, 40]
]);
var options = {
title: 'Breakdown of Camera Models by Price, Photo Rating and Brand',
hAxis: {title: 'Price (USD)', minValue: 0, maxValue: 7500},
vAxis: {title: 'Avg Rating (at peak)', minValue: 0, maxValue: 55},
legend: 'none'
};
var chart = new google.visualization.ScatterChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</script>
</head>
<body>
<div id="chart_div" style="width: 1000px; height: 1000px;"></div>
</body>
</html>
The problem here is that the {v: value, f: 'formatted value'} syntax is not valid for use with the arrayToDataTable method (as documented here(https://developers.google.com/chart/interactive/docs/reference#google.visualization.arraytodatatable) ). If you want to use that syntax, you will have to define your DataTable manually, and then use the #addRows method
Not sure why I had the error, but I found a way to get around it. It started working when I used the DataTable constructor:
var data = new google.visualization.DataTable();
data.addColumn('number', 'Price');
data.addColumn('number', 'Canon');
data.addColumn('number', 'Nikon');
data.addColumn('number', 'Other');
data.addRows([
[{v:6000, f: 'Canon EOS-1Ds Mark III'}, 60 ,null ,null],
[{v:5000, f: 'Canon EOS-1Ds Mark II'}, 50 ,null ,null],
Instead of the arraytoDataTable constructor:
var data = google.visualization.arrayToDataTable([
['Camera','Avg Rating'],
[ {v:6000, f: 'Canon EOS-1Ds Mark III'}, 60],
[ {v:5000, f: 'Canon EOS-1Ds Mark II'}, 50],
[ {v:4000, f: 'Canon EOS-1D Mark IV'}, 40]
]);
Hope that helps anybody who also runs into this.

Categories