2016-09-01 7 views
1

У меня есть круговые диаграммы с несколькими рядами данных, каждый из которых представлен круговой диаграммой (см. Ссылку JSFiddle).Highcharts Auto Calculate Multiple Position Position

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

У меня Actualy появился вопрос о начале решения, но это действительно не оптимально.

Либо я не понимал, как работают Highcharts при создании диаграмм, или есть много неизвестного значения для моей системы, чтобы иметь возможность сделать расчет или и то, и другое.

Обратите внимание, что генератор работает только с 1 по 6 различных серий данных, если использовать больше серий, он не сможет получить место размещения, поскольку я не сделал расчет.

Также он actualy подтвердил работать только на контейнерах из этих размеров:

  • ширина: 340px Высота: 170 пикселей
  • ширина: 680px Высота: 170 пикселей

В контейнере с highter шириной или высота система не сможет вычислить позицию.

Это действительно часть того, почему я пришел к идее о том, как получить оптимальный и общий калькулятор положения.

Вот код, с которым я пришел, и ссылку JSFiddle после примера кода.

// Pie Chart Class 
var pieChart = { 
    create: function(_title, _data, _color, _height, _width) { 
     return (function() { 

      var type = 'pie'; 
      var title = _title || "defaultName"; 
      var color = _color || "#EBEBEB"; 
      var height = _height || 170; 
      var width = _width || 340; 
      var series = []; 
      var chart; 
      var sizeData = getSize(height, width); 
      if (_data) 
       newSeries(_data); 

      // Public functions 
      function newSeries(_data) { 
       var _datas = []; 

       for (var dataSet in _data) { 
        if (_data.hasOwnProperty(dataSet) && (color != null && color != undefined)) { 
         _datas.push({ 
          name: dataSet, 
          y: _data[dataSet], 
         }); 
        } 
       } 

       series.push({ 
        data: _datas, 
        borderWidth: 0, 
        center: [] 
       }); 
       setPos(series.length); 
      } 

      function Series() { 
       return (JSON.stringify(series)); 
      } 

      function drawOn(item) { 
       if (!item || !document.getElementById(item) && !chart) 
        return (null); 
       else { 
        chart = new Highcharts.Chart({ 
         chart: { 
          renderTo: item, 
          backgroundColor: color, 
          plotBackgroundColor: null, 
          plotBorderWidth: null, 
          plotShadow: false, 
          type: 'pie' 
         }, 
         title: { 
          text: title 
         }, 
         plotOptions: { 
          pie: { 
           allowPointSelect: false, 
           borderWidth: 0, 
           dataLabels: { 
            distance: -1, 
            enabled: true, 
            format: '<b>{point.name}</b>: {point.y}', 
            style: { 
             color: 'black' 
            } 
           }, 
           size: sizeData.size 
          } 
         }, 
         series: JSON.parse(Series()) 
        }); 
       } 
      } 

      // Private functions 
      function setPos(_len) { 
       if (_len == 1) 
        series[0].center = [sizeData.center, sizeData.h]; 
       else if (_len == 2) { 
        series[0].center = [sizeData.second, sizeData.h]; 
        series[1].center = [sizeData.fourth, sizeData.h]; 
       } else if (_len == 3) { 
        series[0].center = [sizeData.w1, sizeData.h]; 
        series[1].center = [sizeData.center, sizeData.h]; 
        series[2].center = [sizeData.w6, sizeData.h]; 
       } else if (_len == 4) { 
        series[0].center = [(sizeData.w1 + sizeData.w2)/2, sizeData.h]; 
        series[1].center = [sizeData.w3, sizeData.h]; 
        series[2].center = [(sizeData.w4 + sizeData.w5)/2, sizeData.h]; 
        series[3].center = [sizeData.w6, sizeData.h]; 
       } else if (_len == 5) { 
        series[0].center = [sizeData.w1, sizeData.h]; 
        series[1].center = [sizeData.second, sizeData.h]; 
        series[2].center = [sizeData.center, sizeData.h]; 
        series[3].center = [sizeData.fourth, sizeData.h]; 
        series[4].center = [sizeData.w6, sizeData.h]; 
       } else if (_len == 6) { 
        series[0].center = [sizeData.w1, sizeData.h]; 
        series[1].center = [sizeData.w2, sizeData.h]; 
        series[2].center = [sizeData.w3, sizeData.h]; 
        series[3].center = [sizeData.w4, sizeData.h]; 
        series[4].center = [sizeData.w5, sizeData.h]; 
        series[5].center = [sizeData.w6, sizeData.h]; 
       } 
      } 

      function getSize(height, width) { 
       var nbChart = 6; 
       var diam; 
       var tmpWidth = width - 30; 
       if (nbChart == 1) 
        diam = height - (height/3); 
       else { 
        diam = (tmpWidth - (tmpWidth/nbChart))/nbChart; 
       } 
       var test = (tmpWidth - (diam * nbChart)); 
       var h = ((height - diam)/2)/2; 
       var w = diam + (test/(nbChart * 2)); 
       var decal; 
       if (width >= 680) 
        decal = test/10; 
       else 
        decal = 0; 
       return { 
        width: width, 
        height: height, 
        size: diam, 
        h: h, 
        w1: ((diam/2) + decal), 
        w2: (((w) + diam/2) + decal), 
        w3: (((w * 2) + diam/2) + decal), 
        w4: (((w * 3) + diam/2) + decal), 
        w5: (((w * 4) + diam/2) + decal), 
        w6: (((w * 5) + diam/2) + decal), 
        center: (((((w * 2) + diam/2) + decal) + (((w * 3) + diam/2) + decal))/2), 
        second: (((diam/2) + decal) + (((((w * 2) + diam/2) + decal) + (((w * 3) + diam/2) + decal))/2))/2, 
        fourth: ((((((w * 2) + diam/2) + decal) + (((w * 3) + diam/2) + decal))/2) + (((w * 5) + diam/2) + decal))/2 
       } 
      } 

      return { 
       Series: Series, 
       drawOn: drawOn, 
       newSeries: newSeries 
      } 
     })(); 
    } 
}; 

