Specifying a width and height of 100% generates JavaScript errors - javascript

I am attempting to render a Google bar chart. In my JavaScript, I have the following:
var options = {
width: '100%',
height: '100%',
chartArea: {
height: '100%',
width: '100%',
left: 85,
top: 10,
bottom: 60,
right: 25
},
legend: { position: 'bottom', alignment: 'start' },
annotations: { alwaysOutside: true},
hAxis: {
gridlines: { count: 10 },
},
};
When I execute this, I get the following JavaScript errors:
However, if I change the height from '100%' to '400' as shown below, the chart renders correctly with no JS errors.
var options = {
width: '100%',
height: '400',
chartArea: {
height: '100%',
width: '100%',
left: 85,
top: 10,
bottom: 60,
right: 25
},
legend: { position: 'bottom', alignment: 'start' },
annotations: { alwaysOutside: true},
hAxis: {
gridlines: { count: 10 },
},
};
If it matters, the div that represents the chart is in a Bootstrap container. The HTML looks as follows:
<div id="chart_div" class="col-xs-12 col-md-6">
</div>

The issue is here that google chart width and height expect a number, but you are sending a string including the % symbol, this is what the NaN error is, its Not a Number!
EDIT
Apologies, the documents state it can be either a number or string, my guess is that it is trying to convert it to a string and the % causes the error
chartArea.width
Type: number or string
Default: auto
chartArea.height
Type: number or string
Default: auto
https://developers.google.com/chart/interactive/docs/gallery/barchart#configuration-options
Edit 2
I was actually looking at the chartArea.height and not height.
The documentation states that the height and weight should be in pixels, so a number
height
Height of the chart, in pixels.
Type: number
Default: height of the containing element
width
Width of the chart, in pixels.
Type: number
Default: width of the containing element
So I cant really answer your original question, why the chart will accept a string is a mystery, when it is clearly defined as requiring a number.

Related

Highcharts Automatic resizing of indicators when adding axis

I am storing chart data in localstorage.
Then I add them to the chart.
chart_obj.addAxis({
id: element.yAxis,
lineWidth: 1,
lineColor: '#08F',
offset: 0,
});
chart_obj.addSeries({
type: element.type,
linkedTo: ''+element.linkedTo+'',
yAxis: element.yAxis
});
As a result, my height indicator is on a different indicator.
The thing is that you have to set the height and position manually there.
But, when you add an indicator from the menu of indicators, it is added normally.
Example
How does adding yAxis automatically recalculate the height?
I tried different methods from the API, read the forum - but nowhere found information on how to do it.
To ensure that the series do not scale, you need to do an update on the axes and set their top and height.
chart_obj.yAxis[0].update({
title: {
text: 'updated'
},
height: '50%',
top: '50%'
})
chart_obj.addSeries({
type: 'ao',
yAxis: 1,
greaterBarColor: '#00cc66',
lowerBarColor: '#FF5E5E',
linkedTo: 'AAPL',
showInLegend: true
});
chart_obj.yAxis[1].update({
title: {
text: 'updated'
},
height: '50%',
top: '0%'
})
},
DEMO: https://jsfiddle.net/BlackLabel/u3s2cjyv/

Google Charts Timeline change bar height with react-google-charts

I have this google chart timeline (using react-google-charts).
<Chart
chartType="Timeline"
data={data}
width="100%"
options={{
allowHtml: true
bar: { groupWidth: 10 },
}}
/>
I tried adding bar: { groupWidth: 10 } and its working on the normal bar chart but not on the timeline.
Try for example this jsfiddle here: https://jsfiddle.net/c5hyknfr/2/
Doesnt work for the timeline. Any other way to do that?
EDIT: Added a bounty, in case someone knows also any workaround with CSS and/or using classes. Hacky solutions approved.
You can increase the font size for the bar's labels. This will also increase the bar's height. You need to add the barLabelStyle.fontSize-property in the options-object:
var options = {
timeline: {
groupByRowLabel: true,
showRowLabels: true,
rowLabelStyle: {
fontName: 'Helvetica',
fontSize: 9,
color: '#000000'
},
barLabelStyle: {
fontSize: 30
}
},
'width': 1100,
'height': 2200,
'chartArea': {
width: '80%', // make sure this is the same for the chart and control so the axes align right
height: '80%'
},
'backgroundColor': '#ffd',
'view': {
'columns': [0, 1, 4, 5]
}
};
Then you could adjust your CSS to decrease the font-size again, but your bars will remain bigger. Please note that the labels of the bars aren't correctly centered anymore. That's why you need to transform the position, so the labels are centered again:
rect + text {
font-size: 12px;
transform: translate(0, -5px);
}
With the values from the example it will look like this:

Pass dynamic variables in options to Google Charts

