Making Highcharts.js charts look good on mobile and desktop - javascript

I'm wondering if anyone has successfully implemented a responsive design using Highcharts to make their charts look good on both mobile and desktop.
By default, Highcharts do re-scale when you resize the browser screen its just that the X-axis get cluttered by the tick mark text and bar graphs look tall and too skinny (too compressed).
To get a sense of what I mean, you can go to this page and resize the browser.
I think these issues could possibly be addressed by reducing the amount of data points say to 1/3 of the original number though I'm wondering how that would be accomplished programmatically using Highcharts's API. If that doesn't sound like a good idea I'm also interested in other thoughts or solutions people might have come up with to use Highcharts on mobile (or perhaps even different JS charting libraries where a multi-device solution might be easier to implement?).

The solution seems rather simple.
Just don't give the graph's a fixed width, i.e., don't define the width or set width:100% and, unlike the demo I mention, the bar chart width and accompanying bars will shrink as much as the browser width is reduced.

It probably depends on which types of charts that you are displaying. On mobile, if you're displaying a column chart, you might want to rotate the chart so that it becomes a bar chart.
If you're displaying a line chart, you could "scope" the data, so that you're only displaying the least amount of points needed to get the point across. As you zoom in, re-scope the data to fit the current view. This can be done using some events combined with some hand rolled js.