var crPie = pieChart.create('Test', {T1: 500, T2: 700}, "#EBEBEB", 170, 680); 
crPie.newSeries({T1: 700, T2: 800}); 
crPie.drawOn('container'); 

(Вот ссылка JSFiddle: https://jsfiddle.net/jcL0wuwp/)

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

(я знаю, что какая-то часть кода не optimals, но мой quetion не о том, как оптимизировать или использования классов в JS, хотя я не agaisnt советует.)

ответ

1

Я изменю немного ваше представление позиционирования вашей серии пирогов. Я предпочел бы оборачивать метод getCenter из Higcharts, так что можно будет использовать адаптивные схемы:

(function(H) { 
    H.wrap(H.Chart.prototype, 'addSeries', function(proceed, options, redraw, animation) { 
     proceed.apply(this, Array.prototype.slice.call(arguments, 1)); 
     var chart = this; 
     Highcharts.each(chart.series, function(s) { 
     s.isDirty = true; 
     }); 
     chart.redraw(); 
    }); 

    H.wrap(H.seriesTypes.pie.prototype, 'getCenter', function(proceed) { 
     var series = this, 
     chart = series.chart, 
     width = chart.chartWidth, 
     height = chart.chartHeight, 
     numberOfSeries = chart.series.length, 
     index = series._i, 
     initialSize, size, centerY = height/2, 
     centerX; 
     centerX = (index + 1) * (width/(numberOfSeries + 1)); 
     initialSize = width/(numberOfSeries + 1); 
     size = initialSize > height ? height : initialSize; 
     return [centerX, centerY, size, 0] 
    }); 
    }(Highcharts)); 

Я использовал несколько рядов для вычисления нового размера и центрального положения вас пирога серии. Я изменил метод addSeries, чтобы вы могли добавлять собственные серии pie.

Здесь вы можете найти пример того, как это может работать: это работа http://jsfiddle.net/oohn3q22/6/

+0

THANK как шарм, я не толкал достаточно моего исследования перегружать Highcharts внутренний метод. – Matthias