Highcharts: arrow being rendered on the wrong charts

Viewed 311

I have 3 Highcharts charts on a webpage with a jQuery-UI tabs navigation system - one chart per tab. In only one of these charts I added an arrow to the plotted line. This arrow gets generated inside an IIFE (see the code sample below). Otherwise the Highcharts functions are pretty standard.

The problem occurs when I try to switch tabs and present the data for the other two charts: the arrow is being drawn on the charts that shouldn't have any arrows.

The erroneous arrow isn't always drawn on the other charts - never on the first render, and usually only after the user has switched tabs two or three times, then the arrow appears where it shouldn't. I also noticed that this IIFE is being called each time a chart is rendered (even from the other tabs).

I don't know how Highcharts works internally but each one of my charts is attached to a different DOM element (by ID), therefore Highcharts shouldn't mix the charts when the arrow is being rendered.

Does anyone have any idea why this is happening?

      (function (H) {

            var arrowCheck = false, //This variable helps the arrow to be responsive
                pathTag;



            H.wrap(H.Series.prototype, 'drawGraph', function (proceed) {

                // Now apply the original function with the original arguments,
                // which are sliced off this function's arguments
                // This section takes care of the arrow of the graph

                proceed.apply(this, Array.prototype.slice.call(arguments, 1));

                var arrowLength = 14,
                    arrowWidth = 7,
                    series = this,
                    data = series.data,
                    segments = data,
                    lastSeg = segments[segments.length - 1],
                    path = [],
                    lastPoint = null,
                    nextLastPoint = null;

                if (typeof (lastSeg) === "undefined") {
                    return;
                }

                if (lastSeg.y === 0) {
                    lastPoint = segments[segments.length - 2];
                    nextLastPoint = segments[segments.length - 1];
                } else {
                    lastPoint = segments[segments.length - 1];
                    nextLastPoint = segments[segments.length - 2];
                }

                var angle = Math.atan((lastPoint.plotX - nextLastPoint.plotX) /
                    (lastPoint.plotY - nextLastPoint.plotY));

                if (angle < 0) angle = Math.PI + angle;


                path.push('M', lastPoint.plotX, lastPoint.plotY);

                if (lastPoint.plotX > nextLastPoint.plotX) {

                    if (arrowCheck === true) {

                        pathTag = doc.getElementById("arrow");
                        if (pathTag != null) {
                            pathTag.remove(pathTag);
                        }
                    }

                    path.push(
                        'L',
                        lastPoint.plotX + arrowWidth * Math.cos(angle),
                        lastPoint.plotY - arrowWidth * Math.sin(angle)
                    );
                    path.push(
                        lastPoint.plotX + arrowLength * Math.sin(angle),
                        lastPoint.plotY + arrowLength * Math.cos(angle)
                    );
                    path.push(
                        lastPoint.plotX - arrowWidth * Math.cos(angle),
                        lastPoint.plotY + arrowWidth * Math.sin(angle),
                        'Z'
                    );

                } else {

                    if (arrowCheck === true) {

                        pathTag = doc.getElementById("arrow");
                        if (pathTag != null) {
                            pathTag.remove(pathTag);
                        }
                    }

                    path.push(
                        lastPoint.plotY + arrowWidth * Math.sin(angle)
                    );
                    path.push(
                        lastPoint.plotX - arrowLength * Math.sin(angle),
                        lastPoint.plotY - arrowLength * Math.cos(angle)
                    );
                    path.push(
                        lastPoint.plotX + arrowWidth * Math.cos(angle),
                        lastPoint.plotY - arrowWidth * Math.sin(angle),
                        'Z'
                    );

                }

                series.chart.renderer.path(path)
                    .attr({
                        fill: series.color,
                        id: 'arrow'
                    })
                    .add(series.group);
                arrowCheck = true;

            });

        }(Highcharts));

Here a JSFiddle example (you just need to resize the section where the Charts are to see how the arrow jumps to the wrong chart)

1 Answers
Related