Highcharts horizontal scroll - javascript

I'm new in highcharts and I'm trying to do a graphic with bars and a line. The bars represent the average of set values and the line represents the real value of the set.
I generated the set randomly with 100 values, but the graphic interface sees horrible when I run chart in Jsfiddle. I put a drag selection zoom but is not comfortable to use. Then I decided to put an horizontal scroll and I've seen in Stack Overflow posts that I must to include highstock.js, enable scrollbar and set parameter min and max to enable scroll scrolling. I did it and my chart works but without the scroll.
Link to the Chart: http://jsfiddle.net/zd12fa5L/2/
According to Jsfiddle, my HTML is:
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://code.highcharts.com/stock/highstock.js"></script>
<script src="https://code.highcharts.com/stock/modules/exporting.js"></script>
<div id="container" style="height: 400px"></div>
<div id="report"></div>
And the JSON is:
// create the chart
Highcharts.chart('container', {
chart: {
events: {
selection: function (event) {
var text,
label;
if (event.xAxis) {
text = 'min: ' + Highcharts.numberFormat(event.xAxis[0].min, 2) + ', max: ' + Highcharts.numberFormat(event.xAxis[0].max, 2);
} else {
text = 'Selection reset';
}
label = this.renderer.label(text, 100, 120)
.attr({
fill: Highcharts.getOptions().colors[0],
padding: 10,
r: 5,
zIndex: 8
})
.css({
color: '#FFFFFF'
})
.add();
setTimeout(function () {
label.fadeOut();
}, 1000);
}
},
zoomType: 'x'
},
title: {
text: 'Chart selection demo'
},
subtitle: {
text: 'Click and drag the plot area to draw a selection'
},
xAxis: {
min: 0,
max:9,
categories: ['Subject1','Subject2','Subject3','Subject4','Subject5','Subject6','Subject7','Subject8','Subject9',
'Subject10','Subject11','Subject12','Subject13','Subject14','Subject15','Subject16','Subject17',
'Subject18','Subject19','Subject20','Subject21','Subject22','Subject23','Subject24','Subject25',
'Subject26','Subject27','Subject28','Subject29','Subject30','Subject31','Subject32','Subject33',
'Subject34','Subject35','Subject36','Subject37','Subject38','Subject39','Subject40','Subject41',
'Subject42','Subject43','Subject44','Subject45','Subject46','Subject47','Subject48','Subject49',
'Subject50','Subject51','Subject52','Subject53','Subject54','Subject55','Subject56','Subject57',
'Subject58','Subject59','Subject60','Subject61','Subject62','Subject63','Subject64','Subject65',
'Subject66','Subject67','Subject68','Subject69','Subject70','Subject71','Subject72','Subject73',
'Subject74','Subject75','Subject76','Subject77','Subject78','Subject79','Subject80','Subject81',
'Subject82','Subject83','Subject84','Subject85','Subject86','Subject87','Subject88','Subject89',
'Subject90','Subject91','Subject92','Subject93','Subject94','Subject95','Subject96','Subject97',
'Subject98','Subject99','Subject100']
},
scrollbar: {
enabled: true
},
series: [{
type: 'column',
name: 'Average',
data: [514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0,514.0 ]
},
{
name: 'Value',
data: [11.0,11.0,118.0,126.0,131.0,142.0,159.0,172.0,178.0,181.0,182.0,186.0,189.0,206.0,218.0,219.0,221.0,238.0, 256.0,260.0,272.0,282.0,283.0,300.0,317.0,337.0,351.0,360.0,404.0,424.0,425.0,438.0,446.0,456.0,462.0,
464.0,468.0,469.0,479.0,488.0,494.0,501.0,501.0,503.0,504.0,516.0,518.0,519.0,522.0,530.0,531.0,533.0,
534.0,537.0,549.0,563.0,565.0,573.0,577.0,599.0,608.0,631.0,638.0,641.0,649.0,668.0,674.0,68.0,68.0,
683.0,7.0,727.0,735.0,748.0,749.0,771.0,782.0,783.0,799.0,831.0,839.0,844.0,847.0,847.0,854.0,86.0,867.0,
873.0,888.0,891.0,894.0,896.0,898.0,910.0,918.0,938.0,944.0,963.0,981.0,999.0
]
}]
});
Thank you, regards.

Read Scrollbars for any axis
Include only <script src="https://code.highcharts.com/stock/highstock.js"></script> and remove <script src="https://code.highcharts.com/highcharts.js"></script>. Then scrollbar will appear.
Fiddle demo

Related

Too many categories to display on column chart with vue-apexchart