You can set the chart container div width:100% .
Then just remove the highchart width property. I resolved it for a sparkline chart. Now it is mobile responsive.
Highcharts.chart('my-sparkline-chart, {
chart: {
type: 'areaspline',
height: '70',
//width: '189', //comment width property.
spacing: [0, 0, 0, 0],
backgroundColor: "transparent"
}
...

An Example with bootstrap
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>Highcharts data from JSON Response</title>
<style>
body{
margin-top: 30px;
margin-left:40px;
}
.col-md-4{
padding-left:5px !important;
padding-right:5px !important;
}
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script type="text/javascript">
// Data gathered from http://populationpyramid.net/germany/2015/
// Age categories
var categories = ['0-4', '5-9', '10-14', '15-19',
'20-24', '25-29', '30-34', '35-39', '40-44',
'45-49', '50-54', '55-59', '60-64', '65-69',
'70-74', '75-79', '80-84', '85-89', '90-94',
'95-99', '100 + '];
$(document).ready(function () {
Highcharts.chart('container', {
chart: {
type: 'bar'
},
xAxis: [{
categories: categories,
reversed: false,
labels: {
step: 1
}
}, { // mirror axis on right side
opposite: true,
reversed: false,
categories: categories,
linkedTo: 0,
labels: {
step: 1
}
}],
yAxis: {
title: {
text: null
},
labels: {
formatter: function () {
return Math.abs(this.value) + '%';
}
}
},
plotOptions: {
series: {
stacking: 'normal'
}
},
tooltip: {
formatter: function () {
return '<b>' + this.series.name + ', age ' + this.point.category + '</b><br/>' +
'Population: ' + Highcharts.numberFormat(Math.abs(this.point.y), 0);
}
},
series: [{
name: 'Male',
data: [-2.2, -2.2, -2.3, -2.5, -2.7, -3.1, -3.2,
-3.0, -3.2, -4.3, -4.4, -3.6, -3.1, -2.4,
-2.5, -2.3, -1.2, -0.6, -0.2, -0.0, -0.0]
}, {
name: 'Female',
data: [2.1, 2.0, 2.2, 2.4, 2.6, 3.0, 3.1, 2.9,
3.1, 4.1, 4.3, 3.6, 3.4, 2.6, 2.9, 2.9,
1.8, 1.2, 0.6, 0.1, 0.0]
}]
});
Highcharts.chart('container2', {
chart: {
type: 'bar'
},
title: {
text: 'Population pyramid for Germany, 2015'
},
subtitle: {
text: 'Source: Population Pyramids of the World from 1950 to 2100'
},
xAxis: [{
categories: categories,
reversed: false,
labels: {
step: 1
}
}, { // mirror axis on right side
opposite: true,
reversed: false,
categories: categories,
linkedTo: 0,
labels: {
step: 1
}
}],
yAxis: {
title: {
text: null
},
labels: {
formatter: function () {
return Math.abs(this.value) + '%';
}
}
},
plotOptions: {
series: {
stacking: 'normal'
}
},
tooltip: {
formatter: function () {
return '<b>' + this.series.name + ', age ' + this.point.category + '</b><br/>' +
'Population: ' + Highcharts.numberFormat(Math.abs(this.point.y), 0);
}
},
series: [{
name: 'Male',
data: [-2.2, -2.2, -2.3, -2.5, -2.7, -3.1, -3.2,
-3.0, -3.2, -4.3, -4.4, -3.6, -3.1, -2.4,
-2.5, -2.3, -1.2, -0.6, -0.2, -0.0, -0.0]
}, {
name: 'Female',
data: [2.1, 2.0, 2.2, 2.4, 2.6, 3.0, 3.1, 2.9,
3.1, 4.1, 4.3, 3.6, 3.4, 2.6, 2.9, 2.9,
1.8, 1.2, 0.6, 0.1, 0.0]
}]
});
Highcharts.chart('container3', {
chart: {
type: 'bar'
},
title: {
text: 'Population pyramid for Germany, 2015'
},
subtitle: {
text: 'Source: Population Pyramids of the World from 1950 to 2100'
},
xAxis: [{
categories: categories,
reversed: false,
labels: {
step: 1
}
}, { // mirror axis on right side
opposite: true,
reversed: false,
categories: categories,
linkedTo: 0,
labels: {
step: 1
}
}],
yAxis: {
title: {
text: null
},
labels: {
formatter: function () {
return Math.abs(this.value) + '%';
}
}
},
plotOptions: {
series: {
stacking: 'normal'
}
},
tooltip: {
formatter: function () {
return '<b>' + this.series.name + ', age ' + this.point.category + '</b><br/>' +
'Population: ' + Highcharts.numberFormat(Math.abs(this.point.y), 0);
}
},
series: [{
name: 'Male',
data: [-2.2, -2.2, -2.3, -2.5, -2.7, -3.1, -3.2,
-3.0, -3.2, -4.3, -4.4, -3.6, -3.1, -2.4,
-2.5, -2.3, -1.2, -0.6, -0.2, -0.0, -0.0]
}, {
name: 'Female',
data: [2.1, 2.0, 2.2, 2.4, 2.6, 3.0, 3.1, 2.9,
3.1, 4.1, 4.3, 3.6, 3.4, 2.6, 2.9, 2.9,
1.8, 1.2, 0.6, 0.1, 0.0]
}]
});
})
</script>
</head>
<body>
<div class="col-md-12 row">
<div class="col-md-4">
hello
</div>
<div class="col-md-8 row">
<div class="col-md-4"><div id="container" style="height: 400px;border:1px solid;"></div></div> <div class="col-md-4"><div id="container2" style="height: 400px;border:1px solid;"></div></div>
<div class="col-md-4"><div id="container3" style="height: 400px;border:1px solid;"></div></div>
</div>
</div>
</body>
</html>

try add this on the <head></head>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>

Related

Trying to plot a histogram with randomly generated data in js with highcharts but my code does not work?

There is a problem with getting the code to read the normally distributed data, but I have no idea how to fix this problem. I am trying to implement the histogram using highcharts.
var data = [];
for (var i = 0; i < 1000; i++) {
data.push(Math.random() * (0.5 - (-0.5)) + (-0.5));
};
Highcharts.chart('container', {
chart: {
type: 'column'
},
title: {
text: 'Histogram'
},
xAxis: {
title: {
text: 'Bins'
},
categories: [-0.5, -0.45, -0.4, -0.35, -0.3, -0.25, -0.2, -0.15, -0.1, -0.05, 0,
0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5
],
min: -0.5,
max: 0.5,
tickInterval: 0.05,
gridLineWidth: 0
},
yAxis: {
title: {
text: 'Frequency'
}
},
series: [{
name: 'Data',
data: data
// normally distributed data here
}],
plotOptions: {
column: {
pointPadding: 0,
groupPadding: 0
}
}
});
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="container"></div>
Where should I try to move the data for the code to be working?
I am trying to plot a histogram.
I do not understand what you are trying to do with all these meaningless categories in your xAxis configuration and I think you may need a linear scale.
You should read this part of the documentation about axis types.
Here is a basic example:
let data = [];
for (let i = 0; i < 1000; i++) {
data.push(Math.random() - 0.5);
}
Highcharts.chart('container', {
chart: {
type: 'column'
},
series: [{
name: 'Series',
data
}]
});
#container {
width: 100%;
height: 350px;
}
<script src="https://code.highcharts.com/10.3.3/highcharts.js"></script>
<div id="container"></div>
In principle, a histogram is used to show, reflecting a series of points on a column chart where the columns are the bins in which the points are located. If you want to show your points on a category type axis it might look like this.
At this documentation, it's explained how to create histogram series.
Demo: https://jsfiddle.net/BlackLabel/wLmu62a9/
const data = [-0.5, -0.45, -0.4, -0.35, -0.3, -0.25, -0.2, -0.15, -0.1, -0.05, 0,
0.05, 0.1, 0.15, 0.2, 0.25, 0.3
];
Highcharts.chart('container', {
title: {
text: 'Highcharts Histogram'
},
xAxis: [{
title: {
text: 'Bins'
},
categories: [-0.5, -0.45, -0.4, -0.35, -0.3, -0.25, -0.2, -0.15, -0.1, -0.05, 0,
0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 5.5
],
}, {
title: {
text: 'Histogram'
},
alignTicks: false,
opposite: true
}],
yAxis: [{
title: {
text: 'Data'
}
}, {
title: {
text: 'Histogram'
},
opposite: true
}],
series: [{
name: 'Histogram',
type: 'histogram',
xAxis: 1,
yAxis: 1,
baseSeries: 's1',
zIndex: -1
}, {
name: 'Data',
type: 'scatter',
data: data,
id: 's1',
marker: {
radius: 1.5
}
}]
});
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/histogram-bellcurve.js"></script>
<script src="https://code.highcharts.com/modules/accessibility.js"></script>
<div id="container"></div>

