maafk
maafk

Reputation: 6876

highcharts redraw() with function that references newly redrawn chart

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

Answers (1)

Halvor Holsten Strand
Halvor Holsten Strand

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

Related Questions