在 kendo 网格数据绑定事件上填充 Highchart 饼图

filling Highchart pie graph on kendo grid databound event

我用样本数据创建了一个fiddle,当然还是不行

http://jsfiddle.net/jp2code/q1v4xewc/28/

我有远程数据进入 kendo 网格,我正在尝试通过更新 Highchart 饼图的数据来处理摘要信息。

function onDataBound(e) {
    var pieSubst = ['Meter Count per Substation (Top 10)', [], []];
    var pieFeedr = ['Meter Count per Feeders (Top 10)', [], []];
    $.each(grid.items(), function (index, item) {
        var uid = $(item).data('uid');
        var row = grid.dataSource.getByUid(uid);
        var days = row.Days;
        formatPieData(pieSubst, row.Substation, days, row);
        formatPieData(pieFeedr, row.Feeder, days, row);
    });
    donutChart('#divPieSubst', pieSubst);
    donutChart('#divPieFeedr', pieFeedr);
};

这是我的格式函数:

function formatPieData(array, countLabel, days, row) {
    if ((countLabel == null) || (countLabel == '')) {
        countLabel = '(no label)';
    }
    var dataArray = array[1];
    if (!dataArray) { // if there is nothing at position 2,
        dataArray = []; // create an empty array (which should have been done in the onDataBound(e))
    }
    if (!dataArray[countLabel]) { // if array[label] does not exists,
        dataArray[countLabel] = { // create the array entry using
            Name: countLabel, // the label
            Days: days, // and the days
        };
    } else { // otherwise...
        dataArray[countLabel].Days = dataArray[countLabel].Days + days; // ...add the days
    }
    array[2].push(row); // push the row data on the end
}

上面处理了 617 行,但我的圆环图是空的。

下面是我的 donutChart 函数,用于显示 Highcharts 图表:

