2
votes

Highcharts provides a way to increase the line width of a series when hovering over the series or its associated legend item

Highcharts.chart('container', {
xAxis: {
    categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
plotOptions: {
    series: {
        states: {
            hover: {
                enabled: true,
                lineWidth: 5
            }
        }
    }
},
series: [{
    data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
}]});

Highcharts also provides a way to give the legend item a colour when the legend item is hovered on

  Highcharts.chart('container', {
    xAxis: {
     categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 
     'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
    },
    legend: {
     itemHoverStyle: {
        color: 'red',
     }
    },
    series: [{
     data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 
      216.4, 194.1, 95.6, 54.4]
    }]});

Is there a way to combine the two and give the associated chart series the same colour as the legend item's highlight colour, when the legend item is hovered on? So it would be like this jsfiddle http://jsfiddle.net/56wL9oxs/ except the chart series line would also highlight in red when the legend item is hovered. Currently using Angular 6+ so looking for a non-jquery way of doing it. Thanks!

1

1 Answers

2
votes

Unfortunately, Highcharts doesn't provide such a functionality. However, it can be achieved easily by overwriting legend prototype function responsible for hover events.

This function is Highcharts.Legend.prototype.setItemEvents. There you will find mouseover and mouseout trigger functions with access to the particular series instance. So, in mouseover function you will have to change series line and each series point colour to red (item - series reference):

item.graph.attr({
  stroke: 'red'
});

item.points.forEach(function(point) {
  point.graphic.attr({
    fill: 'red'
  });
});

Next, in mouseout function reset the colour to default one. To make it, just save the default colour in the series object and use it in mouseout function:

// item - series reference
if (!item.initColor) {
  item.initColor = item.color;
}

// piece of code inside mouseout function
item.graph.attr({
  stroke: item.initColor
});

item.points.forEach(function(point) {
  point.graphic.attr({
    fill: item.initColor
  });
});

Whole wrapper code:

(function(H) {
  H.Legend.prototype.setItemEvents = function(item, legendItem, useHTML) {
    var legend = this,
      merge = H.merge,
      fireEvent = H.fireEvent,
      Point = H.Point,
      boxWrapper = legend.chart.renderer.boxWrapper,
      activeClass = 'highcharts-legend-' +
      (item instanceof Point ? 'point' : 'series') + '-active';

    if (!item.initColor) {
      item.initColor = item.color;
    }
    // Set the events on the item group, or in case of useHTML, the item
    // itself (#1249)
    (useHTML ? legendItem : item.legendGroup)
    .on('mouseover', function() {
        item.setState('hover');

        // A CSS class to dim or hide other than the hovered series
        boxWrapper.addClass(activeClass);

        legendItem.css(legend.options.itemHoverStyle);

        item.graph.attr({
          stroke: 'red'
        });

        item.points.forEach(function(point) {
          point.graphic.attr({
            fill: 'red'
          });
        });

      })
      .on('mouseout', function() {

        legendItem.css(
          merge(item.visible ? legend.itemStyle : legend.itemHiddenStyle)
        );


        // A CSS class to dim or hide other than the hovered series
        boxWrapper.removeClass(activeClass);

        item.setState();

        item.graph.attr({
          stroke: item.initColor
        });

        item.points.forEach(function(point) {
          point.graphic.attr({
            fill: item.initColor
          });
        });
      })
      .on('click', function(event) {
        var strLegendItemClick = 'legendItemClick',
          fnLegendItemClick = function() {
            if (item.setVisible) {
              item.setVisible();
            }
          };

        // A CSS class to dim or hide other than the hovered series. Event
        // handling in iOS causes the activeClass to be added prior to click
        // in some cases (#7418).
        boxWrapper.removeClass(activeClass);

        // Pass over the click/touch event. #4.
        event = {
          browserEvent: event
        };

        // click the name or symbol
        if (item.firePointEvent) { // point
          item.firePointEvent(
            strLegendItemClick,
            event,
            fnLegendItemClick
          );
        } else {
          fireEvent(item, strLegendItemClick, event, fnLegendItemClick);
        }
      });
  }
})(Highcharts);

Demo:
https://jsfiddle.net/wchmiel/cdaruenv/

Api reference:
https://api.highcharts.com/class-reference/Highcharts.SVGElement#attr