I am trying to pass a Series number in a Google Chart option through a variable. However it is not accepting it as a variable and instead is taking it as a string. You can see in Image1 that I have passed in Series parameter SecondseriesColumnNumber as a variable and value is 1.
Image 1
However in the output it is considering it as a string but not as the series number as shown below
Image 2
Other parameters are considering the values correctly but not the series one. How can I make this work? My code is below
var options = {
title: title,
width: width,
height: height,
bar: { groupWidth: '75%' },
chartArea: { left: "8%", right: "8%", top: "10%", width: "100%", height: "75%" },
backgroundColor: 'transparent',
tooltip: { textStyle: { color: 'black' }, isHtml: true },
isStacked: isStacked,
seriesType: seriesType,
series: { SecondseriesColumnNumber: { type: SecondseriesType } },
hAxis: { slantedText: true }
};
var chart = new google.visualization.ComboChart($('DivSeries')[0]);
the problem has to do with JavaScript syntax.
you are not able to use a variable as a key in the definition of an object.
you must first create the object, then you can add additional keys using variables.
there are two ways to get / set values of object keys, once the object is defined.
both of the following will return the same value for title.
var title = options.title;
var title = options['title'];
where as in the latter, we can substitute a variable for the title key.
var key = 'title';
var title = options[key];
in this case, define the static options as needed.
var options = {
title: title,
width: width,
height: height,
bar: { groupWidth: '75%' },
chartArea: { left: "8%", right: "8%", top: "10%", width: "100%", height: "75%" },
backgroundColor: 'transparent',
tooltip: { textStyle: { color: 'black' }, isHtml: true },
isStacked: isStacked,
seriesType: seriesType,
series: {},
hAxis: { slantedText: true }
};
then you can use a variable to further define the series option.
var SecondseriesColumnNumber = 1;
options.series[SecondseriesColumnNumber] = { type: SecondseriesType };

How can you force Google Charts vAxes render?

Currently I have two graphs I'm rendering on a page, I'm using google's visualization Charts lib and due to page sizing issues the vAxes refuses to render some/most of the time.
If I give it enough space, it will render the axes fine, but if it's even slightly off, even when there's plenty of space for these bloody axes, they just refuse to render, I can't have that!
I looked into it and it seems to be rendering bunch of tags when it works and doesn't render when it doesn't work, which makes me think there ought to be some bull if-else "AI" that actively chooses to sabotage me! FS!
Has anyone had experience with Charts and managed to find a workaround on forcing the lib to render the vAxes regardless of what google "AI" wills? (Seriously, what happened to second law of robotics?! OBEY ME, SCUM!)
Sorry, I'm a bit irked atm.
Edit: Sorry, to provide the details, here's the js block rendering the charts:
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
// Load the Visualization API and the chart package.
google.charts.load('visualization', {'packages':['corechart']});
// Set a callback to run when the Google Visualization API is loaded.
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var options = {
hAxis: {showTextEvery: 5},
vAxes: {
0: {textPosition: 'out',
viewWindowMode:'pretty',
viewWindow: {min:0},
gridlines: {color: 'transparent'},
},
1: { textPosition: 'out',
viewWindow: {min:0},
gridlines: {color: 'transparent'}
},
},
seriesType: 'bars',
series: {0: {targetAxisIndex:0, type: 'line'},
1:{targetAxisIndex:1},
2:{targetAxisIndex:1},
}
};
//Chart render
var data1 = new google.visualization.DataTable(<?=$jsonEventType?>);
var chart1 = new google.visualization.ComboChart(document.getElementById('chart_div1'));
chart1.draw(data1, options);
}
div element:< div id="chart_div1" style=" height: 100%;"> (it's within multiple other divs, but that's besides the point)
As you can tell it's a basic c-c-c-combo chart, the $jsonEventType doesn't matter i think but here it is:
string(661) "{"cols":[{"label":"Date","type":"string"},{"label":"To Audit","type":"number"},{"label":"Open","type":"number"},{"label":"Closed","type":"number"}],"rows":[{"c":[{"v":"05/07/2018"},{"v":437},{"v":0},{"v":8}]},{"c":[{"v":"12/07/2018"},{"v":419},{"v":0},{"v":21}]},{"c":[{"v":"19/07/2018"},{"v":401},{"v":56},{"v":36}]},{"c":[{"v":"26/07/2018"},{"v":385},{"v":0},{"v":20}]},{"c":[{"v":"02/08/2018"},{"v":369},{"v":0},{"v":12}]},{"c":[{"v":"09/08/2018"},{"v":357},{"v":0},{"v":25}]},{"c":[{"v":"16/08/2018"},{"v":348},{"v":0},{"v":18}]},{"c":[{"v":"23/08/2018"},{"v":336},{"v":0},{"v":14}]},{"c":[{"v":"30/08/2018"},{"v":316},{"v":0},{"v":13}]}]}"
you can use the chartArea config code to ensure there is enough room on either side of the chart.
by default, the chart will follow the size of the container,
but it does not entirely fill the container.
I like to use the chartArea option,
to stretch the chart to the height and width of the container,
and leave room on the edges for the axes and legend, etc...
chartArea: {
top: 32, // leave room on top for legend
left: 60, // for axis index 0
right: 60, // for axis index 1
bottom: 32, // for x-axis
height: '100%', // stretch height
width: '100%', // stretch width
},
height: '100%', // ensure fills height of container
width: '100%', // fills width of container
see following working snippet...
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
var data = new google.visualization.DataTable({"cols":[{"label":"Date","type":"string"},{"label":"To Audit","type":"number"},{"label":"Open","type":"number"},{"label":"Closed","type":"number"}],"rows":[{"c":[{"v":"05/07/2018"},{"v":437},{"v":0},{"v":8}]},{"c":[{"v":"12/07/2018"},{"v":419},{"v":0},{"v":21}]},{"c":[{"v":"19/07/2018"},{"v":401},{"v":56},{"v":36}]},{"c":[{"v":"26/07/2018"},{"v":385},{"v":0},{"v":20}]},{"c":[{"v":"02/08/2018"},{"v":369},{"v":0},{"v":12}]},{"c":[{"v":"09/08/2018"},{"v":357},{"v":0},{"v":25}]},{"c":[{"v":"16/08/2018"},{"v":348},{"v":0},{"v":18}]},{"c":[{"v":"23/08/2018"},{"v":336},{"v":0},{"v":14}]},{"c":[{"v":"30/08/2018"},{"v":316},{"v":0},{"v":13}]}]});
var options = {
chartArea: {
top: 32, // leave room on top for legend
left: 60, // for axis index 0
right: 60, // for axis index 1
bottom: 32, // for x-axis
height: '100%', // stretch height
width: '100%', // stretch width
},
height: '100%', // ensure fills height of container
width: '100%', // fills width of container
hAxis: {showTextEvery: 5},
vAxes: {
0: {
textPosition: 'out',
viewWindowMode:'pretty',
viewWindow: {min: 0},
gridlines: {color: 'transparent'},
},
1: {
textPosition: 'out',
viewWindow: {min: 0},
gridlines: {color: 'transparent'}
},
},
seriesType: 'bars',
series: {
0: {targetAxisIndex:0, type: 'line'},
1: {targetAxisIndex:1},
2: {targetAxisIndex:1},
}
};
var chart = new google.visualization.ComboChart(document.getElementById('chart_div1'));
chart.draw(data, options);
window.addEventListener('resize', function () {
chart.draw(data, options);
});
});
html, body {
height: 100%;
margin: 0px 0px 0px 0px;
overflow: hidden;
padding: 0px 0px 0px 0px;
}
#chart_div1 {
height: 100%;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div1"></div>

