【问题标题】:Map data from an array for only some keys (not filtered)仅针对某些键(未过滤)从数组映射数据
【发布时间】:2018-05-03 14:34:34
【问题描述】:

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

一些键名不是很有帮助,所以我正在尝试编写一个映射函数来传递一些不同的字符串,但其他键名很好,所以我想跳过那些或正常返回它们。

如果未声明键名,我的函数将返回未定义。名称也没有添加到图例中。

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

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

这里有一个完整的 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

【问题讨论】:

    标签: javascript arrays d3.js mapping


    【解决方案1】:

    您可以使用.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);

    【讨论】:

    • 好极了,这似乎是一条更好的路线。因为我仍然可以将原始数据对象传递给各种 d3 函数。谢谢。
    • 有时很难选择。
    【解决方案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);

    【讨论】:

    • 好的,谢谢。也许跳过是错误的词。我不想减少集合。我仍然想推 'KO''OK''OOS' 应该读为 'Out of scope',如果这有意义的话。
    猜你喜欢
    • 1970-01-01
    • 2021-04-19
    • 2017-05-26
    • 2020-11-12
    • 2019-09-29
    • 1970-01-01
    • 2020-11-21
    • 2020-03-17
    • 2020-11-23
    相关资源
    最近更新 更多