animate addPlotBand Highcharts - highcharts

Is there a way to add a plotband that has a smooth transition? Before I am using
addPlotLine and
addPlotBand
chart.yAxis[0].removePlotBand('plot-band-1');
chart.yAxis[0].removePlotLine('plot-line-1');
var x = (new Date()).getTime(), // current time
y = Math.round(Math.random() * 100);
series.addPoint([x, y], true, true);
chart.yAxis[0].addPlotBand({
from: 100000,
to: y,
color: {
linearGradient: { x1: 1, y1: 1, x2: 1, y2: 0 },
stops: [
[0, 'rgba(46, 230, 0, 0.22)'],
[1, 'rgba(46, 230, 0, 0)'] //down
]
},
id: 'plot-band-1'
});
chart.yAxis[0].addPlotLine({
value: y,
color: 'red',
width: 2,
id: 'plot-line-1'
});
to plot the point on a dynamic chart, but now I am using animate to make the plotting smoother
plotLine = yAxis.plotLinesAndBands[0].svgElem;
d = plotLine.d.split(' ');
newY = yAxis.toPixels(y) - d[2];
plotLine.animate({
translateY: newY
}, 300);
Also I am trying the solution from this Highcharts plotBand animation. however it seems that I am unable to implement it properly.
For your reference here is the code of where is used addPlotLine and addPlotBand and this is the current code style being used. Appreciate your help with this. Thank you.

If you pass path d attribute as an array, you can animate it as a simple shape.
Add the plotband before setiInterval and animate it as the plotline on every interval.
const plotbandPath = plotband.svgElem.d.split(' ')
plotbandPath[7] = plotbandPath[9] = newY
plotband.svgElem.animate({
d: plotbandPath
}, 300)
example: http://jsfiddle.net/sqer2x13/

Related

TextPath inside an Arc

I'm trying to add text (TextPath) inside an Arc shape, that is following the curve of en Arc. Making a curved TextPath is easy, however I'm failing to put it on top on Arc shape.
If I set x and y of both objects to for.ex. 100 and 100, they end up in illogical locations, so I'm obviously failing to understand something here. What I'm trying to achieve is shown in attached screenshot - could someone make demo of putting a TextPath on top of en Arc ? Thanks.
what I'm trying to achieve
I slightly modified your demo to remove hardcoded values as much as possible.
You just need to correctly generate an SVG path. You can use some answers from here: How to calculate the SVG Path for an arc (of a circle)
Also, you can use Konva.Path shape to debug the generated path.
function polarToCartesian(centerX, centerY, radius, angleInDegrees) {
var angleInRadians = (angleInDegrees-90) * Math.PI / 180.0;
return {
x: centerX + (radius * Math.cos(angleInRadians)),
y: centerY + (radius * Math.sin(angleInRadians))
};
}
function describeArc(x, y, radius, startAngle, endAngle){
var endAngleOriginal = endAngle;
if(endAngleOriginal - startAngle === 360){
endAngle = 359;
}
var start = polarToCartesian(x, y, radius, endAngle);
var end = polarToCartesian(x, y, radius, startAngle);
var arcSweep = endAngle - startAngle <= 180 ? "0" : "1";
if(endAngleOriginal - startAngle === 360){
var d = [
"M", start.x, start.y,
"A", radius, radius, 0, arcSweep, 0, end.x, end.y, "z"
].join(" ");
}
else{
var d = [
"M", start.x, start.y,
"A", radius, radius, 0, arcSweep, 0, end.x, end.y
].join(" ");
}
return d;
}
var width = window.innerWidth;
var height = window.innerHeight;
var stage = new Konva.Stage({
container: 'container',
width: width,
height: height
});
var layer = new Konva.Layer();
stage.add(layer);
var arc = new Konva.Arc({
x: 250,
y: 250,
innerRadius: 100,
outerRadius: 170,
angle: 260,
rotation: 0,
draggable: true,
fill: 'yellow',
stroke: 'black',
strokeWidth: 4,
offset: 0,
});
layer.add(arc);
var tr1 = new Konva.Transformer({
node: arc,
resizeEnabled: false
});
layer.add(tr1);
var txt = new Konva.TextPath({
x: arc.x(),
y: arc.y(),
draggable: true,
fill: '#333',
fontSize: 22,
fontFamily: 'Arial',
text: "Hello world !",
align: 'center',
data: describeArc(0, 0, (arc.innerRadius() + arc.outerRadius()) / 2, 90, 90 + arc.getAttr("angle")),
});
layer.add(txt);
var tr2 = new Konva.Transformer({
node: txt,
resizeEnabled: false,
});
layer.add(tr2);
const path = new Konva.Path({
x: txt.x(),
y: txt.y(),
data: txt.data(),
stroke: 'red'
});
layer.add(path);
layer.draw();
Demo: https://jsbin.com/muwobaxipe/3/edit?js,output