Cannot find name 'Highcharts'.ts(2304)

I am getting issue in angular "Cannot find name 'Highcharts'.ts(2304)"
how to solve this problem
also I used CDN for high chart
I installed
"npm install --save highcharts"
begin snippet: hide: false console: true babel: false
Highcharts.chart('container', {
chart: {
type: 'spline'
},
xAxis: {
type: 'datetime',
labels: {
overflow: 'justify'
}
},
yAxis: {
opposite: true,
minorGridLineWidth: 0,
gridLineWidth: 0,
alternateGridColor: null,
},
tooltip: {
valueSuffix: ' m/s'
},
plotOptions: {
spline: {
lineWidth: 4,
states: {
hover: {
lineWidth: 5
}
},
marker: {
enabled: false
},
pointInterval: 3600000, // one hour
pointStart: Date.UTC(2015, 4, 31, 0, 0, 0)
}
},
series: [{
name: 'Hestavollane',
data: [0.2, 0.8, 0.8, 0.8, 1, 1.3, 1.5, 2.9, 1.9, 2.6, 1.6, 3, 4, 3.6, 4.5, 4.2, 4.5, 4.5, 4, 3.1, 2.7, 4, 2.7, 2.3, 2.3, 4.1, 7.7, 7.1, 5.6, 6.1, 5.8, 8.6, 7.2, 9, 10.9, 11.5, 11.6, 11.1, 12, 12.3, 10.7, 9.4, 9.8, 9.6, 9.8, 9.5, 8.5, 7.4, 7.6]
}],
navigation: {
menuI
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
temStyle: {
fontSize: '10px'
}
}
}
);
language: html
<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
end snippet

Why is my secondary yAxis not matching to my xAxis in Highcharts?

I am building a combination column/scatter chart using Highcharts. My xAxis data is a categorical set of countries, with two sets of numerical data on yAxis[0] and yAxis[1].
I am trying to essentially duplicate this HighCharts example:
http://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/demo/combo-dual-axes/
Here is my version:
https://jsfiddle.net/MossTheTree/37r1w7f7/
With the xAxis:
xAxis: [{
categories: ["People's Republic of China",
'United States',
'India',
'Australia',
'Indonesia',
'Russian Federation',
'South Africa',
'Germany',
'Poland',
'Kazakhstan',
'Rest of the world'],
labels: {
rotation: -45,
style: {
fontSize: '13px',
fontFamily: 'Verdana, sans-serif'
}
},
crosshair: true
}],
and the yAxis:
yAxis: [{
title: {
text: 'Coal production (Megatonnes)'
},
labels: {
format: '{value} Mt'
},
min: 0,
max: 4000,
tickInterval: 250
},
{
labels: {
format: '{value}%'
},
title: {
text: '% of world total'
},
min: 0,
max: 100,
opposite: true
}],
And the series:
series: [{
name: 'Production',
type: 'column',
data: [3527, 813, 691, 509, 469, 349, 252, 185, 136, 107, 671],
tooltip: {
valueSuffix: ' Mt'
}
},{
name: 'Percentage of World Total',
yAxis: 1,
type: 'scatter',
data: [45.8, 10.5, 9.0, 6.6, 6.1, 4.5, 3.3, 2.4, 1.8, 1.4, 8.6],
tooltip: {
valueSuffix: '%'
}
}]
In general it's all displaying correctly, except the shared tooltip isn't working. Somehow the data plotted to yAxis[1] is not being matched to the xAxis categorical data, and are rather being matched to some integer x values.
I've checked and re-checked against the demo I'm trying to replicate but can't see any obvious errors. What is wrong with my syntax that could be causing this problem?
To display scatter points inside shared tooltip, instead of using scatter, you can use line type series and disable line, by setting lineWidth and lineWidthPlus on hover with 0 value.
API Reference:
http://api.highcharts.com/highcharts/plotOptions.line.lineWidth
http://api.highcharts.com/highcharts/plotOptions.area.marker.states.hover.lineWidthPlus
Example:
https://jsfiddle.net/epwxacoa/

Horizontal Scrollbar for highcharts, NOT Highstock

