简体   繁体   English

将JSON数据转换为Highcharts基本折线图中的格式

[英]Convert JSON data into format in Highcharts' basic line chart

Using Javascript, I am trying to convert some JSON data into the format used in Highcharts' basic line chart. 我正在尝试使用Javascript将一些JSON数据转换为Highcharts基本折线图中使用的格式。

What I have to start with: 我必须从以下内容开始:

originalArray = [
    ['valueA', 1],
    ['valueA', 0],
    ['valueB', 9],
    ['valueB', 9],
    ['valueB', 3],
    ['valueC', 11]
]

And what I'm trying to create using the above: 而我正在尝试使用以上内容创建:

desiredArray = [{
      name: 'valueA',
      data: [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
  }, {
    name: 'valueB',
    data: [0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0]
  }, {
    name: 'valueC',
    data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
  }]

For some additional context, the 0-11 in originalArray[i][1] references a month (0 = January), and the desiredArray is a list of unique names and a count of their occurrences by month. 对于某些其他上下文, originalArray[i][1]的0-11表示一个月(0 =一月),而desiredArray是唯一名称的列表以及它们按月出现的次数。

So far, I can: 到目前为止,我可以:

  • Convert the data into a new array of objects 将数据转换为新的对象数组
  • For each unique name in originalArray 对于originalArray每个唯一名称
    • Create a new object in the desiredArray , and set the name attribute desiredArray创建一个新对象,并设置name属性
    • Add a data attribute that contains an empty array 添加一个包含空数组的data属性

But then I run into trouble, and can't figure out how to: 但是后来我遇到了麻烦,无法弄清楚如何:

  • Loop through the originalArray 遍历originalArray
    • If the name in the originalArray matches the name in the desiredArray 如果originalArray中的名称与desiredArray中的名称匹配
      • Increment a counter in the matching seriesArray[i].data array, using the value of originalArray[i][1] as the index (it always be 0-11). 使用originalArray[i][1]作为索引(始终为0-11),在匹配的seriesArray[i].data数组中增加一个计数器。

So I'm asking: 所以我问:

  1. What's a good way to iterate across my originalArray , match up unique values, and then act only on those matches to push to the desiredArray . 遍历我的originalArray ,匹配唯一值, 然后仅对那些匹配进行操作以推送到所需的desiredArray的好方法是什么?
  2. What's the best way to increment the counters in desiredArray[i].data 什么是增加desiredArray[i].data计数器的最佳方法

I'm open to using libraries, such as underscore.js. 我愿意使用诸如underscore.js之类的库。 Have been trying to figure this out for a couple of days now, so pretty much anything goes within the bounds of Javascript. 几天来一直在试图解决这个问题,所以几乎所有事情都在Javascript的范围内。

Updated with proper array initialization, now. 现在,使用正确的数组初始化进行了更新。

var max = originalArray.reduce(function(p,c){return Math.max(p,c[1]);},0);

var initSums = function(size) {
    var arr = new Array(size);
    for (var i=0;i<size;i++)
        arr[i]=0;
    return arr;
}

var map = originalArray.reduce(function(sums,val){
    if (!sums.hasOwnProperty(val[0])) {
        sums[val[0]] = initSums(max+1);   
    }
    sums[val[0]][val[1]]++;
    return sums;
},{});

var desiredArray = Object.keys(map).map(function(key) {
    return {name: key, data: map[key]}; 
});

What we're doing here is a multi-step process: 我们在这里所做的是一个多步骤过程:

  1. Decide how big our arrays are going to need to be, by first scanning for the largest value in the original array. 通过首先扫描原始数组中的最大值来确定数组的大小。

  2. Use an object to aggregate the counts (using Array.reduce() ). 使用一个对象来聚合计数(使用Array.reduce() )。

  3. Transform the object and its properties into an array of name/data pair objects (using Array.map ). 将对象及其属性转换为名称/数据对对象数组(使用Array.map )。

Edit : An improvement on S McCochran's solution, skipping the extraneous search for the maximum value in originalArray , since there should always be 12 elements of each data array, one per month. 编辑 :对S McCochran解决方案的改进,跳过了对originalArray最大值的多余搜索,因为每个数据数组应始终有12个元素,每月一个。

function formatForHighcharts(array) {

  // Create a map from value name to array of month counts
  var map = originalArray.reduce(function(sums, pair) {
    var key = pair[0], val = pair[1];

    if(!(key in sums))
      sums[key] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];

    // val is the month index, which corresponds directly to array index, so increase that
    sums[key][val]++;

    return sums;
  }, {});

  // Map the object to an array of { name: ..., data: ... } pairs
  var formatted = Object.keys(map).map(function (key) {
    return { name: key, data: map[key] };
  });

  return formatted;
}

Usage: 用法:

var desiredArray = formatForHighcharts(originalArray);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM