Why Highcharts Animation choppy on mobile device? - highcharts

I'm making a HTML5 hybrid app for android with Highcharts for my dashboard page.
There are 3 charts in this page, and only less than 10 points in each chart.
The init animation looks smoothly on PC browser(include chrome & firefox), but very choppy on my mobile device(Nexus 7 and MSM8916 CPU phone).
Even i set duration to 2000, it's still choppy.
With jQuery 2.1.3 and Hightcharts 4.1.5.
Could someone tell me the reason and how to improve the performance of Highcharts animation on mobile device?
html code below, i use jquery mobile 1.4.5 for UI framework.
<div data-role="page" data-title="总览" id="overall-page">
<div role="main" class="ui-content no-margin">
<div class="border-chart" id="hdgjChart"></div>
<div class="border-chart" id="sbzxlChart"></div>
<div class="border-chart" id="lsgjChart"></div>
</div>
</div>
js code below:
$(document).on("pageshow", "#overall-page", function() {
// Draw first Charts.
$('#hdgjChart').highcharts({
credits: {
enabled: false
},
chart: {
type: 'column',
//pinchType: 'xy',
//zoomType: 'xy',
//panning: true
},
title: {
text: '活动告警',
align: 'left',
margin: 0,
style: { "color": "#004488", "fontSize": "16px" }
},
legend: {
enabled: false
},
xAxis: {
labels: {
enabled: false
},
tickLength: 0
},
yAxis: {
labels: {
enabled: false
},
stackLabels: {
style: {
color: "#004488"
},
enabled: true
},
title: {
text: null
},
tickAmount: 8
},
plotOptions: {
column: {
stacking: 'normal',
animation: {
duration: 2000
}
}
},
tooltip: {
headerFormat: '<span style="font-size: 10px">{point.key}</span><br/>'
},
series: [{
name: '数目',
data: [
{
y: 381,
color: "#f00505",
name: "一级告警"
},
{
y: 25,
color: "#f46700",
name: "二级告警"
},
{
y: 652,
color: "#ffcf05",
name: "三级告警"
},
{
y: 72,
color: "#22a5f2",
name: "四级告警"
}]
}]
});
// Draw second chart
$('#sbzxlChart').highcharts({
credits: {
enabled: false
},
chart: {
type: 'pie',
spacingBottom: 0
},
title: {
text: '<span style="color:#004488;font-size:16px">设备在线率</span><span style="color:#004488;font-size:12px">--总设备数:78</span>',
align: 'left',
margin: 0
},
tooltip: {
pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
},
legend: {
align: 'right',
verticalAlign: 'top',
floating: true,
itemDistance: 10,
borderRadius:3,
borderWidth: 1
},
plotOptions: {
pie: {
dataLabels: {
enabled: true,
format: '{point.y}个,{point.percentage:.1f} %',
style: {
color: "#004488"
}
},
innerSize: '50%',
point: {
events: {
legendItemClick: function(e) {
e.preventDefaut();
}
}
},
animation: {
duration: 2000
}
}
},
series: [{
name: '数目',
data: [
{
y: 31,
color: "#00ff00",
name: '在线'
},
{
y: 47,
color: "#959595",
name: '中断'
}
],
showInLegend: true
}]
});
// Draw third chart
$('#lsgjChart').highcharts({
credits: {
enabled: false
},
chart: {
type: 'areaspline',
spacingBottom: 0,
//pinchType: 'x',
//zoomType: 'x',
//panning: true
},
title: {
text: '<span style="color:#004488;font-size:16px">历史告警数量</span><span style="color:#004488;font-size:12px">--最近7天</span>',
align: 'left',
margin: 7
},
tooltip: {
headerFormat: "",
pointFormat: '{point.y}'
},
legend: {
align: 'right',
verticalAlign: 'top',
floating: true,
borderRadius:3,
borderWidth: 1
},
xAxis: {
gridLineWidth: 1,
tickAmount: 7,
tickInterval: 1
},
yAxis: {
stackLabels: {
enabled: true,
useHTML: true,
y: -12,
formatter: function() {
return '<span style="background-color:#0d61be;color:white;font-weight:normal">' + this.total + '</span>';
}
},
title: {
text: null
},
tickAmount: 7
},
plotOptions: {
areaspline: {
stacking: 'normal',
pointStart: 1,
color: '#0d61be',
events: {
legendItemClick: function(e) {
e.preventDefault();
}
},
animation: {
duration: 2000
}
}
},
series: [{
name: '总告警数',
data: [150, 450, 300, 550, 300, 300, 100]
}]
});
});

When I made a simple highcharts test html page, and run it on mobile chrome browser, it runs smoothly.
But when simple packaged it to hybrid android app, using OS WebView & Crosswalk, It runs choppy still.(intel XDK)
I tested a canvas based js chart lib, Chart.js, It's choppy also when hybrid app.
So, I think it's the problem of VebView or Phonegap.
I'm finding the reason now, and will update the issue when I solved it.
Thanks all.

