Update color of plotline label on change highcharts - highcharts

is there a way to change color of the plotline label when the movement goes up and change it again in different font color when movement goes down?
yAxis.addPlotLine({
value: 66,
color: 'red',
width: 2,
id: 'plot-line-1',
label: {
text: 66,
align: 'right',
style: {
color: 'red',
fontWeight: 'bold'
},
y: newY,
x: 0
}
});
Here is a working file http://jsfiddle.net/kttfv1h3/9/
thanks for the help

You can add css style options to your plotLabel like to a simple object; docs
var prev_val = 0; // global
plotlabel = yAxis.plotLinesAndBands[0].label;
if(prev_val <= y) {
plotlabel.css({'color':'blue'});
} else {
plotlabel.css({'color':'green'});
}
prev_val = y;
My jsFiddle: http://jsfiddle.net/kttfv1h3/12/

After playing around a bit with the different settings I found a way to achieve what you are seeking.
By delcaring a new variable oldY
And doing the following in setInterval, the label color changes depending on if the value is increasing or decreasing:
if(y < oldY) {
yAxis.plotLinesAndBands["0"].label.element.style.fill = 'red';
} else {
yAxis.plotLinesAndBands["0"].label.element.style.fill = 'green';
}
oldY = y;
See jsfiddle for a working example based on the one you supplied.

Related

Highcharts plotline with label in the left of the line

I want to align Highcharts PlotLine Label with the line (not top or bottom). Is it possible?
Thank!
I think that the easiest way to achieve it is by rendering the plotLine and adding the custom label on it to cover part of the line.
Demo: https://jsfiddle.net/BlackLabel/b50k6hov/
Code:
chart: {
events: {
render() {
let chart = this,
plotLineCor = chart.yAxis[0].plotLinesAndBands[0].svgElem.d.split(' '),
x = plotLineCor[1],
y = plotLineCor[2];
if (!chart.label) {
// render label in init position
chart.label = chart.renderer.label('TEXT', 0, 0)
.css({
color: 'red'
})
.attr({
fill: 'white',
padding: 12,
zIndex: 6
})
.add();
}
// translate label after reach resize
chart.label.translate(x, y - chart.label.getBBox().height / 2)
}
}
},
API: https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#label
API: https://api.highcharts.com/highcharts/chart.events.render

yAxis resizer to change svgrenderer position also highcharts

