Jquery - 计算 JSON 对象

Jquery - Counting JSON objects

本文关键字:对象 JSON 计算 Jquery      更新时间:2023-09-26

我正在构建一个图表系统,该系统将显示所有数据条目。我使用 ajax 检索数据,循环遍历数据并按颜色(红色、蓝色和黄色)对结果进行分组,然后按月划分。

我设置了基本对象(dateCounts_Red、dateCounts_Blue 和 dateCounts_Yellow),以便默认情况下它从 0 开始所有月份。然后,当计数器找到与专有颜色和月份的匹配项时,计数器将添加。

当我输出我的日期计数时,我得到:

{"2015":{"2015-12":1,"2015-10":null,"2015-08":null,"2015-11":null}}
{"2015":{"2015-12":0,"2015-10":null}}
{"2015":{"2015-12":0,"2015-10":null}}

这是我到目前为止的代码:

var dateCounts_Red = {"2015":{"2015-01":0,"2015-02":0,"2015-03":0,"2015-04":0},"2015":{"2015-05":0},"2015":{"2015-06":0},"2015":{"2015-07":0},"2015":{"2015-08":0},"2015":{"2015-09":0},"2015":{"2015-10":0},"2015":{"2015-11":0},"2015":{"2015-12":0}};
var dateCounts_Blue = {"2015":{"2015-01":0,"2015-02":0,"2015-03":0,"2015-04":0},"2015":{"2015-05":0},"2015":{"2015-06":0},"2015":{"2015-07":0},"2015":{"2015-08":0},"2015":{"2015-09":0},"2015":{"2015-10":0},"2015":{"2015-11":0},"2015":{"2015-12":0}};
var dateCounts_Yellow = {"2015":{"2015-01":0,"2015-02":0,"2015-03":0,"2015-04":0},"2015":{"2015-05":0},"2015":{"2015-06":0},"2015":{"2015-07":0},"2015":{"2015-08":0},"2015":{"2015-09":0},"2015":{"2015-10":0},"2015":{"2015-11":0},"2015":{"2015-12":0}};
data.d.results.forEach(function(element) {
  var date = element.created_date.slice(0, 7);
  var yr = date.slice(0, 4);
  var Color = element.colorvalue;
  if(Color == "red") {
  dateCounts_Red[yr][date]++;
  }
  if(Color == "blue"){
  dateCounts_Blue[yr][date]++;
  }
  if(Color == "yellow"){
  dateCounts_Yellow[yr][date]++;
  }
});
Red_yr_2015_data = [dateCounts_Red['2015']['2015-01'], dateCounts_Red['2015']['2015-02'], dateCounts_Red['2015']['2015-03'], dateCounts_Red['2015']['2015-04'], dateCounts_Red['2015']['2015-05'], dateCounts_Red['2015']['2015-06'], dateCounts_Red['2015']['2015-07'], dateCounts_Red['2015']['2015-08'], dateCounts_Red['2015']['2015-09'], dateCounts_Red['2015']['2015-10'], dateCounts_Red['2015']['2015-11'], dateCounts_Red['2015']['2015-12']];
Blue_yr_2015_data = [dateCounts_Blue['2015']['2015-01'], dateCounts_Blue['2015']['2015-02'], dateCounts_Blue['2015']['2015-03'], dateCounts_Blue['2015']['2015-04'], dateCounts_Blue['2015']['2015-05'], dateCounts_Blue['2015']['2015-06'], dateCounts_Blue['2015']['2015-07'], dateCounts_Blue['2015']['2015-08'], dateCounts_Blue['2015']['2015-09'], dateCounts_Blue['2015']['2015-10'], dateCounts_Blue['2015']['2015-11'], dateCounts_Blue['2015']['2015-12']];
Yellow_yr_2015_data = [dateCounts_Yellow['2015']['2015-01'], dateCounts_Yellow['2015']['2015-02'], dateCounts_Yellow['2015']['2015-03'], dateCounts_Yellow['2015']['2015-04'], dateCounts_Yellow['2015']['2015-05'], dateCounts_Yellow['2015']['2015-06'], dateCounts_Yellow['2015']['2015-07'], dateCounts_Yellow['2015']['2015-08'], dateCounts_Yellow['2015']['2015-09'], dateCounts_Yellow['2015']['2015-10'], dateCounts_Yellow['2015']['2015-11'], dateCounts_Yellow['2015']['2015-12']];

我目前从我的Highcharts js收到以下错误:

Uncaught TypeError: Cannot set property 'index' of undefined

这阻止了图表系统正常工作,返回的数据未与其预期数据一起返回。

