仅针对某些键(未过滤)从数组映射数据

时间:2017-11-20 11:25:27

标签: javascript arrays d3.js mapping

我有一张d3饼图。它从json文件中读取数据(在本例中,它只是一个数组变量)。

一些关键名称不是很有帮助,所以我试着编写一个map函数来传递一些不同的字符串,但是其他的关键名称都没问题,所以我想跳过它们或正常返回它们。

如果未声明键名,则我的函数返回undefined。此名称也未添加到图例中。

我确实知道所有的关键名称,但我宁愿继续我尚未定义的关键名称,因为它们可以按原样返回,如果可能的话(我认为else/if带有{continue 1}}条件)。如果将新密钥添加到数据中,此代码将更有用。

我测试了一个声明了所有键名的版本,它停止抛出一个未定义的变量,但是没有将新的键名追加到图例中。

这里有一个完整的jsfiddle:https://jsfiddle.net/lharby/ugweordj/6/

这是我的js函数(截断)。

 var w = 400,
    h = 400,
    r = 180,
    inner = 70,
    color = d3.scale.category20c();

data = [{"label":"OOS", "value":194}, 
        {"label":"TH10", "value":567}, 
        {"label":"OK", "value":1314},
        {"label":"KO", "value":793},
        {"label":"Spark", "value":1929}];

mapData = data.map(function(d){
    if(d.label == 'OOS'){
        return 'Out of scope';
    }else if(d.label == 'TH10'){
        return 'Threshold 10';
    }else{
       // I don't care about the other keys, they can map as they are. 
        continue;
    }
});

var total = d3.sum(data, function(d) {
    return d3.sum(d3.values(d));
});

var vis = d3.select("#chart")
    .append("svg:svg")
    .data([data])
    .attr("width", w)
    .attr("height", h)
    .append("svg:g")
    .attr("transform", "translate(" + r * 1.1 + "," + r * 1.1 + ")")

var arc = d3.svg.arc()
    .innerRadius(inner)
    .outerRadius(r);

var pie = d3.layout.pie()
    .value(function(d) { return d.value; });

var arcs = vis.selectAll("g.slice")
    .data(pie)
    .enter()
    ///
    };

arcs.append("svg:path")
    .attr("fill", function(d, i) { return color(i); } )
    .attr("d", arc);

var legend = d3.select("#chart").append("svg")
    .attr("class", "legend")
    .attr("width", r)
    .attr("height", r * 2)
    .selectAll("g")
    .data(mapData) // returning mapData up until undefined variables
    .enter().append("g")
    .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });

legend.append("rect")
    .attr("width", 18)
    .attr("height", 18)
    .style("fill", function(d, i) { return color(i); });

legend.append("text")
    .attr("x", 24)
    .attr("y", 9)
    .attr("dy", ".35em")
    .text(function(d) { return d.label; }); // should this point to a reference in mapData? 

HTML是一个id为#chart的简单元素。

2 个答案:

答案 0 :(得分:2)

无法使用map跳过元素。但是,您可以使用reduce

跳过它们

var data = [
    {"label":"OOS", "value":194}, 
    {"label":"TH10", "value":567}, 
    {"label":"OK", "value":1314},
    {"label":"KO", "value":793},
    {"label":"Spark", "value":1929}
];

var mapData = data.reduce(function(result, d) {
    if (d.label == 'OOS') {
        result.push('Out of scope');
    } else if (d.label == 'TH10') {
        result.push('Threshold 10');
    };
    return result;
}, []);

console.log(mapData)

编辑:在您comment之后,您希望的结果更清晰。您可以使用map执行此操作,只需返回属性的值:

var data = [{"label":"OOS", "value":194}, 
        {"label":"TH10", "value":567}, 
        {"label":"OK", "value":1314},
        {"label":"KO", "value":793},
        {"label":"Spark", "value":1929}];

var mapData = data.map(function(d) {
  if (d.label == 'OOS') {
    return 'Out of scope';
  } else if (d.label == 'TH10') {
    return 'Threshold 10';
  } else {
    return d.label
  }
});

console.log(mapData);

答案 1 :(得分:2)

您可以使用.forEach()来迭代您的数据,只更改感兴趣的标签,同时保持所有其他标签不变:

data = [{"label":"OOS", "value":194}, 
        {"label":"TH10", "value":567}, 
        {"label":"OK", "value":1314},
        {"label":"KO", "value":793},
        {"label":"Spark", "value":1929}];

data.forEach(d => {
  if(d.label == 'OOS'){
    d.label = 'Out of scope';
  } else if(d.label == 'TH10'){
    d.label = 'Threshold 10';
  }
});

console.log(data);