Why doesn't highcharts solidgauge charts scale the way I expect? - javascript

I am using a solidgauge chart from highcharts and appear to have scaling issues.
The basic issue is that I want to define a chart that can be resized and expect the graph to adjust to fit the space in the best way.
But sometimes the chart extends outside the container and sometimes the chart is smaller than it needs to be.
A test is in jsFiddle here.
That test shows various versions of the chart:
Chart test [A] = pane.size = 100% / container size = 400px x 400px.
Chart test [B] = pane.size = 140% / container size = 400px x 400px.
Chart test [C] = pane.size = 100% / container size = 400px x 300px.
Chart test [D] = pane.size = 140% / container size = 400px x 300px.
The main chart options used are these:
{
chart: {
type: 'solidgauge'
},
credits: false,
title: {
text: 'Solid Gauge'
},
yAxis: {
minorTickInterval: null,
min: 0,
max: 100
},
pane: {
center: ['50%', '85%'],
size: '140%', // ISSUE: problem scaling chart outside container
//size: '100%', // ISSUE: problem with gap above gauge
startAngle: -90,
endAngle: 90,
background: {
innerRadius: '60%',
outerRadius: '100%',
shape: 'arc'
}
},
plotOptions: {
solidgauge: {
dataLabels: {
y: 5,
decimalPlaces: 1,
units: 'rpm',
borderWidth: 0,
useHTML: true,
format: '<div style="text-align:center"><span style="font-size:25px;color:' +
('black') + '">{point.y:.11f}</span><br/>' +
'<span style="font-size:12px;color:silver">rpm</span></div>'
}
}
},
tooltip: {
enabled: false
}
};
Chart [A] is OK, but if I use the same pane size (100%) and reduce the height (to 300px) to remove the gap between the title and the chart then I get [C] where the chart has been scaled down too small.
Similarly, chart [D] is OK, but if I use the same pane size (140%) and increase the height (to 400px) then the graph extends outside the container as shown in [B].
Are there any options that I am missing that can be used to fix this problem, or am I going to have to dynamically adjust the chart based on container size (which I want to avoid) ?

As you can read on highcharts forum here: https://www.highcharts.com/forum/viewtopic.php?t=33070
Solid gauge is created from angular gauge. The background is one of
key elements that make the chart look like arc shaped solid gauge. If
you disable it you will see that options used for inner radius and
outer radius as well as size or center of pane are calculated for
circle, but the arc is used for visualization.
So, remove the startAngle and endAngle to see how the chart is scaled. As you can notice it is scaled as circle and arc is used only for visualization. That's why it is acting so strange, due to solid gauge architecture.
Demo:
https://jsfiddle.net/BlackLabel/mtevb2d3/

Related

Chart JS: Set Spacing Between Ticks on Y-Axis