I have a chart with some indicators below it. Each indicator area consists
of a svg renderer button. so when I use resize property to drag and resize
the panes, the series resized perfectly but the button remains in its same
position, Can we move the button with the resizer?
Here I created a sample link to regenerate
https://jsfiddle.net/q0ybpnvx/2/
Any help will be appreciated. I am having great trouble. Thank you
You can add and position the custom button in render event:
chart: {
events: {
render: function() {
var chart = this;
if (chart.customBtn) {
chart.customBtn.attr({
y: chart.yAxis[1].top,
});
} else {
chart.customBtn = chart.renderer.button(
'sometext',
5,
chart.yAxis[1].top,
function() {
console.log('some task')
}).add()
}
}
}
},
Live demo: https://jsfiddle.net/BlackLabel/b7vq4ecy/
API Reference:
https://api.highcharts.com/highcharts/chart.events.render
https://api.highcharts.com/class-reference/Highcharts.SVGElement#attr
I was able to do something by manually changing the x/y attributes of my svgRenderer label, the same should apply to buttons.
I'm in angular and have a listener for screen resizing:
Also Note that you can change the entire SVGRenderer label with the attr.text property.
this.chart = Highcharts.chart(.....);
// I used a helper method to create the label
this.chart.myLabel = this.labelCreationHelperMethod(this.chart, data);
this.windowEventService.resize$.subscribe(dimensions => {
if(dimensions.x < 500) { //this would be your charts resize breakpoint
// here I was using a specific chart series property to tell where to put my x coordinate,
// you can traverse through the chart object to find a similar number,
// or just use a hardcoded number
this.chart.myLabel.attr({ y: 15, x: this.chart.series[0].points[0].plotX + 20 });
} else {
this.chart.myLabel.attr({ y: 100, x: this.chart.series[0].points[0].plotX + 50 });
}
}
//Returns the label object that we keep a reference to in the chart object.
labelCreationHelperMethod() {
const y = screen.width > 500 ? 100 : 15; 
const x = screen.width > 500 ? this.chart.series[0].points[0].plotX + 50 :
this.chart.series[0].points[0].plotX + 20
// your label
const label = `<div style="color: blue"...> My Label Stuff</div>`
return chart.renderer.label(label, x, y, 'callout', offset + chart.plotLeft, chart.plotTop + 80, true)
.attr({
fill: '#e8e8e8',
padding: 15,
r: 5,
zIndex: 6
})
.add();
}

Find special chart on highcharts

I would like to build a chart like this
enter image description here
Drag the red point or two blue lines on the left chart, then the chart will generate the second one on the right.
Please advice me how to do with highcharts or other chart library. Thank you very much!
There is no such feature in Highcharts, and implementation will be not so easy, but I'm not saying it's not possible. In order to achieve the similar effect, you can use renderer feature, generate the circle and lines. Then change their attributes (position and dimensions), when dragging the circle. For example:
chart: {
events: {
load() {
var chart = this,
circleWidth = 5,
circleInitPos = {
x: 100,
y: 100
},
lineWidth = 2,
indicator = chart.renderer.g('indicator').attr('zIndex', 5).add(),
leftLine = chart.renderer.rect(0, circleInitPos.y, circleInitPos.x, lineWidth)
.attr({
fill: 'blue'
})
.add(indicator),
bottomLine = chart.renderer.rect(circleInitPos.x, circleInitPos.y, lineWidth, chart.containerHeight - circleInitPos.y)
.attr({
fill: 'blue'
})
.add(indicator),
circle = chart.renderer.circle(100, 100, circleWidth)
.attr({
fill: 'red'
}).add(indicator);
circle.drag = false;
chart.container.onmousemove = function(e) {
if (circle.drag) {
let normalizedEvent = chart.pointer.normalize(e),
groupPos = indicator.getBBox(),
leftLineLen = chart.plotWidth - e.chartX,
bottomLineLen = chart.plotHeight - e.chartY;
// Recalculate dimensions
leftLine.attr({
width: e.chartX,
y: e.chartY
})
bottomLine.attr({
height: chart.containerHeight - e.chartY,
y: e.chartY,
x: e.chartX
})
circle.attr({
x: e.chartX,
y: e.chartY
})
}
}
circle.element.onmousedown = function() {
circle.drag = true
}
circle.element.onmouseup = function() {
circle.drag = false
}
}
}
},
I prepared the example which shows how to do it, so here it is: https://jsfiddle.net/rgs4v5az/
API Reference: https://api.highcharts.com/class-reference/Highcharts.SVGRenderer

Show plotlines in highcharts with hidden axis?

Is there a way to show plotlines even when the associated axis has visible: false? Is seems that hiding the axis also hides the plotlines.
More details...
I'm drawing a diagram of a day, like this:
I simply want to add a vertical line at certain times, line the "Now" time, etc.
If I do that using a plot line, then the axis shows up too:
I definitely do not want the axis to show.
My plan now is to draw my own line on the chart using render.rect or render.path. Is there another option?
I found a relatively trivial solution... just hide it with css:
.highcharts-xaxis {
display: none;
}
and in js:
xAxis: {
type: 'datetime',
labels:{
enabled: false
}
}
You can extend Highcharts by wrapping the method responsible for redrawing an axis.
Highcharts.wrap(Highcharts.Axis.prototype, 'redraw', function(p) {
p.call(this);
console.log(this);
var axis = this,
each = Highcharts.each,
options = this.options;
// move plot lines and bands
if (!axis._addedPlotLB) { // only first time
each((options.plotLines || []), function(plotLineOptions) {
axis.addPlotBandOrLine(plotLineOptions);
});
axis._addedPlotLB = true;
}
each(this.plotLinesAndBands, function(plotLine) {
plotLine.render();
});
});
example: http://jsfiddle.net/ncs81btt/
The solution above is not very elegant, though. Much better ways to do it is using Renderer or hide particular axis elements (labels, ticks, etc.).
Depending on what you need from plot lines functionality, using renderer requires to do some calculations.
var customPlotLines = [{
value: 5,
color: 'red',
width: 3
}, {
value: 10,
color: 'yellow',
width: 3
}]
function renderPlotLines() {
var axis = this.xAxis[0],
top = axis.chart.plotTop,
bottom = top + axis.chart.plotHeight,
path = [
'M', null, top,
'L', null, bottom
];
if (!this.customPlotLines) {
this.customPlotLines = customPlotLines.map(plotLine => {
return this.renderer.path([]).add();
});
}
this.customPlotLines.forEach((plotLine, i) => {
var opt = customPlotLines[i];
path[4] = path[1] = axis.toPixels(opt.value);
plotLine.attr({
d: path.join(' '),
'stroke-width': opt.width,
stroke: opt.color
});
});
}
Hook into load/redraw event, so the elements will resize.
chart: {
zoomType: 'xy',
events: {
load: renderPlotLines,
redraw: renderPlotLines
}
},
example: http://jsfiddle.net/ncs81btt/1/

Highcharts add an image to that chart with an onClick event attached to it

I have created a chart where I've added an image.
Now when I click this image I want to set the yAxis max to a specific point, and when I click it again to reset the yAxis to the original values.
This is the jsfiddle for it: http://jsfiddle.net/inadcod/TynwP/
I have managed to add the image, to add a click event to the image, but it's as far as I got.
Can anyone help me out with this? Thanks!
There are two ways to do what you want.
First way:
The problem is that it's not possible to update chart options and then redraw to get it updated, you have to destroy and then create it again like the following.
So, for this you can store your chart options into a var and then pass as parameter.
// inside options
load: function() {
this.renderer.image('http://inadcod.com/img/zoom.png', 70, 10, 28, 28)
.on('click', function() {
if(options.yAxis.max) {
delete options.yAxis.max; // return to default
} else {
options.yAxis.max = 25;
}
chart = new Highcharts.Chart(options);
})
.css({
cursor: 'pointer',
position: 'relative',
"margin-left": "-90px",
opacity: 0.75
}).attr({
id: 'myImage',
zIndex: -100
}).add();
}
Demo
Second way:
redraw isn't called if you just update axis data like the following.
chart.yAxis[0].max = 25;, that's why I suggested the way above.
But if you set chart.yAxis[0].isDisty = true; and call chart.redraw();, it will work. You can see my demo bellow.
// inside chart options
load: function() {
this.renderer.image('http://inadcod.com/img/zoom.png', 70, 10, 28, 28)
.on('click', function() {
var axis = chart.yAxis[0];
axis.max = 25;
axis.isDirty = true;
chart.redraw();
})
.css({
cursor: 'pointer',
position: 'relative',
"margin-left": "-90px",
opacity: 0.75
}).attr({
id: 'myImage', // your image id
zIndex: -100
}).add();
}
Demo

Resources