Google Charts Loading Error - javascript

I recently ran into a strange issue with Google Charts and loading Google web fonts asynchronously. I was using loader.js and loading the most current version of the charts via google.charts.load('current', { 'packages': ['corechart'] });. Specifically, I was trying to draw two line charts on the same page and at the same time and set their attributes as below:
var options = {
...,
...,
titleTextStyle: {
...,
fontName: 'Lato'
}
}
I then set some additional attributes and defined the data and proceeded to draw the charts like normal. The first chart would be drawn but the second one would never materialize. Nothing was working so I backtracked through the code deleting chunks until I found that deleting fontName: 'Lato' is what resolved the issue. I was asynchronously loading my web fonts with this script:
<script type="text/javascript">
WebFontConfig = {
google: {
families: ['Lato:300, 400, 900']
}
};
(function() {
var wf = document.createElement('script');
wf.src = ('https:' == document.location.protocol ? 'https' : 'http') +
'://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js';
wf.type = 'text/javascript';
wf.async = 'true';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(wf, s);
})();
</script>
Loading my fonts while using this script, I was able to draw one chart, but when I attempted to draw two charts, I was never able to complete it. Every time, the first chart would be populated and the second chart never loaded. I had defined Lato as my primary font, but I did have backups defined as well. This didn't seem to help. My final solution was to load the web font the standard way with:
<link href="https://fonts.googleapis.com/css?family=Lato:300,400,900" rel="stylesheet">
This resolved the issue but I don't like the idea of not being able to load the font asynchronously. Has anyone run into this awkward issue before or am I just missing something really obvious?
*****EDIT*****
Full chart code attached:
google.charts.load('current', { 'packages': ['corechart'] });
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var fontSizeGraph = window.getComputedStyle(document.getElementById('graph_font_size_source'), null).getPropertyValue('font-size');
fontSizeGraph = parseFloat(fontSizeGraph);
var interactivityPermissive = true;
if ($(window).width() < 768) {
interactivityPermissive = false;
} else {
interactivityPermissive = true;
};
var data = google.visualization.arrayToDataTable([
['Accepted Variance', 'High/Low', 'HiHi/LoLo'],
['0', 0, 0],
['1', 38, 45],
['2', 60, 68],
['3', 67, 75],
['4', 76, 88],
['5', 80, 93],
['6', 90, 102],
['7', 98, 108],
['8', 100, 111],
['9', 105, 117],
['10', 111, 123],
['11', 114, 126],
['12', 118, 130],
['13', 120, 134],
['14', 124, 140],
['15', 127, 142],
['16', 130, 145],
['16', 131, 146],
['18', 134, 148],
['19', 137, 153],
['20', 138, 155]
]);
var options = {
enableInteractivity: interactivityPermissive,
title: 'Delay Tags Preserved',
titlePosition: 'out',
titleTextStyle: {
color: '#3D414D',
fontName: "Lato",
fontSize: fontSizeGraph,
bold: true
},
chartArea: {
//top: '7%',
width: '90%',
height: '70%'
},
//chartArea: {'top': 0, 'left': 0},
colors: ['#3D414D', '#4EDEC2'],
curveType: 'function',
fontName: "Lato",
legend: {
position: 'bottom',
textStyle: {
color: '#3D414D',
fontName: "Lato"
}
},
vAxis: {
title: 'Alarm Count Reduction',
viewWindow: {
max: 180,
min: -5,
format: '#',
},
textStyle: {
color: '#3D414D',
fontName: "Lato"
},
showTextEvery: 20,
textPosition: 'in',
gridlines: {
color: '#EFECE7',
count: 5
}
},
hAxis: {
title: 'Accepted Variance (%)',
titleTextStyle: {
color: '#3D414D',
fontName: "Lato"
},
viewWindow: {
max: 24,
min: 0,
},
textStyle: {
color: '#3D414D',
fontName: "Lato"
},
format: '#',
showTextEvery: 2,
viewWindowMode: 'maximized'
},
lineWidth: 2,
tooltip: {
textStyle: {
color: '#3D414D',
fontName: "Lato",
fontSize: (fontSizeGraph * 0.5)
},
//isHtml: true,
ignoreBounds: true
},
animation: {
duration: 1000,
startup: true,
easing: 'out'
}
};
var chart1 = new google.visualization.LineChart(document.getElementById('results_graph_1'));
chart1.draw(data, options);
var data2 = google.visualization.arrayToDataTable([
['Accepted Variance', 'High/Low', 'HiHi/LoLo'],
['0', 0, 0],
['1', 81, 88],
['2', 135, 142],
['3', 180, 189],
['4', 223, 237],
['5', 255, 270],
['6', 303, 317],
['7', 343, 354],
['8', 362, 373],
['9', 380, 392],
['10', 406, 419],
['11', 420, 432],
['12', 443, 456],
['13', 459, 473],
['14', 476, 493],
['15', 493, 510],
['16', 513, 530],
['16', 520, 537],
['18', 533, 548],
['19', 546, 563],
['20', 555, 572]
]);
var options = {
enableInteractivity: interactivityPermissive,
title: 'Delay Tags Modified',
titlePosition: 'out',
titleTextStyle: {
color: '#3D414D',
fontName: "Lato",
fontSize: fontSizeGraph,
bold: true
},
chartArea: {
//top: '7%',
width: '90%',
height: '70%'
},
//chartArea: {'top': 0, 'left': 0},
colors: ['#3D414D', '#4EDEC2'],
curveType: 'function',
fontName: "Lato",
legend: {
position: 'bottom',
textStyle: {
color: '#3D414D',
fontName: "Lato"
}
},
vAxis: {
title: 'Alarm Count Reduction',
viewWindow: {
max: 600,
min: -5,
format: '#',
},
textStyle: {
color: '#3D414D',
fontName: "Lato"
},
showTextEvery: 20,
textPosition: 'in',
gridlines: {
color: '#EFECE7',
count: 5
}
},
hAxis: {
title: 'Accepted Variance (%)',
titleTextStyle: {
color: '#3D414D',
fontName: "Lato"
},
viewWindow: {
max: 24,
min: 0,
},
textStyle: {
color: '#3D414D',
fontName: "Lato"
},
format: '#',
showTextEvery: 2,
viewWindowMode: 'maximized'
},
lineWidth: 2,
tooltip: {
textStyle: {
color: '#3D414D',
fontName: "Lato",
fontSize: (fontSizeGraph * 0.5)
},
//isHtml: true,
ignoreBounds: true
},
animation: {
duration: 1000,
startup: true,
easing: 'out'
}
};
var chart2 = new google.visualization.LineChart(document.getElementById('results_graph_2'));
chart2.draw(data2, options);
}