Label position between series in Highcharts polar chart

I'm trying to position custom labels on the outside of a polar chart but can't figure out any way to do it. Please image below for what I'm trying to achieve.
Doesn't have to use the actual series labels but haven't found anything else that can be positioned relative to the actual chart (top level labels can be positioned anywhere but only using absolute left and top).
Have also tried changing the pointPlacement and tickmarkPlacement to "between" which sort of works but it rotates the actual chart so I get a diamond shape instead of a square, the effect I'm after would be more like rotating the labels and leaving the ticks in place.
IN such case custom labels can be positioned relative to grid line group.
Method for drawing the labels:
function drawLabels () {
let labels = this.customLabels,
bbox = this.xAxis[0].gridGroup.getBBox(),
positions = [
[bbox.x + bbox.width / 2, bbox.y],
[bbox.x + bbox.width, bbox.y + bbox.height / 2],
[bbox.x + bbox.width / 2, bbox.y + bbox.height],
[bbox.x, bbox.y + bbox.height / 2]
];
if (!labels) {
labels = this.customLabels = ['lab1', 'lab2', 'lab3', 'lab4'].map(text => this.renderer.label(text, 0, -9999).add().attr({zIndex: 4}));
}
labels.forEach((label, i) => {
label.align({
align: 'center',
verticalAlign: 'middle',
width: label.width,
height: label.height
}, null, {
x: positions[i][0],
y: positions[i][1],
width: 0,
height: 0
});
});
}
Draw labels on load/redraw:
Highcharts.chart('container', {
chart: {
polar: true,
type: 'line',
events: {
load: drawLabels,
redraw: drawLabels
}
},
example: http://jsfiddle.net/d6y1bn31/

Highcharts Multiseries Gauge with DataLabels at Ends

How would you achieve this (jsFiddle link)
dynamically for the Highcharts "Activity Gauge", so obviously it works there but I had to manually determine the correct x & y coordinates for the labels.
This result is similar to using the "inside" property for column charts, but seems nothing is built-in like that for this chart type (that I've run across at least). One could come close by passing in the same y values as for each series as tick marks on the y-axis (see snippet below) and getting rid of all markings except the number, but then I can't stagger those to be positioned correctly within each series, and for the dataLabel x & y approach I don't know the equation to be able to position the labels based on the series y values dynamically with a callback.
yAxis: {
labels: {
enabled: true,
x: 10, y: -15,
format: '{value} %',
style: {
fontSize: 16,
color: 'black'
}
},
min: 0,
max: 100,
gridLineColor: 'transparent',
lineColor: 'transparent',
minorTickLength: 0,
//tickInterval: 67,
tickPositions: [50, 65, 80], //TRIED TO USE Y-AXIS LABELS BUT COULDN'T STAGGER THEM
tickColor: '#000000',
tickPosition: 'inside',
//tickLength: 50,
tickWidth: 0
},
Any help would be much appreciated, thanks in advance.
Solved via Highcharts support forum:
fiddle
, just call the following function on chart load and redraw events:
function redrawConnectors() {
var chart = this,
cX, cY,
shapeArgs, ang, posX, posY, bBox;
Highcharts.each(chart.series, function(series, j) {
Highcharts.each(series.points, function(point, i) {
if (point.dataLabel) {
bBox = point.dataLabel.getBBox();
shapeArgs = point.shapeArgs;
cX = shapeArgs.x,
cY = shapeArgs.y,
ang = shapeArgs.end;
posX = cX + shapeArgs.r * Math.cos(ang);
posY = cY + shapeArgs.r * Math.sin(ang);
point.dataLabel.attr({
x: posX - bBox.width / 2,
y: posY - bBox.height / 2
});
}
});
});
}

Highcharts navigator handle height

Is there any way to increase the height of the handles in the highstock navigator component? Right now, the only options available are to change the color and the border-color. How about the height and width of the handles?
http://api.highcharts.com/highstock#navigator.handles
Thanks,
Vikas.
You can wrap drawHandles function and modify it to have increased height.
var height = 20;
(function (H) {
H.wrap(H.Scroller.prototype, 'drawHandle', function (proceed, x, index) {
var scroller = this,
chart = scroller.chart,
renderer = chart.renderer,
elementsToDestroy = scroller.elementsToDestroy,
handles = scroller.handles,
handlesOptions = scroller.navigatorOptions.handles,
attr = {
fill: handlesOptions.backgroundColor,
stroke: handlesOptions.borderColor,
'stroke-width': 1
},
tempElem;
// create the elements
if (!scroller.rendered) {
// the group
handles[index] = renderer.g('navigator-handle-' + ['left', 'right'][index])
.css({
cursor: 'e-resize'
})
.attr({
zIndex: 4 - index
}) // zIndex = 3 for right handle, 4 for left
.add();
// the rectangle
tempElem = renderer.rect(-4.5, 0, 9, height, 0, 1)
.attr(attr)
.add(handles[index]);
elementsToDestroy.push(tempElem);
// the rifles
tempElem = renderer.path([
'M', -1.5, 4,
'L', -1.5, 12,
'M',
0.5, 4,
'L',
0.5, 12]).attr(attr)
.add(handles[index]);
elementsToDestroy.push(tempElem);
}
// Place it
handles[index][chart.isResizing ? 'animate' : 'attr']({
translateX: scroller.scrollerLeft + scroller.scrollbarHeight + parseInt(x, 10),
translateY: scroller.top + scroller.height / 2 - 8
});
});
}(Highcharts));
http://jsfiddle.net/za68w54r/
There is an option for increasing the height of the navigator too..
Check this fiddle:
http://jsfiddle.net/gh/get/jquery/1.7.2/highslide-software/highcharts.com/tree/master/samples/stock/navigator/height/
Code:
navigator: {
height: 100
},

Change the color of bar on condition in highcharts

I am using highcharts and I want to change the color of bar depending on their Y axis values.
Something like:
{
color: '#92D050', //DEFAULT COLOR OF CURRENT YEAR BAR ON EACH GROUP
name: 'AUG',
shadow: false,
data: [
{ y: 66, color: '#92D050' },
{ y: 55, color: 'red' },
{ y: 78, color: '#92D050' },
{ y: 55, color: 'red'}
]
}
Here how can I apply codition like y: > 60
You can iterate for each element and modify SVG parameter like fill.
http://jsfiddle.net/CaPG9/
var max = 200;
$.each(chart.series[0].data,function(i,data){
if(data.y > max)
data.graphic.attr({
fill:'red'
});
});
It doesn't work, cause if you put the mouse over the columns, the color reset for the original.
I solved with this code, using a variable that counts how many columns I want to color. In my case, j is set before to 6.
var j = 6;
$.each(chart.series[0].data, function(i,data){
for (var n = 0; n <= j; n++) {
chart.series[0].data[n].update({color:'#441606'});
}
});

Resources