Reputation: 6876
I have a chart with an events.load
function that draws some lines based on the charts properties.
The loading function works exactly how I'd like it to, but I'd like to erase and re-draw the lines each time the chart gets redrawn (such as hiding a series).
I added the same function (with erasing) on the chart.events.redraw
function thinking this would do the trick, but the object given to the redraw()
function is the previous chart properties, not the new properties.
For example in the fiddle, if you hide Canada, the x axis changes, but the lines don't get rendered. But click Canada again to un-hide, and the chart is re-drawn, but with the prior properties.
Is there a way to redraw but with the newly redrawn chart properties? Thanks!
See (fiddle).
events : {
load: function(){
var ren = this.renderer;
// Get data from the highcharts object
var plot = this.plotBox;
var zeroGridLine = this.yAxis[0].ticks[0].gridLine.d;
var zeroGridLineArray = zeroGridLine.split(' ');
var topPos = plot.y; // top of the chart
var zeroPos = parseFloat(zeroGridLineArray.slice(-1)[0]); // position of the zero line
var bottomPos = topPos + plot.height; // bottom of the chart
var vertLinePos = parseFloat(zeroGridLineArray.slice(-2)[0]) + 8; // vertical line position
var horizWidth = 5; // width of the horizontal lines
var strokeWidth = 1; // thickness of the line
var stroke = 'black'; // color of the line
// exports vertical line
ren.path(['M', vertLinePos, topPos, 'L', vertLinePos, zeroPos])
.attr({
stroke: stroke,
'stroke-width': strokeWidth,
id: 'impExpLines_0'
})
.add();
// imports vertical line
ren.path(['M', vertLinePos, zeroPos, 'L', vertLinePos, bottomPos])
.attr({
stroke: stroke,
'stroke-width': strokeWidth,
id: 'impExpLines_1'
})
.add();
// Horizontal line to separate import/export
ren.path(['M', vertLinePos - horizWidth, zeroPos, 'L', vertLinePos + horizWidth, zeroPos])
.attr({
stroke: stroke,
'stroke-width': strokeWidth,
id: 'impExpLines_2'
})
.add();
// top horizontal line
ren.path(['M', vertLinePos - horizWidth, topPos, 'L', vertLinePos + horizWidth, topPos])
.attr({
stroke: stroke,
'stroke-width': strokeWidth,
id: 'impExpLines_3'
})
.add();
// bottom horizontal line
ren.path(['M', vertLinePos - horizWidth, bottomPos, 'L', vertLinePos + horizWidth, bottomPos])
.attr({
stroke: stroke,
'stroke-width': strokeWidth,
id: 'impExpLines_4'
})
.add();
// label imports and exports
ren.text('Exports',vertLinePos + 5,((zeroPos - topPos) / 2) + topPos + 3 )
.attr({id: 'impExpLines_5'})
.add();
// label imports and exports
ren.text('Imports',vertLinePos + 5,((bottomPos - zeroPos) / 2) + zeroPos + 3 )
.attr({id: 'impExpLines_6'})
.add();
},
redraw : function(){
// clear previosuly drawn lines
$("[id^=impExpLines_]").remove();
var ren = this.renderer;
// Get data from the highcharts object
var plot = this.plotBox;
var zeroGridLine = this.yAxis[0].ticks[0].gridLine.d;
var zeroGridLineArray = zeroGridLine.split(' ');
var topPos = plot.y; // top of the chart
var zeroPos = parseFloat(zeroGridLineArray.slice(-1)[0]); // position of the zero line
var bottomPos = topPos + plot.height; // bottom of the chart
var vertLinePos = parseFloat(zeroGridLineArray.slice(-2)[0]) + 8; // vertical line position
var horizWidth = 5; // width of the horizontal lines
var strokeWidth = 1; // thickness of the line
var stroke = 'black'; // color of the line
// exports vertical line
ren.path(['M', vertLinePos, topPos, 'L', vertLinePos, zeroPos])
.attr({
stroke: stroke,
'stroke-width': strokeWidth,
id: 'impExpLines_0'
})
.add();
// imports vertical line
ren.path(['M', vertLinePos, zeroPos, 'L', vertLinePos, bottomPos])
.attr({
stroke: stroke,
'stroke-width': strokeWidth,
id: 'impExpLines_1'
})
.add();
// Horizontal line to separate import/export
ren.path(['M', vertLinePos - horizWidth, zeroPos, 'L', vertLinePos + horizWidth, zeroPos])
.attr({
stroke: stroke,
'stroke-width': strokeWidth,
id: 'impExpLines_2'
})
.add();
// top horizontal line
ren.path(['M', vertLinePos - horizWidth, topPos, 'L', vertLinePos + horizWidth, topPos])
.attr({
stroke: stroke,
'stroke-width': strokeWidth,
id: 'impExpLines_3'
})
.add();
// bottom horizontal line
ren.path(['M', vertLinePos - horizWidth, bottomPos, 'L', vertLinePos + horizWidth, bottomPos])
.attr({
stroke: stroke,
'stroke-width': strokeWidth,
id: 'impExpLines_4'
})
.add();
// label imports and exports
ren.text('Exports',vertLinePos + 5,((zeroPos - topPos) / 2) + topPos + 3 )
.attr({id: 'impExpLines_5'})
.add();
// label imports and exports
ren.text('Imports',vertLinePos + 5,((bottomPos - zeroPos) / 2) + zeroPos + 3 )
.attr({id: 'impExpLines_6'})
.add();
}
}
Upvotes: 1
Views: 164
Reputation: 20536
In short, instead of using the actual drawn grid lines and parsing their location, use the toPixels
function which is a utility method to translate an axis value to pixel position. In your code you have the line:
var zeroPos = parseFloat(zeroGridLineArray.slice(-1)[0]); // position of the zero line
Replace that line with:
var zeroPos = this.yAxis[0].toPixels(0); // position of the zero line
See this JSFiddle demonstration.
I didn't specifically read through the rest of your code, but you might also be able to more easily establish the top and bottom of the axis using this method instead of parsing.
Upvotes: 2