function donutChart(div, array) { // donut: https://www.tutorialspoint.com/highcharts/highcharts_pie_donut.htm
    var target = $(div);
    if (target != null) {
        var chartTitle = array[0].label;
        array[1].data.sort(function (o1, o2) { return o2.days - o1.days });
        console.log('donutChart(' + chartTitle + ') data:');
        console.log(array[1].data);
        var categories = {};
        var colors = Highcharts.getOptions().colors;
        var colorMax = colors.length - 1;
        var top10 = [];
        $.each(array[1].data.slice(0, 9), function (index, item) { // only interested in 0 to 9 (top 10)
            console.log('donutChart: each(array) (index) = ' + index);
            console.log(item);
            var name = item.Name;
            if (name == null) {
                name = '(no label)';
            }
            categories.push(name);
            var entry = {
                name: name,
                y: item.Days,
                color: colors[index % colorMax], // don't go over the array
                drilldown: {
                    name: name,
                    data: item,
                    color: colors[index % colorMax], // don't go over the array
                }
            };
            console.log('donutChart: each(array) data = ');
            console.log(entry);
            top10.push(entry);
        });
        var chart = {
            height: '50%',
            renderTo: div,
            type: 'pie'
        };
        var title = {
            text: chartTitle,
            style: {
                fontSize: { size: '6px' }
            }
        };
        var yAxis = {
            title: {
                text: 'Days'
            }
        };
        var tooltip = {
            pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
        };
        var plotOptions = {
            pie: {
                borderColor: '#000000',
                innerSize: '70%',
                dataLabels: {
                    enabled: true,
                    format: '<b>{point.name}</b>: {point.percentage:.1f} %',
                    style: {
                        color: (Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black'
                    }
                }
            }
        };
        var series = [{
            name: chartTitle,
            colorByPoint: true,
            data: top10,
            size: '60%',
            dataLabels: {
                formatter: function () {
                    return this.y > 5 ? this.point.name : null;
                },
                color: 'white',
                distance: -30
            }
        }];
        var json = {};
        json.chart = chart;
        json.credits = { text: '' };
        json.title = title;
        json.yAxis = yAxis;
        json.tooltip = tooltip;
        json.series = series;
        json.plotOptions = plotOptions;
        console.log('donutChart: json');
        console.log(json);
        $(div).highcharts(json);  
    }
};

从 Chrome 控制台,我可以读取数据中的调试信息。它显示我有数据,但我从未进入循环。

donutChart(Meter Count per Substation (Top 10)) data:
GapMeters.js:272 [ELECTRIC: {…}, Sub 2: {…}, WATER: {…}, Sub 3: {…}, empty: {…}]ELECTRIC: {Name: "ELECTRIC", Days: 2176}Sub 2: {Name: "Sub 2", Days: 797}Sub 3: {Name: "Sub 3", Days: 15}WATER: {Name: "WATER", Days: 243}empty: Days: 15Name: "empty"__proto__: Objectlength: 0__proto__: Array(0)
GapMeters.js:372 donutChart: json
GapMeters.js:373 {chart: {…}, credits: {…}, title: {…}, yAxis: {…}, tooltip: {…}, …}chart: {height: "50%", renderTo: "#divPieSubst", type: "pie"}credits: {text: ""}plotOptions: {pie: {…}}series: [{…}]title: {text: "Meter Count per Substation (Top 10)", style: {…}}tooltip: {pointFormat: "{series.name}: <b>{point.percentage:.1f}%</b>"}yAxis: {title: {…}}__proto__: Object
GapMeters.js:271 

惊喜! Chrome 数据实际上粘贴得很好!

无论如何,我有数据,但是循环中的 console.log 根本没有打印出来。

我做错了什么?

我有一个可以运行的版本。我试图让 JSFiddle 显示我所做的,但我无法弄清楚它的界面:

http://jsfiddle.net/jp2code/q1v4xewc/79/

<div id="divPieSubst"></div>
<div id="divPieFeedr"></div>
<div id="divPieCycle"></div>
<div id="divPieRoute"></div>
<div id="divBarDays"></div>
<div id="grid"></div>
$(function() {

  $(document).ready(function() {
    var e = [];
    e.push({
      Substation: 'ELECTRIC',
      Feeder: '',
      ServiceType: 'Electric',
      Account: '403310300-01',
      Rate: 'SCR2',
      Cycle: '04',
      Route: '4033',
      Customer: 'Customer 403310300-01',
      Address: '',
      Meter: '3P00325',
      Start: '02/04/2015',
      End: '01/19/2021',
      Days: 2176
    });
    e.push({
      Substation: 'Sub 2',
      Feeder: '',
      ServiceType: 'Water',
      Account: '102303446-05',
      Rate: '0',
      Cycle: '01',
      Route: '1023',
      Customer: 'Customer 102303446-05',
      Address: '',
      Meter: '47170023',
      Start: '11/14/2018',
      End: '01/19/2021',
      Days: 797
    });
    e.push({
      Substation: 'WATER',
      Feeder: '',
      ServiceType: 'Water',
      Account: '102001979-07',
      Rate: '0',
      Cycle: '01',
      Route: '1020',
      Customer: 'Customer 102001979-07',
      Address: '',
      Meter: '45234070',
      Start: '01/03/2021',
      End: '01/19/2021',
      Days: 16
    });
    e.push({
      Substation: 'WATER',
      Feeder: '',
      ServiceType: 'Water',
      Account: '103602334-01',
      Rate: '0',
      Cycle: '01',
      Route: '1036',
      Customer: 'Customer 103602334-01',
      Address: '',
      Meter: '45440615',
      Start: '01/03/2021',
      End: '01/19/2021',
      Days: 16
    });
    e.push({
      Substation: 'WATER',
      Feeder: '',
      ServiceType: 'Water',
      Account: '102502791-01',
      Rate: '6',
      Cycle: '01',
      Route: '1025',
      Customer: 'Customer 102502791-01',
      Address: '',
      Meter: '13242857H',
      Start: '01/03/2021',
      End: '01/19/2021',
      Days: 16
    });
    e.push({
      Substation: 'WATER',
      Feeder: '',
      ServiceType: 'Water',
      Account: '401112758-08',
      Rate: '0',
      Cycle: '04',
      Route: '4011',
      Customer: 'Customer 401112758-08',
      Address: '',
      Meter: '44633754',
      Start: '01/04/2021',
      End: '01/19/2021',
      Days: 15
    });
    e.push({
      Substation: 'WATER',
      Feeder: '',
      ServiceType: 'Water',
      Account: '100601731-08',
      Rate: '0',
      Cycle: '01',
      Route: '1006',
      Customer: 'Customer 100601731-08',
      Address: '',
      Meter: '44634197',
      Start: '01/04/2021',
      End: '01/19/2021',
      Days: 15
    });
    e.push({
      Substation: 'WATER',
      Feeder: '',
      ServiceType: 'Water',
      Account: '202802192-03',
      Rate: '0',
      Cycle: '02',
      Route: '2028',
      Customer: 'Customer 202802192-03',
      Address: '',
      Meter: '44633786',
      Start: '01/04/2021',
      End: '01/19/2021',
      Days: 15
    });
    e.push({
      Substation: 'WATER',
      Feeder: '',
      ServiceType: 'Water',
      Account: '201900499-02',
      Rate: '0',
      Cycle: '02',
      Route: '2019',
      Customer: 'Customer 201900499-02',
      Address: '',
      Meter: '44633788',
      Start: '01/04/2021',
      End: '01/19/2021',
      Days: 15
    });
    e.push({
      Substation: 'WATER',
      Feeder: '',
      ServiceType: 'Water',
      Account: '102702268-00',
      Rate: '2',
      Cycle: '01',
      Route: '1027',
      Customer: 'Customer 102702268-00',
      Address: '',
      Meter: '44634247',
      Start: '01/04/2021',
      End: '01/19/2021',
      Days: 15
    });
    e.push({
      Substation: 'WATER',
      Feeder: '',
      ServiceType: 'Water',
      Account: '202602889-09',
      Rate: '0',
      Cycle: '02',
      Route: '2026',
      Customer: 'Customer 202602889-09',
      Address: '',
      Meter: '44634191',
      Start: '01/04/2021',
      End: '01/19/2021',
      Days: 15
    });
    e.push({
      Substation: 'WATER',
      Feeder: '',
      ServiceType: 'Water',
      Account: '102702083-02',
      Rate: '5',
      Cycle: '01',
      Route: '1027',
      Customer: 'Customer 102702083-02',
      Address: '',
      Meter: '13242805H',
      Start: '01/04/2021',
      End: '01/19/2021',
      Days: 15
    });
    e.push({
      Substation: 'WATER',
      Feeder: '',
      ServiceType: 'Water',
      Account: '101606681-01',
      Rate: '5',
      Cycle: '01',
      Route: '1016',
      Customer: 'Customer 101606681-01',
      Address: '',
      Meter: '45059218',
      Start: '01/04/2021',
      End: '01/19/2021',
      Days: 15
    });
    e.push({
      Substation: 'WATER',
      Feeder: '',
      ServiceType: 'Water',
      Account: '100100025-03',
      Rate: '0',
      Cycle: '01',
      Route: '1001',
      Customer: 'Customer 100100025-03',
      Address: '',
      Meter: '45233976',
      Start: '01/04/2021',
      End: '01/19/2021',
      Days: 15
    });
    e.push({
      Substation: 'WATER',
      Feeder: '',
      ServiceType: 'Water',
      Account: '101900421-08',
      Rate: '0',
      Cycle: '01',
      Route: '1019',
      Customer: 'Customer 101900421-08',
      Address: '',
      Meter: '45234013',
      Start: '01/04/2021',
      End: '01/19/2021',
      Days: 15
    });
    e.push({
      Substation: 'Sub 3',
      Feeder: '',
      ServiceType: 'Gas',
      Account: '101900421-08',
      Rate: '0',
      Cycle: '01',
      Route: '1019',
      Customer: 'Customer 101900421-08',
      Address: '',
      Meter: 'G34013',
      Start: '01/04/2021',
      End: '01/19/2021',
      Days: 15
    });
    e.push({
      Substation: 'WATER',
      Feeder: '',
      ServiceType: 'Water',
      Account: '102002727-01',
      Rate: '6',
      Cycle: '01',
      Route: '1020',
      Customer: 'Customer 102002727-01',
      Address: '',
      Meter: '12732616H',
      Start: '01/04/2021',
      End: '01/19/2021',
      Days: 15
    });
    e.push({
      Substation: '',
      Feeder: '',
      ServiceType: '',
      Account: '102202513-00',
      Rate: '2S',
      Cycle: '01',
      Route: '1022',
      Customer: 'Customer 102202513-00',
      Address: '',
      Meter: '44634246',
      Start: '01/04/2021',
      End: '01/19/2021',
      Days: 15
    });
    e.push({
      Substation: 'WATER',
      Feeder: '',
      ServiceType: 'Water',
      Account: '301513750-00',
      Rate: '0',
      Cycle: '03',
      Route: '3015',
      Customer: 'Customer 301513750-00',
      Address: '',
      Meter: '45234068',
      Start: '01/04/2021',
      End: '01/19/2021',
      Days: 15
    });
    e.push({
      Substation: 'WATER',
      Feeder: '',
      ServiceType: 'Water',
      Account: '300911973-01',
      Rate: '0',
      Cycle: '03',
      Route: '3009',
      Customer: 'Customer 300911973-01',
      Address: '',
      Meter: '45234017',
      Start: '01/04/2021',
      End: '01/19/2021',
      Days: 15
    });
    onDataBound(e);
  });

  function onDataBound(e) {
    $('#grid').kendoGrid({
      dataSource: {
        data: e
      },
    });
    var pieSubst = [{
      label: 'Meter Count per Substation (Top 10)',
      data: [],
      rows: []
    }];
    var pieFeedr = [{
      label: 'Meter Count per Feeders (Top 10)',
      data: [],
      rows: []
    }];
    var pieCycle = [{
      label: 'Meter Count per Cycle (Top 10)',
      data: [],
      rows: []
    }];
    var pieRates = [{
      label: 'Meter Count per Rate (Top 10)',
      data: [],
      rows: []
    }];
    var grid = $('#grid').data('kendoGrid');
    $.each(e, function(index, item) {
      formatPieData(pieSubst, item.Substation, item);
      formatPieData(pieFeedr, item.Feeder, item);
      formatPieData(pieCycle, item.Cycle, item);
      formatPieData(pieRates, item.Rate, item);
    });
    donutChart('#divPieSubst', pieSubst);
    donutChart('#divPieFeedr', pieFeedr);
    pieChart('#divPieCycle', pieCycle);
    pieChart('#divPieRates', pieRates);
    barChart('#divBarDays', barData);
  }

  function formatPieData(array, countLabel, item) {
    if ((countLabel == null) || (countLabel == '')) {
      countLabel = '(no label)';
    }
    let dataArray = array[1];
    if (dataArray.data === undefined) { // if there is nothing at position 2,
      dataArray.data = []; // create an empty array (which should have been done in the .ready())
    }
    var data = dataArray.data.find(o => o.Name === countLabel);
    if (data === undefined) { // if array[label] does not exists,
      data = { // create the array entry using
        Name: countLabel, // the label
        Count: 1, // and the days
      };
      dataArray.data.push(data);
    } else { // otherwise...
      data.Count = data.Count + 1; // ...add the days
    }
    array[2].rows.push(item); // push the row data on the end
  }

  function barChart(div, array) { // https://www.tutorialspoint.com/highcharts/highcharts_bar_basic.htm
    var target = $(div);
    if (target != null) {
      var names = [];
      var data1 = [];
      for (var n = array.length - 1; - 1 < n; n--) {
        names.push(array[n].label);
        data1.push(array[n].days);
      }
      var series = [{
        data: data1,
        showInLegend: false,
      }];
      var json = {
        chart: {
          type: 'bar'
        },
        credits: {
          text: ''
        },
        plotOptions: {
          bar: {
            dataLabels: {
              enabled: true
            },
            minPointLength: 5,
          }
        },
        series: series,
        title: {
          text: 'Meter Count per Gap Tier (in Days)',
          style: {
            fontSize: {
              size: '8px'
            }
          },
        },
        tooltip: {
          valueSuffix: ' days'
        },
        xAxis: {
          categories: names,
          labels: {
            enabled: true
          },
          min: 0,
          title: {
            text: null
          }
        },
        yAxix: {
          min: 0,
          labels: {
            enabled: false
          },
        },
      };
      $(div).highcharts(json);
    }
  }

  function donutChart(div, array) { // donut: https://www.tutorialspoint.com/highcharts/highcharts_pie_donut.htm
    var target = $(div);
    if (target != null) {
      var chartTitle = array[0].label;
      array[1].data.sort(function(o1, o2) {
        return o2.Count - o1.Count
      });
      var categories = [];
      var colors = Highcharts.getOptions().colors;
      var colorMax = colors.length - 1;
      var total = 0;
      $.each(array[1].data, function(index, item) { // get count first
        total = total + item.Count;
      });
      var top10 = [];
      $.each(array[1].data.slice(0, 9), function(index, item) { // only interested in 0 to 9 (top 10)
        var name = item.Name;
        if (name == null) {
          name = '(no label)';
        }
        categories.push(name);
        var nColor = index % colorMax; // don't go over the array
        var percent = (item.Count / total) * 100;
        var entry = {
          name: name,
          y: percent,
          color: colors[nColor],
          drilldown: {
            name: name,
            data: item,
            color: colors[nColor],
          }
        };
        top10.push(entry);
      });
      var json = {
        chart: {
          height: percent,
          renderTo: div,
          type: 'pie'
        },
        credits: {
          text: ''
        },
        plotOptions: {
          pie: {
            borderColor: '#000000',
            innerSize: '40%',
            dataLabels: {
              enabled: true,
              format: '{point.name}',
            }
          }
        },
        series: [{
          name: categories,
          colorByPoint: true,
          data: top10,
          dataLabels: {
            format: '{point.name}',
            color: 'white',
            distance: -30
          },
          innerSize: '50%',
          size: '100%',
        }],
        title: {
          text: chartTitle,
          style: {
            fontSize: {
              size: '6px'
            }
          }
        },
        tooltip: {
          pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
        },
        xAxis: {
          categories: categories,
          labels: {
            enabled: true
          },
          min: 0,
          title: {
            text: null
          }
        },
        yAxis: {
          min: 0,
          title: {
            text: 'Count'
          }
        },
      };
      $(div).highcharts(json);
    }
  }

  function pieChart(div, array) { // basic pie: https://www.tutorialspoint.com/highcharts/highcharts_pie_basic.htm
    var target = $(div);
    if (target != null) {
      var chartTitle = array[0].label;
      array[1].data.sort(function(o1, o2) {
        return o2.Count - o1.Count
      });
      var categories = [];
      var colors = Highcharts.getOptions().colors;
      var colorMax = colors.length - 1;
      var total = 0;
      $.each(array[1].data, function(index, item) { // get count first
        total = total + item.Count;
      });
      var top10 = [];
      $.each(array[1].data.slice(0, 9), function(index, item) { // only interested in 0 to 9 (top 10)
        if (item !== undefined) {
          var name = item.Name;
          if (name == null) {
            name = '(no label)';
          }
          categories.push(name);
          var nColor = index % colorMax; // don't go over the array
          var percent = (item.Count / total) * 100;
          var entry = {
            name: name,
            y: percent,
            color: colors[nColor],
            drilldown: {
              name: name,
              data: item,
              color: colors[nColor],
            }
          };
          top10.push(entry);
        }
      });
      var json = {
        chart: {
          height: '50%',
          renderTo: div,
          type: 'pie'
        },
        credits: {
          text: ''
        },
        plotOptions: {
          pie: {
            allowPointSelect: true,
            borderColor: '#000000',
            cursor: 'pointer',
            dataLabels: {
              enabled: true,
              // format: '<b>{point.name}</b>: {point.percentage:.1f} %',
              formatter: function() {
                return 1 < this.y ? '' + this.point.name + ': ' + Highcharts.numberFormat(this.y, 1) + '%' : null;
              },
              style: {
                color: (Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black'
              }
            }
          }
        },
        series: [{
          name: categories,
          colorByPoint: true,
          data: top10,
          dataLabels: {
            formatter: function() {
              return 1 < this.y ? this.point.name : null;
            },
            color: 'white',
            distance: -30
          },
          size: '100%',
        }],
        title: {
          text: chartTitle,
          style: {
            fontSize: {
              size: '6px'
            }
          }
        },
        tooltip: {
          pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
        },
        xAxis: {
          categories: categories,
          labels: {
            enabled: true
          },
          min: 0,
          title: {
            text: null
          }
        },
        yAxis: {
          min: 0,
          title: {
            text: 'Count'
          }
        },
      }
      console.log('pieChart: json');
      console.log(json);
      $(div).highcharts(json);
    }
  }

});

现在似乎没有任何错误(或者我似乎无法让控制台显示)。当控制台 显示错误时,指示的行号似乎与代码中的行号不匹配,所以出现了问题。

我希望这对某人有用。我真的没有看到任何像样的例子说明如何在将数据发送到 Highcharts 之前过滤数据,也没有看到使用单个数据集填充多个 Highchart 图的例子。