这里有一个完整的问题示例 https://jsfiddle.net/awo5aaqb/21/

有谁知道我错过了什么?

日期计数对象存在重大结构缺陷。

当您美化它们时,它们看起来像:

var dateCounts_Blue = {
      "2015": {
        "2015-01": 0,
        "2015-02": 0,
        "2015-03": 0,
        "2015-04": 0
      },
      "2015": {
        "2015-05": 0
      },
      "2015": {
        "2015-06": 0
      },
      "2015": {
        "2015-07": 0
      },
       ......

对象键必须是唯一的,以便这些键明显重复,编译器将覆盖重复项。

修复在开始时脱离预期模式分组的模式

var dateCounts_Red = {
"2015":
{
"2015-01":0,
"2015-02":0,
"2015-03":0,
"2015-04":0,
"2015-05":0,
"2015-06":0,
"2015-07":0,
"2015-08":0,
"2015-09":0,
"2015-10":0,
"2015-11":0,
"2015-12":0
},
};
var dateCounts_Blue = {
"2015":{
"2015-01":0,
"2015-02":0,
"2015-03":0,
"2015-04":0,
"2015-05":0,
"2015-06":0,
"2015-07":0,
"2015-08":0,
"2015-09":0,
"2015-10":0, 
"2015-11":0,
"2015-12":0
}
};
var dateCounts_Yellow = {
"2015":{
"2015-01":0,
"2015-02":0,
"2015-03":0,
"2015-04":0,
"2015-05":0,
"2015-06":0,
"2015-07":0,
"2015-08":0,
"2015-09":0,
"2015-10":0,
"2015-11":0,
"2015-12":0}
};

您的数据结构存在缺陷,并且在执行foreach循环时,这种比较值变得不一致,因为它将其与多个值进行比较,上述JSON可以解决您的问题。

不是很 codereview.stackexchange.com,但我大量修改了你的javascript,让它工作得更好一点

$.ajax({
  url: basePath,
  dataType: 'json',
  cache: false,
  success: function(data) {
    var counts = {};
    data.d.results.forEach(function(element) {
      // If you know it's all the same year, you could totally ignore this
      var yr = element.created_date.slice(0, 4);
      var month = parseInt(element.created_date.slice(5,7));
      var color = element.colorvalue;
      if (counts[color] === undefined) {
        counts[color] = {};
      }
      if (counts[color][yr] === undefined) {
        counts[color][yr] = {};
      }
      current_value = counts[color][yr][month];
      if (current_value === undefined) {
        // Doesnt exist yet, so add it
        counts[color][yr][month] = 1;
      } else {
        // Exists, so increment by 1
        counts[color][yr][month] = current_value + 1;
      }
    });
    console.log(JSON.stringify(counts));
    console.log(transform_series(counts['red']['2015']));
    console.log(transform_series(counts['blue']['2015']));
    console.log(transform_series(counts['yellow']['2015']));
    var Options = {
      chart: {
        renderTo: 'myfirstchart',
        type: 'column',
        margin: 75,
        options3d: {
          enabled: true,
          alpha: 25,
          beta: 0,
          depth: 70
        }
      },
      title: {
        text: "Test Highcharts"
      },
      subtitle: {
        text: 'Test charts'
      },
      plotOptions: {
        column: {
          depth: 25
        }
      },
      xAxis: {
        categories: ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"]
      },
      yAxis: {
        title: {
          text: "Number of entries"
        }
      },
      tooltip: {
        headerFormat: '<b>{point.key}</b><br>',
        pointFormat: '<span style="color:{series.color}">'u25CF</span> {series.name}: {point.y} / {point.stackTotal}'
      },
      plotOptions: {
        column: {
          stacking: 'normal',
          depth: 40
        }
      },
      series: [{
        name: 'Red',
        color: 'red',
        data: transform_series(counts['red']['2015']),
        stack: '2015'
      }, {
        name: 'Blue',
        color: 'blue',
        data: transform_series(counts['blue']['2015']),
        stack: '2015'
      }, {
        name: 'Yellow',
        color: 'yellow',
        data: transform_series(counts['yellow']['2015']),
        stack: '2015'
      }]
    };
    return new Highcharts.Chart(Options);
  }
});

// this transforms the hash {10: 5, 11:1, 12:1} to get you all 12 months
// and returns an array of values [ 0, 0, 0, 0, 0 ... 5, 1, 1] that
// can be used in high charts
function transform_series(series) {
        return Array.apply(null, Array(13)).map(function (_, i) {return (series[i] === undefined) ? 0 : series[i];}).slice(1,13);
}