I ran into the same issue, having 4 charts on one page, together with async webfont loader. Some charts randomly did not display.
It seems that, if there is a font specified on chart options, on draw, code checks if there is window.WebFont object, if yes, use it to load the font(s). Even if this font(s) is already loaded by webfont loader. Each chart draw call, keeps requesting the same fonts, and they keep getting appended as <link>s in <head>. This seems buggy behavior.
The way i hack fixed it, is removing webfont object before calling first chart draw.
google.charts.load('current', { 'packages': ['corechart'], 'callback': {
window.WebFont = null;
var chart1 = someChart();
chart1.draw();
}});

Related

How to add ticks to a Google line chart in JavaScript?

I'm trying to add tick marks to my Google line chart, but when I input ticks: [0, 0.5, 1.0, 1.5, 2.0] on my vertical axis and ticks: [400, 450, 500, 550, 600, 650] on my horizontal axis, they keep appearing more as gridlines than actual tick marks.
For the Google Sheets line chart I created, MAJOR and MINOR ticks are checkboxed. [Major Count: Auto, Minor Count: 1]
For the MAJOR ticks:
Positions on the HORIZONTAL AXIS would be at [400, 450, 500, 550, 600, 650]
Positions on the VERTICAL AXIS would be at [0, 0.5, 1.0, 1.5, 2.0]
Ticks Position: Cross (so it would cross the baseline, rather than being inside or outside of it)
Ticks Length: 12px
Line Thickness: 1px
Line Color: Black
For the MINOR ticks:
Positions on the HORIZONTAL AXIS would be at [425, 475, 525, 575, 625]
Positions on the VERTICAL AXIS would be at [0.25, 0.75, 1.25, 1.75]
Ticks Position: Cross
Ticks Length: 6px
Line Thickness: 1px
Line Color: Black
Here is my code:
google.charts.load('current', {packages: ['corechart', 'line']});
google.charts.setOnLoadCallback(drawLineColors);
function drawLineColors() {
var data = new google.visualization.DataTable();
data.addColumn('number', 'X');
data.addColumn('number', 'Absorbance');
data.addRows([
[380, 0.12],
[390, 0.098],
[400, 0.088],
[410, 0.12],
[420, 0.292],
[430, 0.302],
[440, 0.444],
[450, 0.636],
[460, 0.774],
[470, 0.998],
[480, 1.428],
[490, 1.862],
[500, 1.954],
[510, 1.45],
[520, 0.774],
[530, 0.364],
[540, 0.16],
[550, 0.134],
[560, 0.074],
[570, 0.06],
[580, 0.076],
[590, 0.046],
[600, 0.0004],
[610, 0.008],
[620, 0.006],
[630, 0.0006],
[640, 0.016],
[650, 0.002],
[660, 0.056],
]);
var options = {
title: 'Analytical Spectrum',
titleTextStyle: {
fontName: 'Courier Prime',
fontSize: 30,
bold: true,
color: 'black' },
height: 500,
width: 900,
hAxis:
{
title: 'Wavelength (nm)',
titleTextStyle: {
fontName: 'Courier Prime',
fontSize: 18,
bold: true,
italic: false },
textStyle: {
fontName: 'Courier Prime',
fontSize: 16,
bold: true,
color: 'black'
},
gridlines: {count: '0'},
minTextSpacing: '1',
baseline: '380',
ticks: [400, 450, 500, 550, 600, 650]
},
vAxis:
{
title: 'Absorbance (AU)',
titleTextStyle: {
fontName: 'Courier Prime',
fontSize: 18,
bold: true,
italic: false },
textStyle: {
fontName: 'Courier Prime',
fontSize: 16,
bold: true,
color: 'black'
},
gridlines: {count: '0'},
baseline: '0',
ticks: [0, 0.5, 1.0, 1.5, 2.0],
},
legend: 'none',
lineWidth: 5,
colors: ['#0000ff']
};
var chart = new google.visualization.LineChart(document.getElementById('AnalyticalSpectrum'));
chart.draw(data, options);
}
I've been using this Google Line Chart overview under "Configuration Options" to check how I can change my tick marks, but I'm not yet seeing anything that explains why the tick marks are showing up as gridlines, or how to change that: [https://developers.google.com/chart/interactive/docs/gallery/linechart].

Highcharts Line Chart populating without data lines

This chart worked for years with no issue and a few days ago I noticed the lines are not populating. Cannot find a fix here or on highcharts forums. Typically, when something is wrong with the javascript, nothing populates but in this case, everything populates but the lines and associated data.
Thank you in advance!
JSFiddle: https://jsfiddle.net/jstark/zf3ma5so/2/
$(function () {
$('#container101').highcharts({
chart: {
type: 'line',
spacingBottom: 5,
spacingTop: 15,
spacingLeft: 35,
spacingRight: 35
},
title: {
text: 'Graduation Diploma Types Awarded by Year',
style: {"font-family": "'Open Sans', sans-serif", "color": "#373737","fontSize": "24px", "fontWeight":"bold"}
},
xAxis: {
categories: ['2010', '2011', '2012', '2013', '2014', '2015', '2016', '2017', '2018', '2019', '2020', '2021'],
crosshair: true
},
yAxis: {
min: '40',
max: '60',
title: {
text: 'Percentage Awarded',
style: {"font-family": "'Open Sans', sans-serif", "color": "#373737","fontSize": "16px", "fontWeight":"bold"},
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
valueSuffix: '%',
borderColor: 'gray',
borderRadius: 10,
shadow: false
},
credits: {
enabled: false
},
legend: {
layout: 'horizontal',
align: 'center',
verticalAlign: 'bottom',
borderWidth: 0,
itemMarginBottom: 20,
itemStyle: {"font-family": "'Open Sans', sans-serif", "color": "#373737","fontSize": "16px", "fontWeight":"bold"}
},
series: [{
name: 'Advanced/CCR/Honors Diploma',
color: '#01a2d7',
data: [46, 45, 48, 49, 50, 50, 52, 47, 49, 49, 50, 49],
marker: {
fillColor: '#FFFFFF',
lineWidth: 2,
lineColor: '#01a2d7'
}
}, {
name: 'Standard Diploma',
color: '#01519c',
data: [51, 52, 51, 50, 50, 50, 48, 53, 51, 51, 50, 51],
marker: {
fillColor: '#FFFFFF',
lineWidth: 2,
lineColor: '#01519c'
}
}]
});
});
The min/max properties on yAxis should be numbers instead of strings.
min: 40,
max: 60,
instead of
min: '40',
max: '60',

How to scale stacked google chart for mobile?

I have a stacked chart which is responsive for most screen sizes based on the solution for responsiveness provided here: Google Charts - Responsive Issue - Dynamically Resize
The problem is that despite none of the data values being higher than 5000, when viewed on mobile the scale goes up to 10,000 and the entire chart is rendered illegible. How can i scale the chart correctly for mobile?
JSFIDDLE https://jsfiddle.net/385rzhsg
HTML
<div id="chart"><div id="soc_chart"></div></div>
CSS
#chart {
border: 1px solid #AAA;
min-height: 1000px;
}
JAVASCRIPT
google.charts.load('current', {packages: ['corechart', 'bar']});
google.charts.setOnLoadCallback(drawStacked);
function drawStacked() {
var data = google.visualization.arrayToDataTable([
['SOC', 'GEEKBENCH 5 SINGLE', 'GEEKBENCH 5 MULTI'],
['SNAPDRAGON 870', 914, 3161],
['MEDIATEK DIMENSITY 900 (MT6877)', 731, 2203],
['SNAPDRAGON 845', 504, 2028],
['MEDIATEK DIMENSITY 700 (MT6833V)', 544, 1695],
['MEDIATEK G95', 501, 1599],
['UNISOC TIGER T618', 392, 1441],
['UNISOC TIGER T310', 360, 708],
['MEDIATEK MT8176', 314, 644],
['MEDIATEK HELIO P60 (MT6771)', 288, 1272],
['ROCKCHIP RK3399', 269, 615],
['BROADCOM BCM2711', 234, 672],
['ROCKCHIP RK3326', 86, 272],
['MEDIATEK MT6580A', 69, 227],
['ROCKCHIP RK3288', 10, 20]
]);
var options = {
chartArea: {'width': 'auto', 'height': '90%'},
legend:
{'position':'top',
textStyle: {color: 'black', fontName: 'Lato', fontSize: 14, bold: true, italic: false}},
height: 1000,
isStacked: true,
hAxis:
{title: 'GEEKBENCH 5 SCORE',
textStyle: {color: 'black', fontName: 'Lato', fontSize: 12, bold: true, italic: false},
titleTextStyle: {color: '#940000', fontName: 'Lato', bold: true, italic: false}},
series: {
0:{color:'#F75200'},
1:{color:'#940000'}},
vAxis:
{title: 'SOC NAME',
textStyle: {color: 'black', fontName: 'Lato', fontSize: 12, bold: true, italic: false},
titleTextStyle: {color: '#940000', fontName: 'Lato', bold: true, italic: false}}
};
var chart = new google.visualization.BarChart(document.getElementById('soc_chart'));
chart.draw(data, google.charts.Bar.convertOptions(options));
window.addEventListener('resize', drawStacked, false);
}
for starters, let's take a look at the options for the chart.
var chart = new google.visualization.BarChart(document.getElementById('soc_chart'));
chart.draw(data, google.charts.Bar.convertOptions(options));
the convertOptions method is used to convert options for classic charts to material charts.
but the chart being drawn is a classic chart, so there is no need to use convertOptions.
classic chart: google.visualization.BarChart
material chart: google.charts.Bar
try removing the method...
var chart = new google.visualization.BarChart(document.getElementById('soc_chart'));
chart.draw(data, options);
also, the 'bar' package is for loading material charts,
so it isn't needed either.
google.charts.load('current', {packages: ['corechart', 'bar']});
change to...
google.charts.load('current', {packages: ['corechart']});
if after these changes, the axis continues to extend beyond the max value,
you can manually set the axis range.
we can find the max value of the row stacks, then round up to the nearest 1000.
var maxStack = null;
for (var i = 0; i < data.getNumberOfRows(); i++) {
var rowStack = data.getValue(i, 1) + data.getValue(i, 2);
maxStack = maxStack || rowStack;
maxStack = Math.max(maxStack, rowStack);
}
var maxRound = Math.ceil(maxStack / 1000) * 1000;
then use that value to set the max value of the axis.
hAxis: {
title: 'GEEKBENCH 5 SCORE',
textStyle: {color: 'black', fontName: 'Lato', fontSize: 12, bold: true, italic: false},
titleTextStyle: {color: '#940000', fontName: 'Lato', bold: true, italic: false},
viewWindow: {
min: 0,
max: maxRound // set max value of axis
}
see following working snippet...
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
var data = google.visualization.arrayToDataTable([
['SOC', 'GEEKBENCH 5 SINGLE', 'GEEKBENCH 5 MULTI'],
['SNAPDRAGON 870', 914, 3161],
['MEDIATEK DIMENSITY 900 (MT6877)', 731, 2203],
['SNAPDRAGON 845', 504, 2028],
['MEDIATEK DIMENSITY 700 (MT6833V)', 544, 1695],
['MEDIATEK G95', 501, 1599],
['UNISOC TIGER T618', 392, 1441],
['UNISOC TIGER T310', 360, 708],
['MEDIATEK MT8176', 314, 644],
['MEDIATEK HELIO P60 (MT6771)', 288, 1272],
['ROCKCHIP RK3399', 269, 615],
['BROADCOM BCM2711', 234, 672],
['ROCKCHIP RK3326', 86, 272],
['MEDIATEK MT6580A', 69, 227],
['ROCKCHIP RK3288', 10, 20]
]);
var maxStack = null;
for (var i = 0; i < data.getNumberOfRows(); i++) {
var rowStack = data.getValue(i, 1) + data.getValue(i, 2);
maxStack = maxStack || rowStack;
maxStack = Math.max(maxStack, rowStack);
}
var maxRound = Math.ceil(maxStack / 1000) * 1000;
var options = {
chartArea: {'width': 'auto', 'height': '90%'},
legend: {
position: 'top',
textStyle: {color: 'black', fontName: 'Lato', fontSize: 14, bold: true, italic: false}
},
height: 1000,
isStacked: true,
hAxis: {
title: 'GEEKBENCH 5 SCORE',
textStyle: {color: 'black', fontName: 'Lato', fontSize: 12, bold: true, italic: false},
titleTextStyle: {color: '#940000', fontName: 'Lato', bold: true, italic: false},
viewWindow: {
min: 0,
max: maxRound
}
},
series: {
0:{color:'#F75200'},
1:{color:'#940000'}
},
vAxis: {
title: 'SOC NAME',
textStyle: {color: 'black', fontName: 'Lato', fontSize: 12, bold: true, italic: false},
titleTextStyle: {color: '#940000', fontName: 'Lato', bold: true, italic: false}
}
};
var chart = new google.visualization.BarChart(document.getElementById('soc_chart'));
chart.draw(data, options);
window.addEventListener('resize', function () {
chart.draw(data, options);
});
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="soc_chart"></div>

Striped fill for google line chart

I'm trying to add a striped fill to my line chart, there seem to be an official solution for this https://developers.google.com/chart/image/docs/gallery/line_charts and they talk about chf.
However, I have no idea how to implement this, I've googled for it, and searched stackoverflow for a few hours now and can't seem to find a solution.
I need a striped fill like the even/odd css function.
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(Process1);
function Process1() {
var data = google.visualization.arrayToDataTable([
['value1', 'value2', 'value3', 'value4'],
['10', 400, 380, 48],
['20', 400, 340, 260],
['30', 400, 410, 310],
['40', 400, 390, 380],
['50', 400, 345, 345],
['60', 400, 385, 370],
['70', 400, 430, 410],
['80', 400, null, null],
['90', 400, null, null],
['100', 400, null, null],
['110', 400, null, null],
['120', 400, null, null]
]);
var options = {
theme: 'material',
lineWidth: 3,
colors: ['#3D3D3D', '#4CDD37', '#2076F2'],
title: 'Orderinformation plan 1',
titleTextStyle: {fontName:'Lato', fontSize:'20'},
legend: {
position: 'right',
textStyle: {
fontName:'Lato', fontSize:'12'
},
},
hAxis: {
title: 'Time in minutes',
titleTextStyle: {fontName:'Lato', fontSize:'16', italic:false},
textStyle: {
fontName:'Lato', fontSize:'16'
},
},
vAxis: {
title: 'Temperature in celsius',
titleTextStyle: {fontName:'Lato', fontSize:'16', italic:false},
textStyle: {
fontName:'Lato', fontSize:'16'
},
viewWindowMode: 'explicit',
ticks: [25,50,100,150,200,250,300,350,400,460],
viewWindow: {
max:460,
min:25
},
gridlines: {
count: 10
}
}
};
var chart = new google.visualization.LineChart(document.getElementById('curve_chart_1'));
chart.draw(data, options);
}

Always display value in highcharts column chart

I am not exactly new to highcharts, but I am not exactly a "power user" either.
I have these charts on a security report that will almost invariably always have at least 1 column that has no value displayed because the value is too low, compared to the others.
The design requirement is that these do not have tool tips, just the data being displayed.
Maybe I am being thick, but when I think i see the answer I try it and it doesn't work... for example I have tried setting the "min" attribute on the x axis etc, but no luck. Is this doable? I assume if it is, I am putting the attribute in the wrong place.
Here is an example, look at column one code sample is in there... but it is below as well
JSFiddle Link : http://jsfiddle.net/ur58nae5/
$(function () {
$('#container').highcharts({
chart: {
type: 'column',
backgroundColor: null,
style: {
fontFamily: 'helvetica, arial'
}
},
colors:['#F5A623'],
credits: false,
title: {
text: 'Attacks by Risk Score'
},
subtitle: {
text: 'Number of malicious IPs seen in this period based on maximum risk score'
},
xAxis: {
type: 'category',
title: {
text: "Risk Score"
},
labels: {
rotation: 0,
style: {
fontSize: '11px',
fontFamily: 'helvetica, arial, Verdana, sans-serif'
}
}
},
yAxis: {
min: 0,
title: {
text: 'Number of IP Addresses'
}
},
legend: {
enabled: false
},
tooltip: {
enabled: false
},
series: [{
name: 'IPS',
data: [
['1', 21],
['2', 109],
['3', 112],
['4', 125],
['5', 106],
['6', 112],
['7', 143],
['8', 207],
['9', 386],
['10', 908]
],
dataLabels: {
enabled: true,
rotation: -90,
color: '#FFFFFF',
align: 'right',
y: 10, // 10 pixels down from the top
style: {
fontSize: '10px',
fontFamily: 'helvetica, arial, sans-serif',
textShadow: false,
fontWeight: 'normal'
}
}
}]
});
});
As I understand it, your problem is that sometimes the columns are too small to display the dataLabels. You have a couple of options:
You can use a logarithmic scale to make the data differences less pronounced.
http://jsfiddle.net/ur58nae5/1/
yAxis: {
type:'logarithmic',
title: {
text: 'Number of IP Addresses'
}
},
Or you can format points that are smaller than some threshold to move the label outside the column
series: [{
name: 'IPS',
data: [
{x:1, y:21, dataLabels: { color:'#000', y:-15}},
['2', 109],
['3', 112],
['4', 125],
['5', 106],
['6', 112],
['7', 143],
['8', 207],
['9', 386],
['10', 908]
],
dataLabels: {
enabled: true,
rotation: -90,
color: '#FFFFFF',
align: 'right',
y: 10, // 10 pixels down from the top
style: {
fontSize: '10px',
fontFamily: 'helvetica, arial, sans-serif',
textShadow: false,
fontWeight: 'normal'
}
}
}]
http://jsfiddle.net/ur58nae5/2/
http://jsfiddle.net/ur58nae5/3/

Categories

Resources