I need to draw an arbitrary path on a chart that has a datetime axis:
xAxis: {
type: 'datetime'
}
I'm trying to use chart.renderer.path('M', x, y). I can easily determine the y value, but how do I specify the x?
Here is a simple example (based on a Highcharts' fiddle, copied to http://jsfiddle.net/ykcff0sL/3/). If you look at the last lines of the code, I want to add a line on the chart:
// add line from January to April
chart.renderer.path(
'M', new Date(2014, 0, 1), 0.8,
'L', new Date(2014, 3, 1), 0.9)
.attr({
'stroke-width': 2,
stroke: 'red'
})
.add()
This is not working. I've also tried using toPixels to no avail.
'M', chart.xAxis(0).toPixels(new Date(2014, 0, 1)), 0.8,
'L', chart.xAxis(0).toPixels(new Date(2014, 3, 1)), 0.9)
Can you fix the jsfiddle example to work, or tell me how to?
Renderer.path requires an array of coordinates.
chart.xAxis is also an array of axes, not a function.
To determine x and y of a specific coordinate, use xAxis/yAxis.toPixels()
var xAxis = chart.xAxis[0];
var yAxis = chart.yAxis[0];
chart.renderer.path([
'M', xAxis.toPixels(new Date(2014, 0, 1)), yAxis.toPixels(0.8),
'L', xAxis.toPixels(new Date(2014, 3, 1)), yAxis.toPixels(0.9)
])
.attr({
'stroke-width': 2,
stroke: 'red'
})
.add()
example: http://jsfiddle.net/ykcff0sL/4/
Related
I'm creating a chart with 2 series. The series share the same axis but have different Ys for different Xs. For example:
Axis A: [{ x: 2, y: 5}, { x: 4, y: 10}]
Axis B: [{ x: 1, y: 2}, { x: 3, y: 6}, { x: 3, y: 9}]
I want to show a tooltip for each X value that appears in axis A (so in this case, for x = 2, 4) and in the tooltip show the value that both axis would have there.
So the problem is that for axis B I don't have a point for x = 2 and x = 4. Is there a way to calculate dinamically the Y value that the axis B would have in those Xs?
This is an example: the tooltip shows info of the blue point, but also calculates what the corresponding green point would be and shows it in the tooltip.
Thank you!
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/
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
});
}
});
});
}
I need some help for the handles in the navigator of highstock.
My set options do not work in my example:
http://jsfiddle.net/q1xpn6hL/
Please take a look at line 5 to 9:
borderColor: '#666',
width: 10,
height: 35,
borderRadius: 2,
borderWidth: 0.5
thanks a lot!
Those options are not supported. You would have to extend Highcharts to enable them. It is possible to override function that handles creating of handles.
Example: http://jsfiddle.net/v4vhy01j/
(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,
borderWidth = H.pick(handlesOptions.borderWidth, 1),
borderRadius = H.pick(handlesOptions.borderRadius, 0),
width = H.pick(handlesOptions.width, 9),
height = H.pick(handlesOptions.height, 16),
attr = {
fill: handlesOptions.backgroundColor,
stroke: handlesOptions.borderColor,
'stroke-width': borderWidth
},
tempElem;
// create the elements
if (!scroller.rendered) {
// the group
handles[index] = renderer.g('navigator-handle-' + ['left', 'right'][index])
.css({
cursor: 'ew-resize'
})
.attr({
zIndex: 4 - index
}) // zIndex = 3 for right handle, 4 for left
.add();
// the rectangle
tempElem = renderer.rect(-5, 9 - height/2, width, height, borderRadius)
.attr(attr)
.add(handles[index]);
elementsToDestroy.push(tempElem);
// the rifles
tempElem = renderer.path([
'M', -1.5, 13 - height/2,
'L', -1.5, 5 + height/2,
'M',
0.5, 13 - height/2,
'L',
0.5, 5 + height/2]).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));
The Highstock navigator does not support all those options. Here's what the documentation says:
handles: Object
Options for the handles for dragging the zoomed area. Available options are backgroundColor (defaults to #ebe7e8) and borderColor (defaults to #b2b1b6).
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
},