I am creating a dynamic updated highstock chart with 2 series but at start one series is rendering in wrong place. And when I resize the selection in navigator the series comes back to its correct place.
Here is the config of highstock:
Highcharts.setOptions({
global: {
useUTC: false
}
});
var groupingUnits = [['millisecond', [1, 2, 5, 10, 20, 25, 50, 100, 200, 500]],
['second',[1, 2, 5, 10, 15, 30]],
['minute',[1, 2, 5, 10, 15, 30]],
['day',[1]]
];
// Create the chart
Highcharts.stockChart('container', {
chart: {
events: {
load: function () {
// set up the updating of the chart each second
var series = this.series[0];
var series1 = this.series[1];
setInterval(function () {
var x = (new Date()).getTime(), // current time
y = Math.round(Math.random() * 100);
series.addPoint([x, y], true, false);
series1.addPoint([x, y], true, false);
}, 500);
}
}
},
rangeSelector: {
buttons: [{
count: 1,
type: 'minute',
text: '1min'
},
{
count: 3,
type: 'minute',
text: '3min'
}, {
count: 5,
type: 'minute',
text: '5min'
}, {
type: 'all',
text: 'All'
}],
inputEnabled: false,
selected: 3
},
exporting: {
enabled: false
},
title: {
text: 'Live Chart'
},
yAxis: [
{
labels: {
align: 'right',
x: -3
},
title: {
text: 'Line'
},
height: '60%',
lineWidth: 2,
resize: {
enabled: true
}
},
{
labels: {
align: 'right',
x: -3
},
title: {
text: 'Volume'
},
top: '65%',
height: '35%',
offset: 0,
lineWidth: 2
}],
tooltip: {
split: true
},
series: [
{
type: 'line',
name: 'OHLC',
data: [[]],
dataGrouping: {
units: groupingUnits
}
},
{
type: 'column',
name: 'Volume',
data: [[]],
yAxis: 1,
dataGrouping: {
units: groupingUnits
}
}
]
});
I have created a fiddle for the same:
https://jsfiddle.net/xu058sgp/23/
I have tried changing the height and top property of yAxis but nothing seems to fix this issue. I am not sure but it can be due to the frequency in which the data is getting updated.
Can someone point me out what I am doing wrong here.
As a workaround you could initialize the series and then remove the points before adding your own points.
Initialization:
series: [{
type: 'line',
name: 'OHLC',
data: [0], //added this 0
dataGrouping: {
units: groupingUnits
}
}, {
type: 'column',
name: 'Volume',
data: [0], //added this 0
yAxis: 1,
dataGrouping: {
units: groupingUnits
}
}]
Then, remove the points before adding new ones:
events: {
load: function () {
// set up the updating of the chart each second
var chart = this
var series = this.series[0];
var series1 = this.series[1];
//Remove 0 data
series.setData([], false); //false to avoid redrawing, so we only redraw once per update
series1.setData([], false);
//update graph
setInterval(function () {
var x = (new Date()).getTime(), // current time
y = Math.round(Math.random() * 100);
series.addPoint([x, y], false, false);
series1.addPoint([x, y], false, false);
//redraw graph
chart.redraw();
}, 500);
}
}
Working example: https://jsfiddle.net/ewolden/xu058sgp/46/
Related
Anyone know how to add treemap upon click event on line chart point? Here's my JSFiddle link:
https://jsfiddle.net/ssoj_tellig/d6pfv1bg/19/
When I click on the line chart on the point 0.63 at the third week of sample5, I'd like a treemap to appear at the bottom with the values loaded in var mytreemap_data (or any other values for the demo, doesn't matter). I'd like to understand how it'd work.
Many thanks for your help!
var mytreemap_data = [1528675200000,0.1,0.2,0.3,0.15,0.25]
// How can we show a tree map at the bottom with the values above
// upon clicking on the point 0.63 for the third week of sample 5 ??
const chart_1 = new Highcharts.stockChart('mychart_1', {
chart: {
zoomType: 'x',
type: 'spline',
},
xAxis: {
type: 'datetime',
tickInterval: 86400000 * 7, //show each week
ordinal: false,
labels:{
formatter: function() {
return Highcharts.dateFormat('%d %b %Y', this.value);
},
align: 'right',
rotation: -90,
},
},
yAxis: {
opposite: false,
min: 0,
max: 1,
tickInterval: 0.1,
title: {
text: 'Score'
}
},
legend: {
enabled: true,
layout: 'vertical',
align: 'right',
verticalAlign: 'top'
},
credits : {
enabled : false
},
navigator :{
enabled: true
},
scrollbar :{
enabled: true
},
rangeSelector: {
enabled: true,
allButtonsEnabled: true,
buttons: [{
type: 'month',
count: 1,
text: '1m'
}, {
type: 'all',
text: 'All'
}],
selected: 1
},
series: [{
name: 'sample1',
data: [[1527465600000,0.42242020440407213],[1528070400000,0.38747025807155444],[1528675200000,0.42678078180915674],[1529280000000,0.4091743882448146],
[1529884800000,0.4238743811604633],[1530489600000,0.39724984766613747],[1531094400000,0.39441610665405447],[1531699200000,0.41417484302834673],
[1532304000000,0.39208450506752085],[1532908800000,0.4026164523657783]],
}, {
name: 'sample2',
data: [[1527465600000,0.44242020440407213],[1528070400000,0.40747025807155444],[1528675200000,0.44678078180915674],[1529280000000,0.4291743882448146],
[1529884800000,0.4438743811604633],[1530489600000,0.41724984766613747],[1531094400000,0.41441610665405447],[1531699200000,0.43417484302834673],
[1532304000000,0.41208450506752085],[1532908800000,0.4226164523657783]],
}, {
name: 'sample3',
data: [[1527465600000,0.42242020440407213],[1528070400000,0.42747025807155444],[1528675200000,0.46678078180915674],[1529280000000,0.4491743882448146],
[1529884800000,0.4638743811604633],[1530489600000,0.43724984766613747],[1531094400000,0.43441610665405447],[1531699200000,0.45417484302834673],
[1532304000000,0.43208450506752085],[1532908800000,0.4426164523657783]],
}, {
name: 'sample4',
data: [[1527465600000,0.52242020440407213],[1528070400000,0.48747025807155444],[1528675200000,0.52678078180915674],[1529280000000,0.5091743882448146],
[1529884800000,0.5238743811604633],[1530489600000,0.49724984766613747],[1531094400000,0.49441610665405447],[1531699200000,0.51417484302834673],
[1532304000000,0.49208450506752085],[1532908800000,0.5026164523657783]],
}, {
name: 'sample5',
data: [[1527465600000,0.62242020440407213],[1528070400000,0.58747025807155444],[1528675200000,0.62678078180915674],[1529280000000,0.6091743882448146],
[1529884800000,0.6238743811604633],[1530489600000,0.59724984766613747],[1531094400000,0.59441610665405447],[1531699200000,0.61417484302834673],
[1532304000000,0.59208450506752085],[1532908800000,0.6026164523657783]],
}],
plotOptions: {
series: {
label: {
connectorAllowed: false,
},
pointstart: 1527465600000,
// pointInterval = 2,
tooltip: {
valueDecimals: 2
},
}
},
responsive: {
rules: [{
condition: {
maxWidth: 500
},
}]
}
});
document.getElementById('button').addEventListener('click', e => {
var series = chart_1.series[0];
var series1 = chart_1.series[1]
var series2 = chart_1.series[2];
if (series.visible & series1.visible & series2.visible) {
series.hide();
series1.hide();
series2.hide();
e.target.innerHTML = 'Show samples 1-3';
} else {
series.show();
series1.show();
series2.show();
e.target.innerHTML = 'Hide samples 1-3';
}
})
Use click event callback function for a point and create another chart with treemap series, for example:
plotOptions: {
series: {
point: {
events: {
click: function() {
Highcharts.chart('treemapContainer', {
series: [{
type: 'treemap',
data: mytreemap_data
}]
})
}
}
},
...
}
}
Live demo: https://jsfiddle.net/BlackLabel/rh7cfxLj/
API Reference: https://api.highcharts.com/highcharts/plotOptions.series.point.events.click
Below is the chart code, my problem is JSON needs to be used to grab updated data.
I dont want the whole chart to be re-render, but instead only the candles (add the new ones).
I guess there has to be a loop looking every sec in the new data by looping the JSON and create a chart.update?
Would love a answer from anyone with how i should solve this with code!
https://codeshare.io/alxOMZ
$.getJSON('/api/v1/public/getcharts?market=BTC-'+coinsymbol, function (data) {
// split the data set into trading and volume
var trading = [],
volume = [],
dataLength = data.length,
// set the allowed units for data grouping
groupingUnits = [[
'hour', // unit name
[1] // allowed multiples
], [
'day',
[1, 7]
]],
i = 0;
for (i; i < dataLength; i += 1) {
trading.push([
data[i][0], // the date
data[i][1], // open
data[i][2], // high
data[i][3], // low
data[i][4] // close
]);
volume.push([
data[i][0], // the date
data[i][5] // the volume
]);
}
// create the chart
Highcharts.stockChart('container', {
title: {
text: null
},
scrollbar: {
enabled: false
},
credits: {
enabled: false
},
chart: {
renderTo: 'container',
backgroundColor: 'none',
},
rangeSelector: {
selected: 2,
buttons: [{
type: 'hour',
count: 1,
text: '1h'
}, {
type: 'day',
count: 1,
text: '1D'
}, {
type: 'day',
count: 7,
text: '7D'
}, {
type: 'month',
count: 1,
text: '1M'
}, {
type: 'all',
count: 1,
text: 'All'
}],
selected: 5,
inputEnabled: false
},
legend: {
enabled: false
},
exporting: {
enabled: false
},
plotOptions: {
candlestick: {
lineColor: '#E75162',
upLineColor: '#5BB789',
upColor: '#5BB789',
color: '#E75162'
}
},
yAxis: [{
crosshair: {
snap: false
},
height: '100%',
resize: {
enabled: false
}
}, {
top: '100%',
height: '10%',
offset: 0
}],
tooltip: { enabled: false },
series: [
{
type: 'candlestick',
name: coinsymbol,
data: trading,
dataGrouping: {
units: groupingUnits
}
}, {
type: 'column',
name: coinsymbol+' Volume',
data: volume,
yAxis: 1,
dataGrouping: {
units: groupingUnits
}
}]
});
});
-----CODE-----
$.getJSON('/api/v1/public/getcharts?market=BTC-'+coinsymbol, function (data) {
// split the data set into trading and volume
var trading = [],
volume = [],
dataLength = data.length,
// set the allowed units for data grouping
groupingUnits = [[
'hour', // unit name
[1] // allowed multiples
], [
'day',
[1, 7]
]],
i = 0;
for (i; i < dataLength; i += 1) {
trading.push([
data[i][0], // the date
data[i][1], // open
data[i][2], // high
data[i][3], // low
data[i][4] // close
]);
volume.push([
data[i][0], // the date
data[i][5] // the volume
]);
}
// create the chart
Highcharts.stockChart('container', {
title: {
text: null
},
scrollbar: {
enabled: false
},
credits: {
enabled: false
},
chart: {
renderTo: 'container',
backgroundColor: 'none',
},
rangeSelector: {
selected: 2,
buttons: [{
type: 'hour',
count: 1,
text: '1h'
}, {
type: 'day',
count: 1,
text: '1D'
}, {
type: 'day',
count: 7,
text: '7D'
}, {
type: 'month',
count: 1,
text: '1M'
}, {
type: 'all',
count: 1,
text: 'All'
}],
selected: 5,
inputEnabled: false
},
legend: {
enabled: false
},
exporting: {
enabled: false
},
plotOptions: {
candlestick: {
lineColor: '#E75162',
upLineColor: '#5BB789',
upColor: '#5BB789',
color: '#E75162'
}
},
yAxis: [{
crosshair: {
snap: false
},
height: '100%',
resize: {
enabled: false
}
}, {
top: '100%',
height: '10%',
offset: 0
}],
tooltip: { enabled: false },
series: [
{
type: 'candlestick',
name: coinsymbol,
data: trading,
dataGrouping: {
units: groupingUnits
}
}, {
type: 'column',
name: coinsymbol+' Volume',
data: volume,
yAxis: 1,
dataGrouping: {
units: groupingUnits
}
}]
});
});
Looking at the highcharts api quickly on google, you may need an event property followed by load property, and your logic, which would probably include something like
chart: {
events: {
load: function () {
// here's how you would access your series
var series = this.series[0];
setInterval(function () {
//modify your series here.
}, 1000);
}
}
}
I am trying to split the data contained in a dict into multiple charts. Each chart has two series: column and marker. If represent all the data in a single chart, everything works fine, but if I try to split it, the columns and the marker don't get aligned for some reason
function setup_chart(chart_container){
return new Highcharts.chart(chart_container, {
chart: {
alignTicks: false,
type: 'columnrange',
inverted: true,
zoomType: 'y',
panning: true,
},
credits: {
enabled: false
},
title: {
text: null
},
xAxis: {
categories: [],
className: 'chart-axis-title',
title: {
align:'high'
},
offset: -10
},
navigation: {
buttonOptions: {
x: 5,
y: -12
}
},
yAxis:[{
minRange: 1,
max:null,
min:null,
allowDecimals: false,
title: {
text: 'Days'
},
labels:{
formatter:function(){
if(this.value !=0){
return this.value;
}
}
}
},{
tickPositions: [0, 100],
visible: false
}],
tooltip: {
},
exporting: {
scale: 3,
chartOptions: {
legend: {
enabled: true
}
}
},
legend: {
enabled: false
},
series: [{
yAxis: 1,
data:[]
},{
name: 'Days',
data: [],
stickyTracking: true
}]
});
}
I'm passing the data via jinja2 and populate the chart in the following way:
var options_data_cm = {{options|tojson|safe}}[k]['cms'];
var cm_groups = {{cm_group_dict}};
var cms_details = {};
for(var key in cm_groups){
cms_details[key] = {
"data":[],
"left":[],
"right":[],
"cols":[],
"categories":[]
}
}
for(var key in cms_details){
var crtChart = $('#'+key).highcharts();
crtChart.xAxis[0].update({title:{ text: ""+cm_groups[key] }});
crtChart.addSeries({
type: 'column',
yAxis: 1,
data: cms_details[key]['cols'],
zIndex: 1,
minPointLength: 10,
threshold: -0.1,
pointPadding: 0,
pointRange: 0,
groupPadding: 0,
showInLegend: false,
tooltip: {
pointFormat: false
},
states: {
hover: {
enabled: false
}
}
});
crtChart.addSeries({
name: "Study Days",
dataLabels: {
enabled: false,
padding: 10,
borderWidth: 0,
useHTML:false,
formatter:function(){
if(this.y != 0)
return this.y;
}
},
stickyTracking: false,
data: cms_details[key]['data'],
borderWidth: 0,
zIndex: 5,
maxPointWidth: 5,
tooltip:{
followPointer:true
},
point: {
events: {
click: function() {
if (url != "")
window.open(url,'_blank');
}
}
}
});
crtChart.addSeries({
type:'scatter',
stickyTracking:false,
tooltip:{snap:0},
data:cms_details[key]['left'],
zIndex: 1
});
crtChart.addSeries({
type:'scatter',
stickyTracking:false,
tooltip:{snap:0},
data:cms_details[key]['right'],
zIndex: 1
});
crtChart.xAxis[0].setCategories(cms_details[key]['categories']);
}
Here are two pictures, the first one is with assignment without breaking the data into multiple charts, the second one is an attempt to split it :
I've tried to inspect the content of the data and it seems OK in the sense that both have the same coordinates, however they are shifted.
EDIT:
Here's the link to the jsfiddle
I have managed to solve the issue by adding pointPlacement: 0.2 to the series which was displaced.
Here is my js code:
Highcharts.stockChart('utilizations', {
chart: {
zoomType: 'x'
},
title: {
text: 'KPI'
},
subtitle: {
text: 'CCE & PRB Utilization (%)'
},
rangeSelector: {
buttons: [{
type: 'day',
count: 1,
text: '1d'
}, {
type: 'day',
count: 3,
text: '3d'
}, {
type: 'day',
count: 7,
text: '1w'
}, {
type: 'day',
count: 14,
text: '2w'
}, {
type: 'all',
text: 'All'
}],
selected: 1
},
yAxis: {
labels: {
formatter: function () {return this.value + '%';}
},
max: 100,
min: 0,
tickInterval: 20,
plotLines: [{
value: 0,
width: 2,
color: 'silver'
},{
value: 70,
width: 1,
color: 'red'
}]
},
tooltip: {
crosshairs: true,
shared: true
},
plotOptions: {
series: {
compare: 'value',
showInNavigator: true
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'middle'
},
xAxis: {
type: 'datetime'
},
series: [{
name: 'CCE Util',
type: 'spline',
yAxis: 0,
data: (function(){
var data = [];
for (var i = 0; i < result.length; i++) {
var time = result[i]["time"];
var kpi = result[i]["cce"];
data.push([time, kpi]);
}
return data;
})(),
tooltip: {
valueSuffix: '%',
valueDecimals: 2,
split: true
}
},{
name: 'PRB Util',
type: 'spline',
yAxis: 0,
data: (function(){
var data = [];
for (var i = 0; i < result.length; i++) {
var time = result[i]["time"];
var kpi = result[i]["prb"];
data.push([time, kpi]);
}
return data;
})(),
tooltip: {
valueSuffix: '%',
valueDecimals: 2,
split: true
}
And my plot:
While dragging the navigator bar, sometimes the plot goes to the right position and sometimes it looks like the capture above. According to my experience, the plot position is related to the left end (let's note this as A) position of the navigator selector. When A is on the lowest part of the whole plot in navigator, the shown plot positioned well; and when A goes like the capture above, the plot shown sunk.
Please refer to a short demo with 100 data here: https://jsfiddle.net/ghqyvo0x/
How can I make my plot stable?
Your problem is caused by series.compare: property, which you set in plotOptions configuration object. If you delete this line of code, everything should work as you need. We could read in Highstock API:
Compare the values of the series against the first non-null, non- zero value in the visible range.
plotOptions: {
series: {
//compare: 'percent',
showInNavigator: true
}
}
JSFiddle example
API Reference
I am having a list name aaa. It is an list of list
aaa[0] = [[{'a',1},{'b',2}]
aaa[1] = [[{'q',2},{'bd',0}]
aaa[2] = [[{'sa',3},{'bs',6}]
aaa[2] = [[{'sa',5},{'vb',8}]
I got the response from the model
Now I need to populate this value into Chart
My Chart will contain four lines for aaa[0] ,aaa[1] ,aaa[2] ,aaa[3]
Here is my High Chart Code
<script>
$(document).ready(function () {
//Default time zone
moment.tz.setDefault("America/New_York");
// Global option to disable UTC time usage
Highcharts.setOptions({
global: {
useUTC: false
}
});
// Chart configurations
var options = {
chart: {
renderTo: 'container2',
type: 'area',
marginRight: 45,
zoomType: 'x'
},
title: {
text: 'aaaa'
},
xAxis: {
type: 'datetime',
minRange: 8 * 24 * 3600000,
labels: {
format: '{value:%m-%d-%Y}',
rotation: 45
}
},
yAxis: {
title: {
text: 'count'
},
labels: {
formatter: function () {
return this.value;
}
}
},
plotOptions: {
area: {
marker: {
enabled: true,
symbol: 'circle',
radius: 2,
states: {
hover: {
enabled: true
}
}
},
lineWidth: 1,
threshold: null
}
},
series: [{
fillOpacity: 0.1,
name: 'aaa',
pointInterval: 24 * 3600 * 1000,
pointStart: 1375295400000,
data: GetPercentage()
}]
};
// Rendering the Highcharts
chart = new Highcharts.Chart(options);
function GetPercentage() {
var data = #Html.Raw(JsonConvert.SerializeObject(Model.aaa));
// alert(data)
#foreach(var val in Model.aaa) //loop of getting a list from aaa
{
var percentages = [];
for (var x = 0; x < #val.Count; x++)
{
//Here I need to push the list
}
//percentages.sort(SortByDate);
// return percentages;
}
}
//Sort the array based on first array element
function SortByDate(a,b){
//alert(a[0] +" - " +b[0]);
return (a[0] - b[0]);
}
//Timeout function to reload page on everyone hour
setTimeout(function () {
location.reload(true);
}, 60* 60 * 1000);
//Progress bar to display feed delivery percentage
$('.progress .progress-bar').progressbar({
transition_delay: 500,
display_text: 'fill',
refresh_speed: 500
});
});
</script>
Could anyone help me to diplay a chart with four lines ?
Thanks in advance
Here you can see the series is an object array
$(function () {
$('#container').highcharts({
chart: {
type: 'bar'
},
title: {
text: 'Fruit Consumption'
},
xAxis: {
categories: ['Apples', 'Bananas', 'Oranges']
},
yAxis: {
title: {
text: 'Fruit eaten'
}
},
series: [{
name: 'Jane',
data: [1, 0, 4]
}, {
name: 'John',
data: [5, 7, 3]
}]
});
});
You should add more objects into series array to create more than one line.