Highcharts - размещение меток данных Dynami c на многосерийных диаграммах doughtnut - PullRequest
0 голосов
/ 25 мая 2020

Справочная информация: Я пытаюсь создать многосерийную кольцевую диаграмму с метками данных, расположенными в центре каждого фрагмента, как это (см. Ниже), однако я хочу, чтобы метки данных переставляли себя, если Размер div изменен:

enter image description here

Проблема: Я изо всех сил пытаюсь точно переместить метки данных при изменении размера div.

Мне нужно получить текущий размер графика кольцевой диаграммы в процентах, с помощью которого я мог бы рассчитать точное расстояние от краев кольцевой диаграммы для размещения меток данных.

Пример скрипки

Вот макет в скрипке: http://jsfiddle.net/simkus/bo2eumkd/30/

$(function() {
  var container = $('#container')[0];
  $('#resizer').resizable({
    // On resize, set the chart size to that of the 
    // resizer minus padding. If your chart has a lot of data or other
    // content, the redrawing might be slow. In that case, we recommend 
    // that you use the 'stop' event instead of 'resize'.

   // TODO we need to calculate the distance of dataLabels from the edges of the
   // doughnut chart. The main thing is that the chart might be resized, to e.g. 200pxx200px
   // and then the labels now gets scatared by the current algorythm where we calculate `distance`
   // the `distance` should be calculated I think not in pixels by % of the current
   // chart placeholder size. The chart it self has a `size` of 80% for all series.
   // the inner size is also measured in %, so the distance somehow has to be done
   // similary, but at this point, the `distance` doesn't work with % as size and innerSize
    resize: function() {
      chart.setSize(
        this.offsetWidth - 20,
        this.offsetHeight - 20,
        false
      );
    }
  });

  let seriesData = [{
      "base": 1949,
      "data": [106, 105, 26, 43, 55, 136],
      "name": "Total",
    },
    {
      "base": 871,
      "data": [38, 44, 14, 20, 25, 75],
      "name": "Male",
    },
    {
      "base": 1063,
      "data": [65, 61, 12, 23, 31, 60],
      "name": "Female",
    }
  ]
  let categories = [
    "Don't know",
    "Australia",
    "India",
    "Japan",
    "Brazil",
    "I don’t know"
  ]


  let series = [];
  let plotArea = 350;
    let centerInnerSize = 40; // 40%

  for (let i = 0; i < seriesData.length; i++) {
      var showInLegend = false,
          data = [],
          innerSize = centerInnerSize + ((100 - centerInnerSize) / seriesData.length) * i,
          width = (plotArea / 2) * ((1 - centerInnerSize / 100) / seriesData.length),
          distance = (plotArea / 2) * (1 - innerSize / 100) - width / 2;

      if (i == 0) {
          showInLegend = true;
      }

      for (let j = 0; j < categories.length; j++) {
          data.push({
            'name': categories[j],
            'y': seriesData[i].data[j]
          })
      }

      series.push({
          name: seriesData[i].name,
          data: data,
          innerSize: innerSize + '%',
          size: "80%",
          showInLegend: true,
          dataLabels: {
              enabled: true,
              distance: -distance,
          }
      })
  }


  var chart = new Highcharts.Chart({
    chart: {
      renderTo: 'container',
      plotBackgroundColor: null,
      plotBorderWidth: 1,
      plotShadow: false,
      type: 'pie',
      events: {
        render() {
          let chart = this;

          chart.series.forEach(s => {
            s.points.forEach(p => {
              let label = p.dataLabel;

              p.dataLabel.translate(label.translateX, label.translateY)
            })
          })
        }
      }
    },
    subtitle: {
      text: 'Drag the handle in the lower right to resize'
    },
    tooltip: {
      pointFormat: '{series.name}: <b>{point.percentage:.2f}%</b>'
    },
    plotOptions: {
      pie: {
        allowPointSelect: false,
        cursor: 'pointer',
        minSize: 1,
        dataLabels: {
          enabled: true,
          color: '#000000',
          format: '{percentage:.2f} %',
        }
      }
    },
    series: series,
  });
});

Есть идеи, как я могу решить эту проблему?

Ответы [ 2 ]

0 голосов
/ 29 мая 2020

Обновлен расчет расстояния в процентах, и теперь он работает.

http://jsfiddle.net/4g1pxvqb/36/

  for (let i = 0; i < seriesData.length; i++) {
      var showInLegend = false,
          data = [],
          innerSize = centerInnerSize + ((100 - centerInnerSize) / seriesData.length) * i,
          width = (100 - centerInnerSize) / 3; 

          distance = '-' + (10 + width * (2 - i)) + '%';
0 голосов
/ 25 мая 2020

Мне нужно получить текущий размер графика кольцевой диаграммы в пикселях, с помощью которого я мог бы рассчитать точное расстояние от краев пончика для размещения меток данных.

Я не уверен, какой у вас Идея разместить метки данных, но вы должны быть в состоянии достичь ее, используя обратный вызов render, где вы можете получить доступ к каждой точке и ее метке.

Демо: http://jsfiddle.net/BlackLabel/5m41p986/

  events: {
    render() {
      let chart = this;

      chart.series.forEach(s => {
        s.points.forEach(p => {
          let label = p.dataLabel;

          p.dataLabel.translate(label.translateX, label.translateY)
        })
      })
    }
  }

API: https://api.highcharts.com/highcharts/chart.events.render

...