I want to implement the scrollbar in highcharts, not highstock because it will cost additional money for my company (just for a scrollbar, does not make sense). I have tried this but apparently does not help me:
How to enable highcharts x and y axis scrollbars? .
There are some examples here:
http://jsfiddle.net/fj6d2/3076/
https://www.highcharts.com/blog/news/224-scrollbars-for-any-axis/
but with highstock, I want to do the same thing with Highchart.
From what I have found out Highcharts does not support scrollbars. If I just insert use overflow: scroll on a wrapped div of the chart, that would still make my title center in the middle of a long div and also the y axis will be hidden when I go to the right of that long div.
Is there any way to have ScrollBar with the above things on a highchart (NOT HIGHSTOCK) ?
Here is my option
let options = {
legend: {
itemStyle: {
fontWeight: 'bold',
fontSize: '13px'
},
// width: 780,
itemWidth: 130,
floating: false
},
xAxis: {
position: {align: 'left'},
text: null,
}, // ,
// tickLength: 0
type: 'category',
categories: categories,
min: 0// ,
// max: 10
},
navigator: {
enabled: false
},
scrollbar: {
enabled: true,
showFull: false,
barBackgroundColor: 'rgb(44,89,142)',
barBorderRadius: 0,
barBorderWidth: 0,
buttonBackgroundColor: 'rgb(44,89,142)',
buttonBorderWidth: 0,
buttonArrowColor: 'white'
},
yAxis: {
// minorTickInterval: 'auto',
title: {
/* style: {
textTransform: 'uppercase'
}*/
}, // ,
min: 0,
// max: 20,
},
// General
background: '#FFFFFF',
chart: {
height: 500,
width: 3900,
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
type: 'column',
backgroundColor: '#FFFFFF',
style: {
fontFamily: 'Lucida Grande, Lucida Sans Unicode, Arial, Helvetica,
sans-serif'
},
borderColor: '#ACB2BC',
borderWidth: 1,
events: { load: function fn() { console.log(this); /* this.width(800);
*/ } } // #container
},
plotOptions: {
bar: {
dataLabels: {
enabled: true
}
},
candlestick: {
lineColor: '#404048'
},
pie: {
dataLabels: {
enabled: true,
distance: -50,
style: {
fontWeight: 'bold',
color: 'white'
}
},
allowPointSelect: true,
cursor: 'pointer',
data: values,
showInLegend: true
}
},
series: [{
name: 'reports',
data: values
}],
credits: {
enabled: false
}
};
I am using React. I just pass the options to a Highcharts.
this.chart = new Highcharts['Chart'](
this.refs.chart,
this.props.options);
chart.scrollablePlotArea
Since Highcharts v7.1.2, a scrollable plot area can be defined for either horizontal or vertical scrolling, depending on whether the minWidth or minHeight option is set. This does NOT require Highcharts Stock (aka Highstock) to be used.
A demo from the API reference is here and below:
Highcharts.chart('container', {
chart: {
type: 'spline',
scrollablePlotArea: {
minWidth: 700,
scrollPositionX: 1
}
},
title: {
text: 'Scrollable plot area'
},
subtitle: {
text: 'Open on mobile and scroll sideways'
},
xAxis: {
type: 'datetime',
labels: {
overflow: 'justify'
}
},
yAxis: {
tickWidth: 1,
title: {
text: 'Wind speed (m/s)'
},
lineWidth: 1,
opposite: true
},
tooltip: {
valueSuffix: ' m/s',
split: true
},
plotOptions: {
spline: {
lineWidth: 4,
states: {
hover: {
lineWidth: 5
}
},
marker: {
enabled: false
},
pointInterval: 3600000, // one hour
pointStart: Date.UTC(2015, 4, 31, 0, 0, 0)
}
},
series: [{
name: 'Hestavollane',
data: [0.2, 0.8, 0.8, 0.8, 1, 1.3, 1.5, 2.9, 1.9, 2.6, 1.6, 3, 4, 3.6,
5.5, 6.2, 5.5, 4.5, 4, 3.1, 2.7, 4, 2.7, 2.3, 2.3, 4.1, 7.7, 7.1,
5.6, 6.1, 5.8, 8.6, 7.2, 9, 10.9, 11.5, 11.6, 11.1, 12, 12.3, 10.7,
9.4, 9.8, 9.6, 9.8, 9.5, 8.5, 7.4, 7.6]
}, {
name: 'Vik',
data: [0, 0, 0.6, 0.9, 0.8, 0.2, 0, 0, 0, 0.1, 0.6, 0.7, 0.8, 0.6, 0.2,
0, 0.1, 0.3, 0.3, 0, 0.1, 0, 0, 0, 0.2, 0.1, 0, 0.3, 0, 0.1, 0.2,
0.1, 0.3, 0.3, 0, 3.1, 3.1, 2.5, 1.5, 1.9, 2.1, 1, 2.3, 1.9, 1.2,
0.7, 1.3, 0.4, 0.3]
}]
});
#container {
max-width: 800px;
min-width: 320px;
height: 400px;
width: 400px;
}
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="container"></div>

Want to avoid spacing between each stacked bars in highcharts?

