This is in connection with my previous post (Add design to plotLabel Highcharts), Is there a way to make renderer.label responsive? see my screenshot below for further details. Here is the jsfiddle http://jsfiddle.net/x8vhp0gr/
plotlabel = yAxis.plotLinesAndBands[0].label;
plotbandLabel.animate({
y: yAxis.toPixels(y) - labelOffset
}, {
duration: 400,
step: function() {
this.attr({
text: yAxis.toValue(this.y + labelOffset).toFixed(2)
})
},
complete: function() {
this.attr({
text: y.toFixed(2)
})
}
}),
plotLine.animate({
translateY: newY
}, 400);
Related
Is there a way to update specific xAxis label when a user wants to print the chart?
This is the initial chart (inverted column with custom styles). I created xAxis labels with formatter function
xAxis: {
arrowOnEnd: true,
labels: {
x: 40,
formatter: function() {
if (this.isLast) { return 'Less Likely' }
if (this.isFirst) { return 'More Likely' }
}
},
and was able to position them so it looks like inverted xAxis has values from Less likely to More likely as follows
events: {
load: function() {
// https://stackoverflow.com/questions/51656849/xaxis-point-specific-label-positions
const chart = this;
Highcharts.objectEach(chart.xAxis[0].ticks, function(tick: any) {
if (!tick.isNewLabel && tick.isFirst) { tick.label.attr({ y: 25 })}
if (!tick.isNewLabel && tick.isLast) { tick.label.attr({ y: 590 })}
});
},
The problem I have is when I want to print the chart:
xAxis labels gets back to its original location.
I tried to replicate events: { load: ... } logic in beforePrint or wrapping 'print' event to highcharts object, but that doesn't seem to take any effect
beforePrint: function() {
const chart = this;
Highcharts.objectEach(chart.xAxis[0].ticks, function(tick: any) {
if (tick.isFirst) { tick.label.attr({ y: 125 })}
if (tick.isLast) { tick.label.attr({ y: 590 })}
});
}
Highcharts.wrap(Highcharts.Chart.prototype, 'print', function (proceed) {
const chart = this;
Highcharts.objectEach(chart.xAxis[0].ticks, function(tick: any) {
if (tick.isFirst) { tick.label.attr({ y: 25 })}
if (tick.isLast) { tick.label.attr({ y: 590 })}
});
proceed.call(this)
});
I tried tickPositionier but couldn't actually work out how to make that work.
Worth to mention. that afterPrint event with the same logic resets the chart, so I don't understand why one event is working (afterPrint) but the other doesn't (print)
afterPrint: function() {
const chart = this;
Highcharts.objectEach(chart.xAxis[0].ticks, function(tick: any) {
if (tick.isFirst) { tick.label.attr({ y: 25 })}
if (tick.isLast) { tick.label.attr({ y: 590 })}
});
},
Am I missing something here? Why I can't update tick position for printing?
Sidenote - jsfiddle gives me 502 Bad Gateway so I'm unable to demo it there
Changing the load event to render should fix the issue when the chart will be initialized again before the print.
Demo: https://jsfiddle.net/BlackLabel/4qbp1w0z/
chart: {
type: 'bar',
events: {
render: function() {
// https://stackoverflow.com/questions/51656849/xaxis-point-specific-label-positions
const chart = this;
Highcharts.objectEach(chart.xAxis[0].ticks, function(tick) {
if (!tick.isNewLabel && tick.isFirst) {
tick.label.attr({
y: 20
})
}
if (!tick.isNewLabel && tick.isLast) {
tick.label.attr({
y: 350
})
}
});
},
}
},
API: https://api.highcharts.com/highcharts/chart.events.render
Code is as below
chart: {
type: "funnel",
marginBottom: 25,
backgroundColor: "transparent",
events: {
load: function() {
var chart = this;
Highcharts.each(chart.series[0].data, function(p, i) {
chart.options.labels.items.push({
html: "less confident" + i,
style: { left: 550, top: 50 }
});
p.dataLabel.attr({
x: (chart.plotWidth - chart.plotLeft) / 2,
"text-anchor": "middle"
});
});
}
}
},
I see that you're trying to add a label for every point. Highcharts has build in functionality for this called data labels: https://api.highcharts.com/highcharts/series.line.dataLabels
Another approach is to use SVGRenderer.label: https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#label
I want to create a chart that reads its data from an Api. To do that i have this fiddle http://jsfiddle.net/68oe1oLf/69/
Note: https://jsfiddle.net/68oe1oLf/69/ will lead to mixed content error and will fail to load data from the api
This is the javascript code
$(document).ready(function () {
$.get( "http://firmbridgecapital.com/live.php", function( dt ) {
localStorage.setItem("data", dt);
});
window.setInterval(function(){
$.get( "http://firmbridgecapital.com/live.php", function( dt ) {
localStorage.setItem("data", dt);
});
}, 5000);
Highcharts.setOptions({
global: {
useUTC: false
}
});
Highcharts.chart('container', {
chart: {
type: 'spline',
animation: Highcharts.svg, // don't animate in old IE
marginRight: 10,
events: {
load: function () {
// set up the updating of the chart each second
var series = this.series[0];
setInterval(function () {
var x = (new Date()).getTime(), // current time
y = parseInt(localStorage.getItem("data"));
series.addPoint([x, y], true, true);
}, 5000);
}
}
},
title: {
text: 'Live random data'
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150
},
yAxis: {
max: 3,
title: {
text: 'Value'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
formatter: function () {
return '<b>' + this.series.name + '</b><br/>' +
Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x) + '<br/>' +
Highcharts.numberFormat(this.y, 2);
}
},
legend: {
enabled: false
},
exporting: {
enabled: false
},
series: [{
name: 'Random data',
data: (function () {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -150; i <= 0; i += 25) {
data.push({
x: time,
y: parseInt(localStorage.getItem("data"))
});
}
return data;
}())
}]
});
});
I borrowed the idea from this docs example http://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/demo/dynamic-update/
My chart is always grounded on value 1 and does not show the changing values in the y axis. How may i fix this?.
The value you are referencing, i.e. live php page, seems to be 1.x and increasing very slowly. (1.7 while I was looking).
In your parsing you do the following:
y = parseInt(localStorage.getItem("data"));
And since the value is 1.7, and you try to parse it as an integer with parseInt, it gets converted to 1. Using parseFloat will give you a slowly increasing graph.
Is there a way to keep the scroll on the most right?
I am trying live update on highchart and it seems that sometimes I am encountering scroll being left behind.
$(function() {
Highcharts.setOptions({
global: {
useUTC: false
}
});
// Create the chart
$('#container').highcharts('StockChart', {
chart: {
events: {
load: function() {
// set up the updating of the chart each second
var series = this.series[0],
hasPlotLine = false,
$button = $('#button'),
chart = $('#container').highcharts(),
yAxis = chart.yAxis[0],
plotLine,
d,
newY;
yAxis.addPlotLine({
value: 66,
color: 'red',
width: 2,
id: 'plot-line-1',
label: {
text: 66,
align: 'right',
y: newY,
x: 0
}
});
setInterval(function() {
var x = (new Date()).getTime(), // current time
y = Math.round(Math.random() * 100);
series.addPoint([x, y], true, true);
plotLine = yAxis.plotLinesAndBands[0].svgElem;
d = plotLine.d.split(' ');
newY = yAxis.toPixels(y) - d[2];
plotlabel = yAxis.plotLinesAndBands[0].label;
plotlabel.animate({
translateY:newY,
text:y
},400),
plotLine.animate({
translateY: newY
}, 400);
}, 1000);
}
}
},
rangeSelector: {
buttons: [{
count: 1,
type: 'minute',
text: '1M'
}, {
count: 5,
type: 'minute',
text: '5M'
}, {
type: 'all',
text: 'All'
}],
inputEnabled: false,
selected: 0
},
title: {
text: 'Live random data'
},
exporting: {
enabled: false
},
series: [{
name: 'Random data',
data: (function() {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -999; i <= 0; i += 1) {
data.push([
time + i * 1000,
Math.round(Math.random() * 100)
]);
}
return data;
}())
}]
});
});
I know it a little bit hard to explain my concern, but check this image
I have search setExtremes but I am not sure if how it works or how it will be set up on future dated in case this is the function that I am looking for.
Here is the jsfiddle http://jsfiddle.net/kttfv1h3/3/
Appreciate your help
setExtremes() will work - see API http://api.highcharts.com/highcharts/Axis.setExtremes.
The only thing you need to adjust is the min value - you can calculate it from the last point or set some fixed value.
xAxis.setExtremes(x - 1000 * 60, x)
example: http://jsfiddle.net/nmx5hruo/
Im using multiple highchart chart inside my page and i use addpoint function to update the chart.
the problem is after some time the chart will be compressed into less than a half of original chart size.
i captured my screen which could be found here for make the problem clear:
http://www.screenr.com/f3E7
sample chart generation code:
$(function () {
$(document).ready(function() {
Highcharts.setOptions({
global: {
useUTC: false
}
});
//var chart;
chart = new Highcharts.Chart({
chart: {
renderTo: 'ch_trafficio',
type: 'spline',
marginRight: 10,
events: {
load: function() {
// set up the updating of the chart each second
var series = this.series[0];
var series1= this.series[1];
}
}
},
title: {
text: ''
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150
},
yAxis: {
title: {
text: 'Value'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
formatter: function() {
return '<b>'+ this.series.name +'</b><br/>'+
Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x) +'<br/>'+
Highcharts.numberFormat(this.y, 2);
}
},
plotOptions : {
area : {
lineWidth : 1,
marker : {
enabled : false,
states : {
hover : {
enabled : true,
radius : 5
}
}
},
shadow : false,
states : {
hover : {
lineWidth : 1
}
}
}
},
legend: {
enabled: true
},
exporting: {
enabled: true
},
series: [{
name: 'InBound',
type : "area",
color: '#89A54E',
data: (function() {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -119; i <= 0; i++) {
data.push({
x: time + i * 1000,
y: Math.random()
});
}
return data;
})()
},{
name: 'OutBound',
type : "area",
color: '#AA4643',
data: (function() {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -119; i <= 0; i++) {
data.push({
x: time + i * 1000,
y: Math.random()
});
}
return data;
})()
}
]
});
chart update functions:
chart.series[0].addPoint([x,data.oid1], false, true);
chart.series[1].addPoint([x,data.oid2], true, true);
chart1.series[0].addPoint([x,data.oid5], true, true);
chart2.series[0].addPoint([x,data.oid3], false, true);
chart2.series[1].addPoint([x,data.oid4], true, true);
chart3.series[0].addPoint([x,data.oid7], true, true);
thanks in advance
you need to add a shifting parameter for your points to shift over the chart
var series = chart.series[0],
shift = series.data.length > 100; // shift if the series is longer than 100
and to change adding point like below
chart.series[0].addPoint([x,data.oid1], true, shift);
example here