i have a big data set to display ( around 150 category) with a library named vue-apexchart my problem is that i cant find a way to make the graph scrollable on xaxis without having a broken display the following image will explain my problem better
as you can see having too many categories leads to an unreadable chart
can you please help me
i have tried to make a scrollable div, the probleme still remains ( unreadable xaxis )
here's my chartOptions object :
chartOptions: {
chart: {
type: "bar",
height: 350,
},
plotOptions: {
bar: {
horizontal: false,
columnWidth: "55%",
endingShape: "rounded",
},
},
dataLabels: {
enabled: false,
},
stroke: {
show: true,
width: 2,
colors: ["transparent"],
},
xaxis: {
categories: [],
},
fill: {
opacity: 1,
},
},
I think there are two strategies that you could adopt here. In my opinion, the second one is better.
1. Horizontal bar chart
If you do not have strict constraints in terms of UX/UI, a possible solution might be to switch both axes...
plotOptions: {
bar: {
horizontal: true
}
},
... and give your chart much more height:
chart: {
type: 'bar',
height: 2500,
},
Doing that would allow you to use the natural vertical scrolling of your browser.
let data = [];
for (let i = 1; i <= 150; i++) {
data.push({x: `Category ${i}`, y: i});
}
let options = {
series: [{
name: 'Series',
data
}],
chart: {
type: 'bar',
height: 2500
},
yaxis: {
labels: {
style: {
fontSize: '10px'
},
offsetY: 3
}
},
plotOptions: {
bar: {
horizontal: true
}
},
dataLabels: {
enabled: false
}
};
let chart = new ApexCharts(document.querySelector('#chart'), options);
chart.render();
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
<div id="chart"></div>
All categories are visible. This is not very handy, though.
2. Zoom, pan and tick settings
Zooming and panning are useful features. They are available by default in the toolbar, but this toolbar does not appear immediately when your xaxis has categories. To enable the toolbar in this case, you have to change xaxis.tickPlacement from 'between' to 'on' (see Zoom on Category Bar Charts – ApexCharts.js).
Since you have a lot of categories, it is also a good idea to limit the number of visible labels with xaxis.tickAmount.
xaxis: {
tickPlacement: 'on',
tickAmount: 25
},
Thanks to the zoomX() method, you can decide to display your chart with only a subset of your data. The rest is still accessible via zooming and/or panning.
let data = [];
for (let i = 1; i <= 150; i++) {
data.push({x: `Category ${i}`, y: i});
}
let options = {
series: [{
name: 'Series',
data
}],
chart: {
type: 'bar',
height: 350
},
xaxis: {
tickPlacement: 'on',
tickAmount: 25
},
dataLabels: {
enabled: false
}
};
let chart = new ApexCharts(document.querySelector('#chart'), options);
chart.render();
chart.zoomX(37, 71);
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
<div id="chart"></div>

Highchart column animation when adding new column

I'm trying to make a simple bar chart that updates every 5 seconds using highchart. Below is my code:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="underscore-min.js"></script>
</head>
<body>
<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
</body>
<script>
Highcharts.chart('container', {
chart: {
type: 'column'
},
title: {
text: 'Activity Count per Model'
},
xAxis: {
categories: [],
crosshair: true,
title: {
text: 'Model'
}
},
yAxis: {
min: 0,
title: {
text: 'Activity Count'
}
},
plotOptions: {
column: {
animation: true,
pointPadding: 0.2,
borderWidth: 0
}
},
series: [{
name: 'Count',
data: []
}]
});
setInterval(function(){
$.getJSON("http://localhost/getdata.php", function(data){
$('#container').highcharts().series[0].setData(data.value,true);
$('#container').highcharts().xAxis[0].setCategories(data.model);
});
}, 5000);
</script>
</html>
The data returned from JSON call:
{"model":["a","aa","aaa","aaaa","aab","b","c","d","e"],"value":[40,20,70,40,70,20,30,40,50]}
Right now functionally the code works fine (chart shows up with the data updated every 5 second). The problem is that if the chart updates with new column, there's no animation on it. But if the existing data is updated without adding new column, there's animation in it (column growing up / shrinking, other column adjust if axis change). How do I enable the animation when new column is inserted into the chart?
In that case there are different possibilities how the chart should be animated. So you should consider what animation you'd want to.
From setData() docs:
When the updated data is the same length as the existing data, points will be updated by default, and animation visualizes how the points are changed.
IN your case you can split your data in two parts - the new point and the rest data. The rest data can be set with setData() - and you will preserve the animation because the old and new data have same length. And the point can be added with animation via addPoint().
$('#button').click(function () {
const data = new Array(12).fill(2)
chart.xAxis[0].setCategories(categories.concat('13'), false);
chart.series[0].setData(data);
chart.series[0].addPoint(40, true, false, true);
});
example: http://jsfiddle.net/Lqy2e42h/

Technique to use to reduce the number of javascript lines to write