Related

How to detect when dataLabels are overlapping and adjust them programmatically

I have a stacked column/scatter chart with some dataLabels off to one side. The issue I am facing is that when my two markers begin to get close to one another, their dataLabels overlap
I need to always show both labels, so is there a way to detect when labels are overlapping and move the bottom one down by adjusting its y value based on how much overlap there is?
sample fiddle of the issue
Highcharts.chart('container', {
chart: {
type: 'column',
width: 500
},
title: {
text: 'Stacked column chart'
},
xAxis: {
visible: false,
},
yAxis: {
min: 0,
visible: false,
title: {
},
},
legend: {
layout:"vertical",
align: "right",
verticalAlign: "bottom",
itemMarginTop: 15,
y: -10,
x: -50
},
tooltip: {
enabled: false,
},
plotOptions: {
scatter: {
marker: {
symbol: "triangle",
},
dataLabels: {
enabled: true,
x: -80,
y: 50,
allowOverlap: true,
useHTML: true,
}
},
column: {
pointWidth: 70,
stacking: 'normal',
dataLabels: {
enabled: false
}
}
},
series: [{
name: '',
data: [100],
color: "#ededed"
}, {
name: '',
data: [500]
}, {
name: '',
data: [400]
},
{
type: "scatter",
data: [1000],
color: "#000",
dataLabels: {
formatter: function(){
return "<div class='label-text'>Your goal of <br/>$"+ this.y +"<br/>text</div>"
},
}
},
{
type: "scatter",
data: [900],
color: "#000",
dataLabels: {
formatter: function(){
return "<div class='label-text'>You are here <br/>$"+ this.y +"<br/>text</div>"
},
}
}]
});
You can correct data-labels positions by using the attr method on their SVG elements.
For example:
chart: {
events: {
render: function() {
const series = this.series;
const dl1 = series[3].points[0].dataLabel;
const dl2 = series[4].points[0].dataLabel;
if (dl1.y + dl1.height > dl2.y) {
dl2.attr({
y: dl1.y + dl1.height
});
}
}
}
}
Live demo: https://jsfiddle.net/BlackLabel/5Lmh4owb/
API Reference:
https://api.highcharts.com/class-reference/Highcharts.SVGElement.html#attr
https://api.highcharts.com/highcharts/chart.events.render

How to label xAxis with series data using Highcharts?

I'm newbie to highchart and I've got a demo for polar chart using highcharts
Highcharts.chart('container', {
chart: {
polar: true,
type: 'area'
},
accessibility: {
description: 'ASDFR'
},
title: {
text: '',
x: -120
},
pane: {
size: '100%',
startAngle:-42
},
xAxis: {
categories: ['ATT', 'TEC', 'TAC', 'DEF', 'CRE'],
tickmarkPlacement: 'on',
lineWidth: 0,
labels:{
formatter: function(){
return this.value + '???'
}
}
},
yAxis: {
gridLineInterpolation: 'polygon',
},
tooltip: {
shared: true,
pointFormat: '<span style="color:{series.color}">{series.name} <b>{point.y:,.0f}</b></span>'
},
legend: {
align: 'right',
verticalAlign: 'middle',
layout: 'vertical'
},
series: [{
name: '',
data: [73, 80, 80, 54, 92],
}],
responsive: {
rules: [{
condition: {
maxWidth: 500
},
chartOptions: {
legend: {
align: 'center',
verticalAlign: 'bottom',
layout: 'horizontal'
},
pane: {
size: '70%'
}
}
}]
}
});
How can I show the value of the series right in the xAxis label e.g ATT 73, TEC 80, TAC 80...
You can get the associated value through series data. Example:
xAxis: {
...,
labels: {
formatter: function() {
return this.value + ' ' + this.chart.series[0].yData[this.pos];
}
}
}
Live demo: https://jsfiddle.net/BlackLabel/pyohzk8c/
API Reference: https://api.highcharts.com/highcharts/xAxis.labels.formatter

Highcharts how to add an extra value to a bar

