将对象的属性转换为数组

时间:2017-03-25 05:50:59

标签: javascript arrays d3.js

我正在创建一个带有D3的气泡图,我可以使用虚拟数据构建图表,但是当我尝试使用我的实时数据时,图表无法正常工作。我理解为什么它不起作用,因为数据以D3的格式出现。我只是不知道如何使用JavaScript重新组织数据。

我的数据存储在这样的对象中:

datas = {fieldA:[Array[32]], fieldB[Array[32]]};

属性中的Array看起来像这样:

Array[Object,Object,Object...]

我需要的数据是名为raw_data

的对象数组中的属性

所以要访问其中一个数据点,它看起来像这样:

datas.fieldA[0].raw_data

我需要像这样访问数据:

datas[0].fieldA.raw_data

这将允许我在我的D3 viz中绑定datas并且可以访问fieldA和fieldB。现在,我可以绑定datas.fieldA这是一个问题,因为我需要两个字段来创建它。

如果有帮助的话,下面是我写的实际d3代码。我可以创建圆圈,但现在需要将文字附加到圆圈。真实的字段名称是countword和word。

    var h = options.dataset.chart_information.height;
    var w = options.dataset.chart_information.width;
    var margin = {left:5, right:5, top:5, bottom:5};
    var dataWord = options.dataset.data.countword;
    var dataText = options.dataset.data.word;



    var simulation = d3.forceSimulation()
                        .force("x", d3.forceX(w/2).strength(0.05))
                        .force("y", d3.forceY(h/2).strength(0.05))
                        .force("collide", d3.forceCollide(function(d) { return rScale(d.raw_data) + 0.2; }));

    var rScale = d3.scaleSqrt()
                    .domain([d3.min(dataWord, function(d) { return d.raw_data; }), 
                            d3.max(dataWord, function(d) { return d.raw_data; })])
                    .range([10,60]);

    var svg = d3.select(options.divSelector)
                .append("svg")
                .attr("height",h)
                .attr("width",w);

    var circles = svg.selectAll(".circle")
                    .data(dataWord)
                    .enter()
                    .append("circle")
                        .attr("r", function(d) { return rScale(d.raw_data); })
                        .attr("fill","steelblue");

    simulation.nodes(dataWord)
                .on("tick", ticked);

    function ticked() {
        circles
            .attr("cx", function(d) { return d.x })
            .attr("cy", function(d) { return d.y });
    };

3 个答案:

答案 0 :(得分:2)

这是一种处理数组的功能方法。请注意,结果中对象的数量将是所有字段的最小值(在这种情况下为fieldA和fieldB)。如果字段长度不同,那只会是一个问题。我在其间放了一些console.log来解释路上的步骤。显然,这些日志和变量赋值不是必需的 - 代码可以缩短...... Object.assign是ES2015(ES6)代码 - 如果这是一个必须替换的问题,可能就像here



var datas = {fieldA:[ { rawdata:'a1'}, { rawdata:'a2' }, { rawdata:'a3' } ], fieldB: [ { rawdata:'b1'}, { rawdata:'b2'} ]};

// transform each field to contain it‘s name
var fields = Object.keys(datas).map(function(fieldName) {
  return datas[fieldName].map(function(value) {
    let object = {};
    object[fieldName] = value;
    return object;
  });
});
console.log(fields);

// use d3.zip to transpose
var zipped = d3.zip.apply(null, fields);
console.log(zipped);

// merge objects in array
var result = zipped.map(function(objects) {
  return Object.assign.apply(null, objects);
});

console.log(result);

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

如果我理解正确的话。你有一个像这样的对象:

datas = {fieldA:[{raw_date:0}, {raw_date:1}], fieldB[{raw_date:0}, {raw_date:1}]};

并且您想将其转换为格式如下的数组:

datas = [{fieldA:{raw_date:0, raw_date:1}, {fieldB{raw_date:0, raw_date:1}}];

如果是这种情况,你可以这样做:

var org = {fieldA:[{raw_data:0}, {raw_data:1}], fieldB:[{raw_data:0}, {raw_data:1}]};

var reformatted = [];
for(var i = 0; i < Math.min(org.fieldA.length, org.fieldB.length); i++){  
  reformatted.push({filedA:{raw_data:org.fieldA[i].raw_data}, fieldB:{raw_data:org.fieldB[i].raw_data}});
}

console.log(reformatted);

答案 2 :(得分:-1)

var datas= {
    fieldA: [1, 2, 3],
    filedB: [4, 5, 6]
};

var array = $.map(datas, function(value, index) {
    return [value];
});