I am building a line chart using ChartJS. I want to increase the spacing between the vertical tick marks on the Y-Axis. Here is a slice of the relevant options being passed to ChartJS. Is there a property in the ticks section that will allow me to increase the spacing between the ticks, thereby increasing the total height of the chart canvas?
lineChartOptions = {
scales: {
yAxes: [
{
id: 'y-axis-0',
position: 'left',
ticks: {
... // <-- WHAT OPTION GOES HERE?
}
},
Note: It is not an option to simply decrease the height of the canvas using CSS, the canvas stretches to fill the space thereby distorting the chart.
If not much different data you can use this to set range
//EXAMPLE DATA [533,743,612,983]
ticks: {
beginAtZero: false,
stepSize: 100,
max: 1000
min: 500
}

Overlapping bars in c3 (v4) bar chart

I would like to make a reference to this previous question:
stacked bar chart with overlapping bars C3js
However, my only problem is that I want to overlap columns to show (as an example) that from 4 students, 3 have passed the subject. Right now I have a bar with height 3 and on top a bar with height 4, which makes it 7 and I want a bar of 4 with a bar of 3 overlapping. How can I change my code? Thanks:
<div id="chart3"></div>
<script>
var chart = c3.generate({
bindto: '#chart3',
data: {
url: '../static/CSV/Chart_data/number_students.csv,
x:'AC_YEAR',
type: 'bar',
groups: [
['Total women', 'Passed women'],
['Total men', 'Passed men']
],
},
axis: {
y: {
label: {
text:"Number of students",
position: "outer-middle"
},
},
x: {
label: {
text:"Year",
position: "outer-center"
},
}
},
size: {
height: 400,
width: 800
},
bar:{
width:{ratio:0.7}
},
legend: {
show: true,
position: 'inset',
inset: {
anchor: 'top-right',
x: 10,
y: 5,
step: 2
}
}
});
</script>
The csv file number_students is:
AC_YEAR,Passed women,Passed men,Total women,Total men
2010,72,239,98,315
2011,77,227,83,276
2012,65,226,93,298
2013,54,215,77,283
2014,63,233,88,294
2015,49,205,64,267
The current one looks like this:
And the one I want should overlap so that, in 2010 for example, we would see only a little of green (the 7 female students that did not passed) because the blue in the front is only 7 units less than the green. And in the right 29 units of red color (the male students that did not passed).
I have never worked with c3 before so I have no idea if there is any chart in c3 that can particularly do this. I was able to solve this by using d3.
Firstly c3 uses path for bars instead of rects for some reason otherwise changing the width of the bars could have been easier.
What I did was first store all the dimensions of the bars for all four categories into four different arrays using d3.select(**bars**).node().getBBox() and then adjust the y and width for Total women and Total men bars according to y attributes of Passed women and Passed men because we want to overlap them.
Then hide all the path elements created by c3 and then wrap all this in a function to be called when the user resizes the browser window.
Here'a the complete fiddle or a plunkr

Defining the height of the jqPlot horizontal bars and the distance between them

is there a way to define the height of the horizontal bars and the distance between them. I am searching for a possibility to put as many horizontal bars in a view as possible.
Thanks!
My solution:
seriesDefaults: {
...
rendererOptions: {
...
barPadding: 1,
barMargin: 10,
barWidth: 20,
...
}
},

Highcharts Donut Chart customization

I'm working with highcharts and aiming to make a chart similar to this:
Now I've been playing around with the whole ordeal for a while now and I've come been able to reach the following point: http://jsfiddle.net/ccjSy/24/
$(function () {
$(document).ready(function () {
var chart = null;
var categories = ['Body Fat', 'Lean Mass'],
name = 'Body Fat vs. Lean Mass',
data = [{
y: 69,
color: '#F0CE0C',
drilldown: {
name: 'Body Fat',
color: '#F0CE0C'
}
}, {
y: 207,
color: '#23A303',
drilldown: {
name: 'Lean Mass' ,
color: '#23A303'
}
}];
// Build the data array
var browserData = [];
for (var i = 0; i < data.length; i++) {
// add browser data
browserData.push({
name: categories[i],
y: data[i].y,
color: data[i].color
});
}
// Create the chart
chart = new Highcharts.Chart({
chart: {
renderTo: 'donutchart',
type: 'pie',
spacingTop: 0
},
title: {
text: 'Your Body Fat vs Lean Mass',
style: {"color": '#7d7d7d'}
},
series: [{
name: 'Weight',
data: browserData,
dataLabels: {
style: {
fontFamily: 'ArialMT',
fontSize: '15px',
fontWeight: 'bold',
color: '#7d7d7d'
}
},
innerSize: '70%'
}],
tooltip: {
valueSuffix: ' lbs'
},
plotOptions: {
series: {
cursor: 'pointer'
}
}
});
});
});
I am thinking of leaving the space empty in the donut chart and inserting a custom circle with the Weight labeling.
However, I'm not certain how to tackle the following problems:
1) Leave more defined white spaces in between my two columns
2) How to properly align my two data labels? (As you can see in the model, they are in a straight line with neutral lines attached)
3) How to display the data underneath the two labels with both, the pounds and the percentage, as shown in the image.
Answering each of your three questions:
"More white space between columns?" -- add a plotOptions.pie.borderWidth element. The default value is 1. I used 5 to give it more white space.
"Properly align the two data labels?" -- You can compute a custom startAngle based on the two data values which will give you the correct angle to start with. Since you only have two data values in the series, that's easy.
Calculate startAngle for pie chart
var startAngle = 0 - (90 + (180 * (data[0].y / (data[0].y + data[1].y))));
Notice that if you change the y value for the first data object, the "Body Fat" portion of the pie chart will still maintain it's correct position, even as the portion of the chart grows larger or smaller.
"Display data underneath the two labels with custom formatting?" -- use plotOptions.pie.format to apply custom formatting to the pie value labels.
format: '<div style="position: relative; top: -20px; text-align: center">{point.name}<br><b><span style="font-size: 29px">{point.percentage:.0f}%</span></b> ({point.y} lbs)</div>'
Here's a working JSFiddle to see the results. You'll still need to add a dark gray circle behind the pie chart and add the "Total Weight" text but that shouldn't be too difficult.
Since I'm sure you'll be wondering about this, I should mention that there's a lot of white space under the pie chart title because it's leaving enough room for other labels that may appear above or below the pie. Since you're only using two values that will always be on the left/right sides of the pie chart, that doesn't change the fact that HighCharts is preparing to have other labels that may need to be displayed in the surrounding area.

Legend on bottom with highcharts

I am using highcharts to draw some charts. I use the basic line plot like this:
http://www.highcharts.com/demo/spline-irregular-time
How can I display the legend under the chart area instead of at the right?
http://www.highcharts.com/demo/column-stacked-percent
Thx
marginBottom can be used to put legend on bottom of chart. You can still use legend property to move legend for example in the middle or right(i used center).
chart: {
marginBottom: 100
},
legend: {
align: 'center',
verticalAlign: 'bottom',
x: 0,
y: 0
},
Possible solution: fiddle
Having the legend under the chart is the default, so you can omit the legend propery entirely. Bear in mind that to make this look nice, you'll have to add a little to the bottom margin, otherwise the chart and the legend will overlap.
chart: {
type: 'line',
marginRight: 130,
marginBottom: 70 // Increase this to 70 or so
},
// Remove the legend property completely
Here's a demonstration.

Categories

Resources