Increase Height Of Chart On Export

Using latest highcharts (3.0.7). We are trying to add text to the top of the chart on export. to do this I need to increase the spacingTop so that we do not overwrite any chart elements. This then causes the chart to become less high by that amount of spacingTop for a the same chart height. How can I get the current chart height and add X amount to it on export? I have tried:
exporting: {
sourceWidth: 400,
//sourceHeight: this.chartHeight,
//sourceHeight: this.chartHeight + 200,
scale: 1, //(default)
chartOptions: {
subtitle: null,
height: this.chartHeight + 200
}
}
This seems to be ignored. See this fiddle. This was just a test to see if I could do this at all. Seems like it should be straight forward. If I uncomment out the sourceHeight it still does not do what I expect - the chart is still 400px high. So it seems that this.chartHeight does not contain anything.
In the end this height change code is going to exist in a function we call:
chartMainLoc.exportChart({
type: 'image/jpeg',
sourceHeight: this.chartHeight + 200,
sourceWidth: this.chartWidth,
scale: 1
}, {
chart: {
events: {
load: function () {
this.renderer.text('Occupational Employment and Wage Rates (OES) for Multiple Occupations in Louisiana in 2012<br /> The graph below shows the annual occupational employment and annual wage data for Multiple Occupations in Louisiana in 2012.<br /> ', 5, 15).attr({
rotation: 0
}).css({
color: '#4572A7',
fontSize: '10px',
fontStyle: 'italic',
width: this.chartWidth
}).add();
this.renderer.rect(5, 5, this.chartWidth - 10, 60, 5).attr({
'stroke-width': 2,
stroke: 'black',
zIndex: 2
}).add();
}
},
spacingTop: 200,
shadow: false
}
})
Since I do not know the chart's height or width beforehand I have to get this value somehow.
You need to set chart optiosn with objects (chart / series etc) like in the example http://jsfiddle.net/GQUDJ/2/

Categories

Resources