i am making a web page where i am having many graphs like the ones here
http://vz.comxa.com/v2/
I am using highcharts JavaScript charting library. To make one chart you write the code like shown here http://jsfiddle.net/gh/get/jquery/1.9.1/highslide-software/highcharts.com/tree/master/samples/highcharts/demo/line-time-series/
$(function () {
$.getJSON('https://www.highcharts.com/samples/data/jsonp.php?filename=usdeur.json&callback=?', function (data) {
$('#container').highcharts({
chart: {
zoomType: 'x'
},
title: {
text: 'USD to EUR exchange rate over time'
},
subtitle: {
text: document.ontouchstart === undefined ?
'Click and drag in the plot area to zoom in' : 'Pinch the chart to zoom in'
},
xAxis: {
type: 'datetime'
},
yAxis: {
title: {
text: 'Exchange rate'
}
},
legend: {
enabled: false
},
plotOptions: {
area: {
fillColor: {
linearGradient: {
x1: 0,
y1: 0,
x2: 0,
y2: 1
},
stops: [
[0, Highcharts.getOptions().colors[0]],
[1, Highcharts.Color(Highcharts.getOptions().colors[0]).setOpacity(0).get('rgba')]
]
},
marker: {
radius: 2
},
lineWidth: 1,
states: {
hover: {
lineWidth: 1
}
},
threshold: null
}
},
series: [{
type: 'area',
name: 'USD to EUR',
data: data
}]
});
});
});
and the html
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
Since my charts are placed in modals,does it mean i must have the javascript for each chart in the page header. Due to the sheer number of charts involved,i reckon that's be a lot of JavaScript. What technique can i use to reduce the lines of javascript i will write?.
When building multiple charts you can reuse same options. One way could be to use Highcharts.merge function to add new options to the common ones.
Demo with Highcharts.merge in use - 2 charts: http://jsfiddle.net/gh/get/jquery/1.9.1/highslide-software/highcharts.com/tree/master/samples/highcharts/demo/gauge-solid/
More complex option could be to create a custom series type with changed default options and optionally more features if required.
Demo - Sprakline: http://jsfiddle.net/gh/get/jquery/1.9.1/highslide-software/highcharts.com/tree/master/samples/highcharts/demo/sparkline/

How to toggle legend layout in highchart

I am interested to change legend layout on click event as below
1st click horizontal - bottom
2nd click horizontal top
3rd click virtical left
4th click virtical right
Here is Link to FIDDLE
I don't know how this can be done, this is what I have tried so far.
HTML
<script src="http://code.highcharts.com/highcharts.js"></script>
<div id="container" style="height: 400px"></div>
<input id='legend' type='button' value='toggle legend'>
JAVASCRIPT
$(function () {
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
zoomType: 'xy',
marginLeft: 50,
marginBottom: 90
},
yAxis: {
reversed: true,
//min: 0,
//max: 50
},
plotOptions: {
series: {
stacking: 'normal'
}
},
xAxis: {
opposite: true
},
series: [{
name: '01-Jan-2014',
data: [
[28, 10],
[30, 0]
]
}]
});
var last = 0;
$('#legend').click(function(){
var arr = ['vertical','horizontal'];
if(last>arr.length){last=0;}
setTimeout(function() { alert(arr[last++]);},10);
chart.series[0].update({ legend: { layout: arr[last] }});
});
});
Here's a way to do it here. I hate resorting to setting the internal dirty flags but it seems to work well:
var somePositions = [['center','bottom'],
['center','top'],
['left','middle'],
['right','middle']];
$('#btn').click(function(){
posIdx++;
if (posIdx == 4) posIdx = 0;
chart.legend.options.align = somePositions[posIdx][0];
chart.legend.options.verticalAlign = somePositions[posIdx][1];
chart.isDirtyLegend = true;
chart.isDirtyBox = true;
chart.redraw();
});
You need to use tranlsate() function which allows to move SVG elements like legend.
var legend = chart.legend.group;
$('#btn').click(function(){
legend.translate(0,0)
});
http://jsfiddle.net/F3cSa/1/

Highcharts stacking bar chart border not displaying on right side

When I create a stacking bar chart, the rightmost 'box' doesn't have the border drawn on the right hand side.
Is there an option or something that I can set in Highcharts to force the white border line to be drawn around the 75% box in the image seen below?
Here is a link to the jsfiddle I used for testing:
http://jsfiddle.net/zKgsF/
Please note: Setting the borderWidth property to higher than 1 works in displaying, but the rightmost border is much thinner than the others. See the image below.
Here is the javascript for the chart:
$(function () {
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'bar',
backgroundColor: 'rgba(0,0,0,.3)',
margin: [15,6,15,15],
},
xAxis: {
categories: ['']
},
credits: {
enabled: false
},
yAxis: {
gridLineColor: "#FF0000",
labels:
{
align: 'right',
formatter: function()
{
return this.value + "%";
}
},
},
tooltip: {
formatter: function()
{
return "<b>" + this.series.name + '</b>: ' + this.y + ' (' + Math.round(this.percentage,1) + "%)";
}
},
plotOptions: {
bar: {
animation: false,
stacking: 'percent',
borderWidth: '1',
dataLabels: {
enabled: true,
color: 'white',
formatter: function() {
if (this.percentage < 10)
{
return ""
}
else
{
return Math.round(this.percentage,1) + "%";
}
},
style: {
fontSize: '18px'
}
}
}
},
series: [{
data: [30]
},{
data: [10]
}]
});
});
EDIT:
Looks like it's not related to the bar chart being "stackable". It might just be related to the fact that the chart goes to the max 'y' value axis... as seen here in another example: http://jsfiddle.net/zKgsF/1/
As suggested by Cubbuk, you can tweak it with by adding the max value of yAxis.
In addition, you can specify a endOnTick property too.
max: 100.1,
endOnTick: false
For API navigate here and for here is an example.

Categories

Resources