I'm creating a column chart in Google Charts, and I want to also create a table chart showing summary data based on the column values, viz. average, minimum, maximum, total.
I've declared these as global variables (initialised as 0) outside the drawchart function, and I've assigned values within the drawchart function (without var):
function drawPower() {
$.get("costs_daily.csv", function(csvString) {
// transform the CSV string into a 2-dimensional array
var arrayData = $.csv.toArrays(csvString, {onParseValue: $.csv.hooks.castToScalar});
// this new DataTable object holds all the data
var data = new google.visualization.arrayToDataTable(arrayData);
/// get min, max cost
var range = data.getColumnRange(3);
var n_rows = data.getNumberOfRows();
function getSum(data, row) {
var total = 0;
for (i = 0; i < n_rows; i++)
total = total + data.getValue(i, row);
return total;
}
totCost = getSum(data, 3);
aveCost = totCost / n_rows;
minCost = range.min;
maxCost = range.max;
var options = {
title: 'Costs for last 30 days',
titleTextStyle: {color: 'grey', fontSize: 16},
hAxis: {title: 'Date', titleTextStyle: {bold: false, italic: false, color: 'grey'}, slantedTextAngle: 90, textStyle: {fontSize: 12}},
legend: {position: 'top'},
vAxes: {
0: {title: 'Cost (p)', titleTextStyle: {bold: false, italic: false, color: 'grey'}},
},
focusTarget: 'category',
intervals: {color:'#000000',
textStyle: { color: 'none'}},
series: {
0: {color: '#44AA99', type: 'bars'},
1: {color: '#DDCC77', type: 'bars'},
2: {
color: 'transparent',
type: 'line',
lineWidth: 0,
pointSize: 0,
enableInteractivity: false,
visibleInLegend: false
}
},
interpolateNulls: true,
bar: { groupWidth: '75%' },
isStacked: true,
};
var formatter = new google.visualization.NumberFormat(
{prefix: '£', fractionDigits: 2}
);
formatter.format(data,1);
formatter.format(data,2);
formatter.format(data,3);
var chart = new google.visualization.ComboChart(document.getElementById('power_div'));
chart.draw(data, options);
},'text');
}
I've then created a separate function to draw a table with these values:
function drawTable() {
statsData = [
['Stat', 'Cost'],
['Average', aveCost],
['Minimum', minCost],
['Maximum', maxCost],
['Total', totCost]
];
var stats = new google.visualization.arrayToDataTable(statsData);
var options = {
showRowNumber: false,
width: '100%',
height: '100%'
};
var formatter = new google.visualization.NumberFormat(
{prefix: '£', fractionDigits: 2}
);
formatter.format(stats,1);
var table = new google.visualization.Table(document.getElementById('table_div'));
table.draw(stats, options);
}
but the values remain at their initialised values (zero). Is there a way to pass the calculated values from the chart function to the table function?
not sure where drawTable is called from now,
but yes, you can pass the values from the chart function to the table function.
create the statsData in the chart function,
then pass it to the table function.
and remove where ever the table function is currently being called.
totCost = getSum(data, 3);
aveCost = totCost / n_rows;
minCost = range.min;
maxCost = range.max;
statsData = [
['Stat', 'Cost'],
['Average', aveCost],
['Minimum', minCost],
['Maximum', maxCost],
['Total', totCost]
];
drawTable(statsData);
...
function drawTable(statsData) {
...
see following snippet...
function drawPower() {
$.get("costs_daily.csv", function(csvString) {
// transform the CSV string into a 2-dimensional array
var arrayData = $.csv.toArrays(csvString, {onParseValue: $.csv.hooks.castToScalar});
// this new DataTable object holds all the data
var data = new google.visualization.arrayToDataTable(arrayData);
/// get min, max cost
var range = data.getColumnRange(3);
var n_rows = data.getNumberOfRows();
function getSum(data, row) {
var total = 0;
for (i = 0; i < n_rows; i++)
total = total + data.getValue(i, row);
return total;
}
totCost = getSum(data, 3);
aveCost = totCost / n_rows;
minCost = range.min;
maxCost = range.max;
statsData = [
['Stat', 'Cost'],
['Average', aveCost],
['Minimum', minCost],
['Maximum', maxCost],
['Total', totCost]
];
drawTable(statsData);
var options = {
title: 'Costs for last 30 days',
titleTextStyle: {color: 'grey', fontSize: 16},
hAxis: {title: 'Date', titleTextStyle: {bold: false, italic: false, color: 'grey'}, slantedTextAngle: 90, textStyle: {fontSize: 12}},
legend: {position: 'top'},
vAxes: {
0: {title: 'Cost (p)', titleTextStyle: {bold: false, italic: false, color: 'grey'}},
},
focusTarget: 'category',
intervals: {color:'#000000',
textStyle: { color: 'none'}},
series: {
0: {color: '#44AA99', type: 'bars'},
1: {color: '#DDCC77', type: 'bars'},
2: {
color: 'transparent',
type: 'line',
lineWidth: 0,
pointSize: 0,
enableInteractivity: false,
visibleInLegend: false
}
},
interpolateNulls: true,
bar: { groupWidth: '75%' },
isStacked: true,
};
var formatter = new google.visualization.NumberFormat(
{prefix: '£', fractionDigits: 2}
);
formatter.format(data,1);
formatter.format(data,2);
formatter.format(data,3);
var chart = new google.visualization.ComboChart(document.getElementById('power_div'));
chart.draw(data, options);
},'text');
}
function drawTable(statsData) {
var stats = new google.visualization.arrayToDataTable(statsData);
var options = {
showRowNumber: false,
width: '100%',
height: '100%'
};
var formatter = new google.visualization.NumberFormat(
{prefix: '£', fractionDigits: 2}
);
formatter.format(stats,1);
var table = new google.visualization.Table(document.getElementById('table_div'));
table.draw(stats, options);
}
Related
I am displaying pie-chart as a tootip inside a column chart using google charts.
In the pie-chart, I want to do legend: { position: 'labeled' }, but it is not displaying the bars of the Column chart, and so cannot display the Pie chart.
It is only displaying the gridlines.
My current code:
//Create Charts
function AggregateCharts(aggregateResult){
$('#hidden_div').show();
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback( function(){ drawTooltipCharts(aggregateResult) });
}
// Draw tool tip charts
function drawTooltipCharts(aggregateResult) {
//set bar chart data
primaryData=[];
if(aggregateResult){
aggregateResult.map(data=>{
if(data.Count>0 || data.High>0 || data.Medium>0)
{
//Set Options
var tooltipOptions = {
title: 'Data Title',
isStacked: true,
pieHole: 0.4,
sliceVisibilityThreshold:0,
colors: ['#c1c1c1','#0074AA','#1DB2F7','#F7941D' ],
legendTextStyle: { color: '#1DB2F7' ,fontSize: 12},
titleTextStyle: { color: '#1DB2F7', alignment: 'center',fontSize: 15},
chartArea: {width:510, height: 250} ,
legend: { position: 'labeled' },
pieStartAngle: 100,
pieSliceTextStyle: { fontSize:12 },
};
//Create chart View
var view = new google.visualization.DataTable();
view.addColumn('string', 'Criteria');
view.addColumn('number', 'Users');
var total=total;
var Count=data.Count;
var High=data.High;
var Medium=data.Medium;
//calculation part
var Countpercentage =((Count/total).toFixed(2))*100;
var Highpercentage =((High/total).toFixed(2))*100;
var Mediumpercentage =((Medium/total).toFixed(2))*100;
var NoCriteriaEndorsed= 100-(Math.floor(Countpercentage) + Math.floor(Highpercentage) + Math.floor(Mediumpercentage) );
var tooltipData=[];
tooltipData.push(["No Criteria Endorsed",NoCriteriaEndorsed]);
tooltipData.push(["50-69% Criteria Endorsed",Mediumpercentage]);
tooltipData.push(["70-99% Criteria Endorsed",Highpercentage]);
tooltipData.push(["100% Criteria Endorsed",Countpercentage]);
//Add total rows
view.addRows(tooltipData);
var hiddenDiv = document.getElementById('hidden_div');
var tooltipChart = new google.visualization.PieChart(hiddenDiv);
google.visualization.events.addListener(tooltipChart, 'ready', function() {
// Get the PNG of the chart and set is as the src of an img tag.
var tooltipImg = '<img src="' + tooltipChart.getImageURI() + '">';
// Add the new tooltip image to your data rows.
primaryData.push([data.Diagnosis,data.Count,tooltipImg,data.High,tooltipImg,data.Medium,tooltipImg]);
});
tooltipChart.draw(view, tooltipOptions);
}
})
//Create bar chart
drawBarChart(primaryData);
}
}
function drawBarChart(primaryData) {
var fromDate=$("#fromdate").val()?$("#fromdate").val():getMinDate(AggregateData)
var tooltipData = new google.visualization.DataTable();
tooltipData.addColumn('string', 'Event');
tooltipData.addColumn('number', '100% Criteria Endorsed');
// Add a new column for your tooltips.
tooltipData.addColumn({
type: 'string',
label: 'Tooltip Chart',
role: 'tooltip',
'p': {'html': true}
});
tooltipData.addColumn('number', '70-99% Criteria Endorsed');
// Add a new column for your tooltips.
tooltipData.addColumn({
type: 'string',
label: 'Tooltip Chart',
role: 'tooltip',
'p': {'html': true}
});
tooltipData.addColumn('number', '50-69% Criteria Endorsed');
// Add a new column for your tooltips.
tooltipData.addColumn({
type: 'string',
label: 'Tooltip Chart',
role: 'tooltip',
'p': {'html': true}
});
// Add your data (with the newly added tooltipImg).
tooltipData.addRows(primaryData);
var minwidth=tooltipData.getNumberOfRows() <25 ?(25*50) : tooltipData.getNumberOfRows() *50;
var primaryOptions = {
title: 'Results' ,
legend: 'none',
tooltip: {isHtml: true},
isStacked: true,
colors: ['#F7941D', '#1DB2F7', '#0074AA'],
legendTextStyle: { color: '#000000' , fontSize: 20 },
titleTextStyle: { color: '#000000', fontSize: 16, fontName: 'Calibri Light', bold: true },
width: minwidth,
bar: {groupWidth:15},
hAxis: {
textStyle: { color: "#1DB2F7" ,fontSize: 8, bold: true },
gridlines: { count: 4, color: "#1DB2F7" },
baselineColor: '#1DB2F7',
},
vAxis: {
title: 'Number of Respondents',
titleTextStyle: { color: '#000000', fontSize: 18, fontName: 'Calibri Light', bold: true},
textStyle: { color: "#1DB2F7", fontSize: 10, bold: true },
gridlines: { count: 4 , color: "#1DB2F7" },
baselineColor: '#1DB2F7' ,
},
};
var visibleDiv = document.getElementById('visible_div');
var primaryChart = new google.visualization.ColumnChart(visibleDiv);
primaryChart.draw(tooltipData, primaryOptions);
CustomOptions(primaryOptions);
var btndownloadchart = document.getElementById('downloadchart');
btndownloadchart.addEventListener('click', function () {
this.href= primaryChart.getImageURI();
}, false);
}
//Date format to display in chart legend
function dateFormat(requestDate){
var date = requestDate?new Date(requestDate):new Date();
var dateString =date.toLocaleString('en', { month: 'long' })+" "+ date.getDate() +", "+ date.getFullYear() ;
return dateString;
}
//get mindate value for aggregate if from date not selected initially..
function getMinDate(AggregateData){
if(AggregateData){
var minDate = Math.min.apply(null, AggregateData.map(function(o) { return new Date(o.CreatedDate); }))
return date = new Date(minDate)
}
return new Date()
}
function CustomOptions(primaryOptions) {
var $container = $('#visible_div');
var svg = $container.find('svg') ;
var svgWidth=$container.find('svg').width();
var $titleElemWidth = parseInt($container.find('svg').width()/8) ;
var svgMargin= ('-' +((svgWidth/15)>170?170:(svgWidth/15))+ 'px');
svg.css("margin-left", svgMargin);
var $titleElem = $container.find("text:contains(" + primaryOptions.vAxis.title +")");
$titleElem.attr('y',$titleElemWidth<320?320:$titleElemWidth);
//Hide tooltip chart
$('#hidden_div').hide();
}
]]>
When I do legend: { alignment: 'center' } in the 'tooltipOptions', the Column chart and the Pie-chart is displaying correctly.
But I want to do 'legend: { position: 'labeled' }', as the Pie-Chart slices is not displaying the percentage for small values.
Try passing the following to your options:
pieSliceTextStyle: {
color: 'white',
fontSize: '13',
top: 10,
left: 50,
position: 'start',
},
I am trying to present formatted data for the tooltip value of a Pie Chart. My data consists of a name and size (size is number of bytes).
The default tooltip does not let me use a custom formatter for the size value. If I use string I lose the Percentage value and Name of legend in the tooltip. Is there a way to do this?
I want to maintain the Legend Color, Name and Percentage, but have the value formatted to a more readable form
Current Wrong
Desired
var entries = [{name: 'Test1', size: 1234}, {name: 'Test2', size: 324563425}, {name: 'Test3', size: 321453452345}, {name: 'Test4', size: 789078}]
var drawChart = function(entries, elementId) {
var options = {
width: "100%",
height: 148,
fontSize: 8,
tooltip: { textStyle: { bold: true, color: '#000000', fontSize: 13 }, showColorCode: true, isHtml: true, ignoreBounds: true, text: 'both', trigger: 'selection' },
legend: { position: 'right', textStyle: { fontSize: 10 } },
chartArea: { left: 5, top: 10, right: 5, bottom: 10, height: "148", width: "100%" },
sliceVisibilityThreshold: 0,
pieSliceText: 'none',
//pieHole: 0.4,
};
var chart = new google.visualization.PieChart(document.getElementById(elementId));
var data = new google.visualization.DataTable();
data.addColumn('string', 'Name');
data.addColumn('number', 'Size');
data.addColumn({ type: 'string', role: 'tooltip' });
data.addRows(entries.length);
var i = 0;
$.each(entries, function () {
data.setCell(i, 0, this.name);
data.setCell(i, 1, this.size);
// How to make this display correctly?
// If it stays like this i lose percentage and legend name from tooltip
data.setCell(i, 2, formatBytes(this.size));
i++;
});
chart.draw(data, options);
}
var formatBytes = function (bytes, precision) {
if (isNaN(parseFloat(bytes)) || !isFinite(bytes)) return '-';
if (typeof precision === 'undefined') precision = 1;
var units = ['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'],
number = Math.floor(Math.log(bytes) / Math.log(1024));
return (bytes / Math.pow(1024, Math.floor(number))).toFixed(precision) + ' ' + units[number];
};
provide the formatted value in the last argument of setCell
the tooltip will show the formatted value by default
see following working snippet...
google.charts.load('current', {
callback: function () {
drawChart([{name: 'Test1', size: 1234}, {name: 'Test2', size: 324563425}, {name: 'Test3', size: 321453452345}, {name: 'Test4', size: 789078}], 'chart_div');
},
packages: ['corechart']
});
var drawChart = function(entries, elementId) {
var options = {
width: "100%",
height: 148,
fontSize: 8,
tooltip: { textStyle: { bold: true, color: '#000000', fontSize: 13 }, showColorCode: true, isHtml: true, ignoreBounds: true, text: 'both', trigger: 'selection' },
legend: { position: 'right', textStyle: { fontSize: 10 } },
chartArea: { left: 5, top: 10, right: 5, bottom: 10, height: "148", width: "100%" },
sliceVisibilityThreshold: 0,
pieSliceText: 'none',
//pieHole: 0.4,
};
var chart = new google.visualization.PieChart(document.getElementById(elementId));
var data = new google.visualization.DataTable();
data.addColumn('string', 'Name');
data.addColumn('number', 'Size');
data.addRows(entries.length);
var i = 0;
$.each(entries, function () {
data.setCell(i, 0, this.name);
data.setCell(i, 1, this.size, formatBytes(this.size, 1));
i++;
});
chart.draw(data, options);
}
var formatBytes = function(bytes, precision) {
if (isNaN(parseFloat(bytes)) || !isFinite(bytes)) return '-';
if (typeof precision === 'undefined') precision = 1;
var units = ['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'],
number = Math.floor(Math.log(bytes) / Math.log(1024));
return (bytes / Math.pow(1024, Math.floor(number))).toFixed(precision) + ' ' + units[number];
};
<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"></div>
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.
Using Google Charts API, I have made a line chart. Is there any way to be able to shade between two vertical lines? I know I most likely have to use a combo chart, but can anyone make a simple jsfiddle of an Area Chart that shades the middle of two vertical lines? Thank you!
following is a snippet that draws a bell curve based on the input range.
vertical lines are drawn to identify the Mean and Standard Deviation ranges.
shading is added to highlight the areas within 1, 2, & 3 Standard Deviations from the Mean.
google.charts.load('43', {
callback: function () {
document.getElementById('range-draw').addEventListener('click', loadBellCurve, false);
window.addEventListener('resize', loadBellCurve, false);
loadBellCurve();
},
packages:['controls', 'corechart']
});
function loadBellCurve() {
// build data sample
var rangeMin = parseInt(document.getElementById('range-min').value);
var rangeMax = parseInt(document.getElementById('range-max').value);
var step = 0.05;
var dataChart = new google.visualization.DataTable({
cols: [
{label: 'Sample', type: 'string'},
{label: 'Value', type: 'number'},
{label: 'Var', type: 'number'},
{label: 'X', type: 'number'},
{label: 'Y', type: 'number'}
]
});
for (var i = rangeMin; i <= rangeMax; i=i+step) {
dataChart.addRow([i.toString(), i, null, null, null]);
}
// find sample mean
var dataMean = google.visualization.data.group(
dataChart,
[{column: 0, type: 'string', modifier: function () {return '';}}],
[{column: 1, type: 'number', aggregation: google.visualization.data.avg}]
);
var sampleMean = dataMean.getValue(0, 1);
// find sample standard deviation
for (var i = 0; i < dataChart.getNumberOfRows(); i++) {
dataChart.setValue(i, 2, Math.pow(dataChart.getValue(i, 1) - sampleMean, 2));
}
var dataVar = google.visualization.data.group(
dataChart,
[{column: 0, type: 'string', modifier: function () {return '';}}],
[{column: 2, type: 'number', aggregation: google.visualization.data.avg}]
);
var sampleStdDev = Math.sqrt(dataVar.getValue(0, 1));
// set standard deviation ranges 1-3
var sampleRange = [];
sampleRange.push([
sampleMean - sampleStdDev,
sampleMean + sampleStdDev
]);
sampleRange.push([
sampleMean - (sampleStdDev * 2),
sampleMean + (sampleStdDev * 2)
]);
sampleRange.push([
sampleMean - (sampleStdDev * 3),
sampleMean + (sampleStdDev * 3)
]);
// set X/Y coordinates
for (var i = 0; i < dataChart.getNumberOfRows(); i++) {
dataChart.setValue(i, 3, dataChart.getValue(i, 1) * sampleStdDev + sampleMean);
dataChart.setValue(i, 4, getNormalDistribution(dataChart.getValue(i, 1) * sampleStdDev + sampleMean, sampleMean, sampleStdDev));
}
// fill-in standard deviation areas
var stdDevCols = {};
stdDevCols['1_SD'] = dataChart.addColumn({label: '1 Std Dev', type: 'number'});
stdDevCols['2_SD'] = dataChart.addColumn({label: '2 Std Dev', type: 'number'});
stdDevCols['3_SD'] = dataChart.addColumn({label: '3 Std Dev', type: 'number'});
for (var i = Math.floor(sampleRange[2][0]); i <= Math.ceil(sampleRange[2][1]); i=i+0.05) {
var rowIndex = dataChart.addRow();
dataChart.setValue(rowIndex, 3, i);
if (((i) >= sampleRange[0][0]) && ((i) < sampleRange[0][1])) {
dataChart.setValue(rowIndex, stdDevCols['1_SD'], getNormalDistribution(i, sampleMean, sampleStdDev));
} else if (((i) >= sampleRange[1][0]) && ((i) < sampleRange[1][1])) {
dataChart.setValue(rowIndex, stdDevCols['2_SD'], getNormalDistribution(i, sampleMean, sampleStdDev));
} else {
dataChart.setValue(rowIndex, stdDevCols['3_SD'], getNormalDistribution(i, sampleMean, sampleStdDev));
}
}
// add vertical lines for mean and standard deviations
addVerticalLine('MEAN', sampleMean);
addVerticalLine('< 1 SD', sampleRange[0][0]);
addVerticalLine('> 1 SD', sampleRange[0][1]);
addVerticalLine('< 2 SD', sampleRange[1][0]);
addVerticalLine('> 2 SD', sampleRange[1][1]);
// series options
var markersArea = {
enableInteractivity: false,
pointsVisible: false,
tooltip: false,
type: 'area'
};
var markersLine = {
enableInteractivity: false,
lineWidth: 3,
pointsVisible: false,
tooltip: false,
type: 'line',
visibleInLegend: false
};
// combo chart
var chartCombo = new google.visualization.ChartWrapper({
chartType: 'ComboChart',
containerId: 'chart-combo',
options: {
animation: {
duration: 1000,
easing: 'linear',
startup: true
},
colors: ['#1565C0', '#43A047', '#FFB300', '#E53935', '#43A047', '#FFB300', '#FFB300', '#E53935', '#E53935'],
explorer: { actions: ['dragToZoom', 'rightClickToReset'] },
hAxis: {
format: '#,##0'
},
height: 340,
legend: {
textStyle: {
color: '#676767',
fontSize: 10
}
},
series: {
0: {
pointShape: {
type: 'star',
sides: 4,
dent: 0.3
},
pointSize: 12,
pointsVisible: true,
type: 'scatter'
},
1: markersArea,
2: markersArea,
3: markersArea,
4: markersLine,
5: markersLine,
6: markersLine,
7: markersLine,
8: markersLine
},
seriesType: 'scatter',
theme: 'maximized',
title: 'Normal Distribution',
titleTextStyle: {
color: '#676767',
bold: false,
fontSize: 10
},
tooltip: {
isHtml: true
},
vAxis: {
format: '#,##0.0000'
},
width: '100%'
}
});
// range filter
var controlRangeFilter = new google.visualization.ControlWrapper({
controlType: 'ChartRangeFilter',
containerId: 'chart-control-range',
options: {
filterColumnIndex: 0,
ui: {
chartType: 'AreaChart',
chartOptions: {
annotations: {
highContrast: false,
stem: {
color: 'transparent',
length: 0
},
textStyle: {
color: 'transparent'
}
},
chartArea: {
left: 0,
width: '100%'
},
colors: ['#1565C0', '#43A047', '#FFB300', '#E53935', '#43A047', '#FFB300', '#FFB300', '#E53935', '#E53935'],
height: 72,
width: '100%'
}
}
}
});
// chart data view
var viewChart = new google.visualization.DataView(dataChart);
viewChart.setColumns([3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]);
// draw dashboard
var dashboard = new google.visualization.Dashboard(document.getElementById('dashboard'));
dashboard.bind(controlRangeFilter, chartCombo);
dashboard.draw(viewChart);
function getNormalDistribution(x, Mean, StdDev) {
return Math.exp(-((x - Mean) * (x - Mean)) / (2 * StdDev * StdDev)) / (Math.sqrt(2 * Math.PI) * StdDev);
}
function addVerticalLine(colLabel, xVal) {
var yCol = dataChart.addColumn({label: colLabel, type: 'number'});
var annCol = dataChart.addColumn({role: 'annotation', type: 'string'});
var rowIndex = dataChart.addRow();
dataChart.setValue(rowIndex, 3, xVal);
dataChart.setValue(rowIndex, yCol, getNormalDistribution(xVal, sampleMean, sampleStdDev));
dataChart.setValue(rowIndex, annCol, xVal.toFixed(2) + ' %');
rowIndex = dataChart.addRow();
dataChart.setValue(rowIndex, 3, xVal);
dataChart.setValue(rowIndex, yCol, 0);
}
}
input {
font-family: Arial;
font-size: 10px;
}
input[type=number] {
text-align: right;
width: 48px;
}
label {
font-family: Arial;
font-size: 10px;
font-weight: bold;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="dashboard">
<div>
<label for="range-min">Min:</label> <input type="number" id="range-min" value="-4" />
<label for="range-max">Max:</label> <input type="number" id="range-max" value="4" />
<input type="button" id="range-draw" value="Draw Chart" />
</div>
<div id="chart-combo"></div>
<div id="chart-control-range"></div>
<div id="chart-table"></div>
</div>
I found the following code online and would like to adapt it to my existing code.
Here's the code to show/hide data series on click I found:
http://jsfiddle.net/asgallant/6gz2Q/
Here's my Adaptation so far:
function drawChart() {
var data = new google.visualization.arrayToDataTable([
['Draw', '1997', '1998'],
['1', 1236777, 1408007],
['2', 834427, 572882],
['3', 2164890, 1614181],
['4', 1893574, 3897171],
['5', 2851881, 673906],
['6', 359504, 630853]
]);
// Instantiate and draw our chart, passing in some options.
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
// create columns array
var columns = [];
// display these data series by default
var defaultSeries = [1];
var series = {};
for (var i = 0; i < data.getNumberOfColumns(); i++) {
if (i == 0 || defaultSeries.indexOf(i) > -1) {
// if the column is the domain column or in the default list, display the series
columns.push(i);
}
else {
// otherwise, hide it
columns[i] = {
label: data.getColumnLabel(i),
type: data.getColumnType(i),
calc: function () {
return null;
}
};
}
if (i > 0) {
// set the default series option
series[i - 1] = {};
if (defaultSeries.indexOf(i) == -1) {
// backup the default color (if set)
if (typeof(series[i - 1].color) !== 'undefined') {
series[i - 1].backupColor = series[i - 1].color;
}
series[i - 1].color = '#CCCCCC';
}
}
}
// Options customize what goes inside our chart.
var options = {
fontName: 'verdana',
fontSize: 12,
// Curve the series line.
curveType: "function",
title: 'Title of Chart',
// disables tooltip on hover data points
enableInteractivity: true,
// Enable/Disable tooltip. selection or none.
tooltip: { trigger: 'none' },
// Select multiple Data points.
selectionMode: 'multiple',
// Customize vAxis ---------------------------------------------------------
vAxis: {
gridlines: {color: 'black', count: 5},
title: 'Title of vAxis',
// Affects only the Title. eg. Not title.
titleTextStyle: {fontName: 'verdana', fontSize: 10, color: 'black', bold: false, italic: false},
// Range of data for vAxis eg. min: 0, max:9
viewWindow: {min: 0, max: 5006386},
// Affects only the Range. eg. Not title.
textStyle: {fontName: 'verdana', fontSize: 12, color: 'black', bold: false, italic: false}
},
// Customize hAxis ---------------------------------------------------------
hAxis: {
title: 'Title of hAxis',
// Affects only the Title. eg. Not title.
titleTextStyle: {fontName: 'verdana', fontSize: 10, color: 'black', bold: false, italic: false},
// Affects only the Range. eg. Not title.
textStyle: {fontName: 'verdana', fontSize: 10, color: 'black', bold: false, italic: false}
},
// Customize Series ---------------------------------------------------------
series: {
0: {lineWidth: 1, pointSize: 4},
1: {lineWidth: 1, pointSize: 4},
2: {lineWidth: 1, pointSize: 4}
},
// Customize Annotations ---------------------------------------------------------
annotations: {
textStyle: {fontName: 'verdana', fontSize: 10, color: 'black', bold: false, italic: false, auraColor: 'none'}
},
// Custome Legends ---------------------------------------------------------
legend: {
// Position top, right, bottom, left.
position: 'top',
// Align at the star, center or end.
alignment: 'start',
// Affects only the Range. eg. Not title.
textStyle: {fontName: 'verdana', fontSize: 10, color: 'black', bold: false, italic: false}
}
}; // End Options
function showHideSeries () {
var sel = chart.getSelection();
// if selection length is 0, we deselected an element
if (sel.length > 0) {
// if row is undefined, we clicked on the legend
if (sel[0].row == null) {
var col = sel[0].column;
if (columns[col] == col) {
// hide the data series
columns[col] = {
label: data.getColumnLabel(col),
type: data.getColumnType(col),
calc: function () {
return null;
}
};
// grey out the legend entry
series[col - 1].color = '#CCCCCC';
}
else {
// show the data series
columns[col] = col;
series[col - 1].color = null;
}
var view = new google.visualization.DataView(data);
view.setColumns(columns);
chart.draw(view, options);
}
}
}
google.visualization.events.addListener(chart, 'select', showHideSeries);
// create a view with the default columns
var view = new google.visualization.DataView(data);
view.setColumns(columns);
chart.draw(view, options);
}
google.load('visualization', '1', {packages: ['corechart']});
google.setOnLoadCallback(drawChart);
...And here is what I really wanted to figure how to incorporate into this code. I can't seem to figure it out. It's driving me nuts!
// Declare our Columns and set types, roles, etc.
view.setColumns([
0,
1, { calc: "stringify", sourceColumn: 1, type: "string", role: "annotation" },
2, { calc: "stringify", sourceColumn: 2, type: "string", role: "annotation" },
3, { calc: "stringify", sourceColumn: 3, type: "string", role: "annotation" }
]);
Try replacing this section:
if (i == 0 || defaultSeries.indexOf(i) > -1) {
// if the column is the domain column or in the default list, display the series
columns.push(i);
}
with this:
if (i == 0 || defaultSeries.indexOf(i) > -1) {
// if the column is the domain column or in the default list, display the series
columns.push(i);
if (i > 0) {
columns.push({
calc: "stringify",
sourceColumn: i,
type: "string",
role: "annotation"
});
}
}
Here is asgallant solution which worked as desired.
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('number', 'x');
data.addColumn('number', 'y1');
data.addColumn('number', 'y2');
data.addColumn('number', 'y3');
// add random data
var y1 = 50, y2 = 50, y3 = 50;
for (var i = 0; i < 100; i++) {
y1 += Math.floor(Math.random() * 5) * Math.pow(-1, Math.floor(Math.random() * 2));
y2 += Math.floor(Math.random() * 5) * Math.pow(-1, Math.floor(Math.random() * 2));
y3 += Math.floor(Math.random() * 5) * Math.pow(-1, Math.floor(Math.random() * 2));
data.addRow([i, y1, y2, y3]);
}
// Instantiate and draw our chart, passing in some options.
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
// create columns array
var columns = [];
// display these data series by default
var defaultSeries = [1, 3];
var series = {};
for (var i = 0; i < data.getNumberOfColumns(); i++) {
if (i == 0 || defaultSeries.indexOf(i) > -1) {
// if the column is the domain column or in the default list, display the series
columns.push(i);
}
else {
// otherwise, hide it
columns.push({
label: data.getColumnLabel(i),
type: data.getColumnType(i),
sourceColumn: i,
calc: function () {
return null;
}
});
}
if (i > 0) {
columns.push({
calc: 'stringify',
sourceColumn: i,
type: 'string',
role: 'annotation'
});
// set the default series option
series[i - 1] = {};
if (defaultSeries.indexOf(i) == -1) {
// backup the default color (if set)
if (typeof(series[i - 1].color) !== 'undefined') {
series[i - 1].backupColor = series[i - 1].color;
}
series[i - 1].color = '#CCCCCC';
}
}
}
var options = {
width: 600,
height: 400,
series: series
}
function showHideSeries () {
var sel = chart.getSelection();
// if selection length is 0, we deselected an element
if (sel.length > 0) {
// if row is undefined, we clicked on the legend
if (sel[0].row == null) {
var col = sel[0].column;
if (typeof(columns[col]) == 'number') {
var src = columns[col];
// hide the data series
columns[col] = {
label: data.getColumnLabel(src),
type: data.getColumnType(src),
sourceColumn: src,
calc: function () {
return null;
}
};
// grey out the legend entry
series[src - 1].color = '#CCCCCC';
}
else {
var src = columns[col].sourceColumn;
// show the data series
columns[col] = src;
series[src - 1].color = null;
}
var view = new google.visualization.DataView(data);
view.setColumns(columns);
chart.draw(view, options);
}
}
}
google.visualization.events.addListener(chart, 'select', showHideSeries);
// create a view with the default columns
var view = new google.visualization.DataView(data);
view.setColumns(columns);
chart.draw(view, options);
}
google.load('visualization', '1', {packages: ['corechart']});
google.setOnLoadCallback(drawChart);