The goal is to make a bar chart like this one in the picture showing the values in percentage but also in MillionTonnes:
The bars are representing the percentage value. The value of the million tonnes is just extra information. Both values can go at the end of the bar and the percentage should appear first and then the Million Tonnes value. Something like:
49% (49.6 Million Tonnes). How can I make this two values appear at the end of the bar? This is the code I have. TIA
Highcharts.chart('grafica1', {
chart: {
type: 'column',
inverted: true,
plotBackgroundColor: null,
plotBorderWidth: 0,
plotShadow: false
},
title: {
text: ' '
},
xAxis: {
type: 'category',
labels: {
useHTML: true
}
},
yAxis: {
min: 0,
max: 100,
title: {
text: null,
},
labels: {
enabled: false,
}
},
legend: {
enabled: false
},
tooltip: {
enabled: false
},
plotOptions: {
series: {
borderWidth: 0,
dataLabels: {
enabled: true,
format: '({point.y:.1f} Million tones)%'
}
}
},
responsive: {
rules: [{
condition: {
maxWidth: 500
},
chartOptions: {
chart: {
inverted: false
},
legend: {
align: 'center',
verticalAlign: 'bottom',
layout: 'horizontal'
}
}
}]
},
series: [{
name: 'Production',
colorByPoint: true,
data: [{
name: 'PACKAGING PAPERS<br>AND BOARDS',
y: 49,
color: '#005eb8',
}, {
name: 'CASE MATERIALS',
y: 29.9,
color: '#fff',
borderWidth: 2,
borderColor: '#005eb8'
}, {
name: 'OTHER PACKAGING & PAPER',
y: 14.4,
color: '#fff',
borderWidth: 2,
borderColor: '#005eb8'
}, {
name: 'WRAPPINGS',
y: 4.7,
color: '#fff',
borderWidth: 2,
borderColor: '#005eb8'
}]
}]
});
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="grafica1" class="chart1Slide2"></div>
When using the stacking option (Doc) it's possible.
Here a working fiddle

Highcharts change legend of only last stacked value

I have a highchart, as showed on the appended image.
I am attempting to format the legend of only my last data stacked. In this case, index 1 always.
Any help on how to achieve this?
My main goal, being, on there always showing a value i have in a variable, which will be the max value possible.
createChart: function (id, chartData, maxYValues, chartTitle, chartNames, dataToMax) {
var me = this;
debugger;
me.highChart = new Highcharts.Chart({
chart: {
type: 'column',
renderTo: id
},
title: {
text: chartTitle,
fontSize: '8px'
},
xAxis: {
labels: {
overflow: 'justify'
},
categories: chartNames
},
yAxis: {
gridLineWidth: 0,
minorGridLineWidth: 0,
labels: {
enabled: false
},
stackLabels: {
enabled: true,
format: maxYValues
},
title: {
enabled: false
}
},
colors: ['#afafaf', '#f89c1c', '#3aaa80'],
credits: {
enabled: false
},
tooltip: {
pointFormat: '<span>{point.name}</span>'
},
plotOptions: {
series: {
colors: ['#3aab80', '#3aab80'],
colorByPoint: true,
borderWidth: 0,
dataLabels: {
enabled: true,
headerFormat: '{point.y + point.name}',
format: '{y} mb',
verticalAlign: 'top',
y: -20
}
},
column: {
stacking: "percent"
},
area: {
dataLabels: {
enabled: false
}
}
},
legend: {
labelFormat: '<b>{point.y} MB</b><br/>',
labelFormatter: function () {
if (me.series.data.index === 1) {
return maxYValues;
}
}
},
series: [{
showInLegend: false,
data: chartData,
color: '#3aab80'
}, {
showInLegend: false,
data: dataToMax,
legend: {
labelFormat: maxYValues + 'MB</b><br/>'
}
}],
navigation: {
menuItemStyle: {
fontSize: '8px'
}
}
});
},
Thank you
UPDATE: Added code snipped, and updated the image to what my current code is showing

Reduce gap between series data in Bar Highchart

I want to reduce space between bar chart series data. Below mentioned is the image which gives a clear picture :
Can anyone suggest the best approach to do it?
$(function () {
$('#container').highcharts({
chart: {
type: 'bar'
},
title: {
text: 'Historic World Population by Region'
},
subtitle: {
text: 'Source: Wikipedia.org'
},
xAxis: {
categories: ['Africa', 'America', 'Asia', 'Europe', 'Oceania'],
title: {
text: null
}
},
yAxis: {
min: 0,
title: {
text: 'Population (millions)',
align: 'high'
},
labels: {
overflow: 'justify'
}
},
tooltip: {
valueSuffix: ' millions'
},
plotOptions: {
bar: {
dataLabels: {
enabled: true
}
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
x: -40,
y: 100,
floating: true,
borderWidth: 1,
backgroundColor: '#FFFFFF',
shadow: true
},
credits: {
enabled: false
},
series: [{
name: 'Year 1800',
data: [107, 31, 635],
pointWidth: 22,
}, {
name: 'Year 1900',
data: [133, 156, 947],
pointWidth: 22
}]
});
});
http://jsfiddle.net/fMdk3/5/
The options you want to play with are pointPadding (padding between bars) and groupPadding (padding between seies).
e.g.
plotOptions: {
series: {
pointPadding: 0,
groupPadding: 0.1,
}
},
e.g. http://jsfiddle.net/BZzWQ/

Resources