I am working with Highcharts and have come across a little problem that I am struggling to overcome.
I have created a jsfiddle so you can see my issue:
http://jsfiddle.net/jo_pappi/0e5h8sts/3/ [A]
As you can see
I can achieve the above format in highcharts, Since this chart is rendering based on dynamic data When a single group values arrives highcharts leaves so much space between the bars. Am attaching image here
And the code
$('#container-one').highcharts({
chart: {
type: 'bar',
events: {
click: function (event) {
console.log(event.pageX + ',' + event.pageY);
}
}
},
credits: {
enabled: false
},
title: {
text: 'Total fruit consumtion, grouped by gender'
},
xAxis: {
categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas'],
minPadding: 1.1,
maxPadding: 1.1
},
yAxis: {
allowDecimals: false,
min: 0,
title: {
text: 'Number of fruits'
}
},
tooltip: {
enabled: false,
formatter: function () {
return '<b>' + this.x + '</b><br/>' + this.series.name + ': ' + this.y + '<br/>' +
'Total: ' + this.point.stackTotal;
}
},
plotOptions: {
// column: {
// stacking: 'normal'
// }
series: {
pointWidth: 20,
stacking: 'normal',
borderWidth: 0,
events: {
click: function (event) {
//reloadFlash();
//$('#report').html('click on yAxis title');
console.log(event.pageX + ',' + event.pageY);
}
}
}
},
series: [{
name: 'John',
color: 'rgba(89,89,89,1)',
data: [5], // data: [5, 3, 4, 7, 4],
stack: 'male',
pointPadding: -0.0,
pointPlacement: -0.0
}, {
name: 'Joe',
color: 'rgba(255,95,215,1)',
data: [3], // data: [3, 4, 4, 2, 2],
stack: 'male',
pointPadding: -0.0,
pointPlacement: -0.0
}, {
name: 'Jane',
color: 'rgba(217,116,0,1)',
data: [2], // data: [2, 5, 6, 2, 1],
stack: 'female',
pointPadding: -0.0,
pointPlacement: -0.0
}, {
name: 'Janet',
color: 'rgba(155,215,255,1)',
data: [3], // data: [3, 0, 4, 4, 3],
stack: 'female',
pointPadding: -0.0,
pointPlacement: -0.0
}]
});
how can i reduce the spaces between bars?
If changing height of the chart is one solution means how can i achieve this dynamically?
Removing "pointWidth" solved the white space between the bars. But i need the bars should be off same height in all possible cases. I have solved the problem by setting height dynamically based on the categories count. say for example if am having only one category i have set the height for the chart as "210" and for 2 categories "270" like that. and removed pointWidth.
$('#container-one').highcharts({
chart: {
type: 'bar',
height: 210,
...
.
.
plotOptions: {
bar: {
pointPadding: 0,
borderWidth: 0
},
series: {
//pointWidth: 20,
stacking: 'normal',
.
.
});
When i have two categories i have set chart height as 270
$('#container-two').highcharts({
chart: {
type: 'bar',
height: 270,
...
.
.
plotOptions: {
bar: {
pointPadding: 0,
borderWidth: 0
},
series: {
//pointWidth: 20,
stacking: 'normal',
.
.
});
and the Fiddle Link
may be what i did was wrong. But its fixed my problem. correct me if am wrong.
Thanks all
The options you can use are:
plotOptions:{
bar:{
pointPadding: 0,
groupPadding: 0,
}
}
But you also need to not force your bar point width.
Remove:
series: {
pointWidth: 20,
http://jsfiddle.net/d9f8b22x/
The API docs discuss how these options relate to each other:
http://api.highcharts.com/highcharts#plotOptions.column.pointPadding
What are you using 'pointWidth: 20' in series for ?? That is creating the problem.. Also you are giving the categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas'] even if the data comes for only apples.. one solution would be to generate the categories dynamically.. say for example if data comes only for apples push only apples in the categories array. Then after that you can use :
_chart.setSize(width,height)
method to dynamically set the new height and width of the highchart. Also removing pointWidth will solve the problem ...

Categories

Resources