score:0

Accepted answer

Aparently the target you get from the events have a property called graphic which is a handle to the Highcharts.SVGElement of the slice. With that, we can call the .toFront() function which will change the DOM order without changing the order of the slices in the donut.

document.addEventListener('DOMContentLoaded', function() {
  const chart = Highcharts.chart('container', getChartOptions())
})

/** 
 * Gets the highchart options for the pie chart.
 * Each data point has event handlers added to them 
 * To set the correct border widths
 */
function getChartOptions() {
  return {
    series: [{
      type: 'pie',
      innerSize: '80%',
      allowPointSelect: true,
      slicedOffset: 0,
      states: {
        // Remove default hover settings
        hover: {
          halo: null,
          brightness: 0,
        },
      },
      data: getMockData()
    }],
  };
}

/** 
 * Generates mock data for highcharts
 * Each data point has event handlers set up in the `events` property
 */
function getMockData() {
  return [{
      color: '#aaf',
      borderColor: '#aaf',
      y: 4,
      events: getEventHandlers(),
    },
    {
      color: '#afa',
      borderColor: '#afa',
      y: 3,
      events: getEventHandlers(),
    },
    {
      color: '#faa',
      borderColor: '#faa',
      y: 8,
      events: getEventHandlers(),
    },
  ]
}

/** 
 * Event handlers for highchart data points. 
 * The border width of the slice is set to 20 for `select` and `mouseOver`
 * The border width of the slice is set to 0 for `unselect` and `mouseOut` (except when the event is selected, in which case `mouseOut` shouldn't do anything)
 */
function getEventHandlers() {
  return {
    select: (obj) => {
      obj.target.update({
        borderWidth: 20
      });
      obj.target.graphic.toFront();
    },
    unselect: (obj) => {
      obj.target.update({
        borderWidth: 0
      });
    },
    mouseOver: (obj) => {
      obj.target.update({
        borderWidth: 20
      });
      obj.target.graphic.toFront();
    },
    mouseOut: (obj) => {
      if (!obj.target['selected']) {
        obj.target.update({
          borderWidth: 0
        });
      }
    },
  };
}
/* A drop shadow is the effect I want to accomplish, but it should be above the other slices. */
.highcharts-pie-series .highcharts-point-hover,
.highcharts-pie-series .highcharts-point-select {
  filter: drop-shadow(0 0 10px black);
}
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="container" style="width:100%; height:400px;"></div>

score:1

To achieve extra border when you hovering you can trigger to the point.events and add SVG attributes.

  plotOptions: {
    pie: {
      type: 'pie',
      innerSize: '80%',
      allowPointSelect: true,
      slicedOffset: 0,
      states: {
        hover: {
          halo: null,
          brightness: 0,
        },
      },
      point: {
        events: {
          mouseOver: (obj) => {
            obj.target.graphic.attr({
                'stroke-width': 50,
                stroke: obj.target.color,
                zIndex: 3,
                filter: 'drop-shadow(0 0 10px black)'
              }).css({
                borderRadius: 20
              })
              .add();
          },
          mouseOut: (obj) => {
            obj.target.graphic.attr({
                'stroke-width': 1,
                stroke: obj.target.color,
                filter: 'transparent'
              }).css({
                borderRadius: 0
              })
              .add();
          },
        }
      }

    }
  },

Live demo:

https://jsfiddle.net/BlackLabel/u4ypbsrk/

API References:

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

https://api.highcharts.com/class-reference/Highcharts.CSSObject,

https://api.highcharts.com/highcharts/plotOptions.pie.point.events


Related Query

More Query from same tag