按数组中的对象属性分组 [英] group by object attributes in array

查看:143
本文介绍了按数组中的对象属性分组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用对象中的这些属性创建任意组的列和行:

I'm trying to create arbitrary groups of columns and rows using these attributes in the objects:

        var svg = d3.select("#right-section").append("svg").attr("width",600).attr("height",600);
        var flatInputMatrix = [1,1,1,0,0,3,3,3,0,0,4,4,4,0,0,5,5,5,0,0,0,2,0,4,4,0,0,0,5,5,0,1,0,2,2];
        var m = 5;
        var r = 3;

        var counter = -1;

        var data = flatInputMatrix.map(function(d, i) {
          i % m === 0 ? counter++ : null;
          return {
            column: i % m,
            row: counter,
            value: d
          };
        });

        var columnsGroups = svg.append("g")
        var columns = columnsGroups.selectAll("columns").data(data.column= this.column).enter()

        var numbers = svg.selectAll("numbers").data(data).enter().append("text")
            .attr("x",function(d,i) { return (i % m)*50 + 10 + r; })
            .attr("y",function(d,i) { return Math.floor(i / m) *50+50; })
            .style("opacity", 0.5)
            .text(function(d) { return d.value; })
            .on("mouseover", function(d.columns){d3.select(this).style("opacity", 1)  })

这个想法是让一列(后来的一组列)在被光标悬停时的不透明度= 1.

The idea is to have a column (later a group of columns) have the opacity = 1 when it is hovered over by the cursor.

推荐答案

解决方案1 ​​

由于您要按列分组,因此我相信最好的方法是先嵌套您的数据(当然是按列):

Since you want to group by columns, I believe the best approach is nesting your data first (by columns, of course):

var nested = d3.nest()
    .key(function(d) {
        return d.column
    })
    .entries(data);

然后,我们附加不同的组,每列一个:

Then, we append different groups, one for each column:

var columns = svg.selectAll("foo")
    .data(nested)
    .enter()
    .append("g")
    .attr("transform", function(d) {
        return "translate(" + (50 + 50 * d.key) + ",0)";
    })
    .style("opacity", 0.5);

最后,我们设置mouseover:

columns.on("mouseover", function() {
    d3.select(this).style("opacity", 1);
}).on("mouseout", function() {
    d3.select(this).style("opacity", 0.5)
})

这是演示:

var svg = d3.select("body").append("svg").attr("width", 600).attr("height", 600);

var flatInputMatrix = [1, 1, 1, 0, 0, 3, 3, 3, 0, 0, 4, 4, 4, 0, 0, 5, 5, 5, 0, 0, 0, 2, 0, 4, 4, 0, 0, 0, 5, 5, 0, 1, 0, 2, 2];
var m = 5;
var r = 3;

var counter = -1;

var data = flatInputMatrix.map(function(d, i) {
  i % m === 0 ? counter++ : null;
  return {
    column: i % m,
    row: counter,
    value: d
  };
});

var nested = d3.nest()
  .key(function(d) {
    return d.column
  })
  .entries(data);

var columns = svg.selectAll("foo")
  .data(nested)
  .enter()
  .append("g")
  .attr("transform", function(d) {
    return "translate(" + (50 + 50 * d.key) + ",0)";
  })
  .style("opacity", 0.5);

var numbers = columns.selectAll("foo")
  .data(function(d) {
    return d.values
  })
  .enter()
  .append("text")
  .attr("y", function(d) {
    return d.row * 50 + 50;
  })
  .text(function(d) {
    return d.value;
  });

columns.on("mouseover", function() {
  d3.select(this).style("opacity", 1);
}).on("mouseout", function() {
  d3.select(this).style("opacity", 0.5)
})

<script src="https://d3js.org/d3.v4.min.js"></script>

解决方案#2

但是,如果您不想实质性地重构代码,则只需在mouseover函数中使用数据:

However, if you don't want to substantially refactor your code, you can simply use the datum in the mouseover function:

numbers.on("mouseover", function(d) {
    var column = d.column;
    numbers.filter(function(d) {
            return d.column === column
        })
        .style("opacity", 1)
}).on("mouseout", function() {
    numbers.style("opacity", 0.5)
})

这样,您可以像现在一样保留代码.这是演示:

That way, you can keep your code just like it is right now. Here is the demo:

var svg = d3.select("body").append("svg").attr("width", 600).attr("height", 600);

var flatInputMatrix = [1, 1, 1, 0, 0, 3, 3, 3, 0, 0, 4, 4, 4, 0, 0, 5, 5, 5, 0, 0, 0, 2, 0, 4, 4, 0, 0, 0, 5, 5, 0, 1, 0, 2, 2];
var m = 5;
var r = 3;

var counter = -1;

var data = flatInputMatrix.map(function(d, i) {
  i % m === 0 ? counter++ : null;
  return {
    column: i % m,
    row: counter,
    value: d
  };
});

var numbers = svg.selectAll("numbers")
  .data(data)
  .enter()
  .append("text")
  .attr("x", function(d, i) {
    return (i % m) * 50 + 10 + r;
  })
  .attr("y", function(d, i) {
    return Math.floor(i / m) * 50 + 50;
  })
  .style("opacity", 0.5)
  .text(function(d) {
    return d.value;
  });

numbers.on("mouseover", function(d) {
  var column = d.column;
  numbers.filter(function(d) {
      return d.column === column
    })
    .style("opacity", 1)
}).on("mouseout", function() {
  numbers.style("opacity", 0.5)
})

<script src="https://d3js.org/d3.v4.min.js"></script>

这篇关于按数组中的对象属性分组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