本文介绍了避免在d3.layout.stack()["group 1","group 2"]中枚举组名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当未手动列出组时,我很难理解d3.layout.stack().在下面的示例中,类似于我在其他问题中发现的内容,组在[]中列为"Apple",依此类推,但据我所知,必须手动输入.我正在寻找一种无需手动输入苹果",蓝莓"等的方法.

I am having a really hard time understanding d3.layout.stack() when groups are not listed manually. In the below example, similar to what I've found in other questions, groups are listed in [] as "Apple", etc., but as far as I understand this has to be inputted manually. I am seeking a way to not have to manually input "Apple", "Blueberry", etc.

var dataset = d3.layout.stack()(["Apple", "Blueberry", "Lettuce", "Orange"].map(function(fruit) {
      return data.map(function(d) {
        return {x: d.orchard, y: +d[fruit]};
      });
    }));

我尝试在数据对象中插入如下一行,称为名称":

I've tried inserting a line in my data object as below, called 'names':

[{names='Apple','Blueberry','Lettuce','Orange'}, {Apple=1.0, Orange=2.0, Lettuce=1.0, orchard=小明, Blueberry=1.0}, {Apple=1.0, Orange=1.0, Lettuce=1.0, orchard=小陈, Blueberry=1.0}, {Apple=1.0, Orange=1.0, Lettuce=1.0, orchard=小虎, Blueberry=1.0}, {Orange=1.0, Lettuce=1.0, orchard=小桃, Blueberry=1.0, Apple=1.0}]

有没有办法编写类似于下面的代码?

Is there a way to code something similar to below?

var dataset = d3.layout.stack()([d3.keys(names)].map(function(fruit) {

我应该集中精力在数据对象中插入唯一的名称列表,还是通过在d3代码本身中解析数据以累积唯一组名称的列表来做到这一点?

Should I be focused more on inserting a unique list of names into my data object, or do so by parsing my data in my d3 code itself to accumulate a list of unique group names?

我想知道d3.keys逻辑是否有意义,是否也可以将其应用于以下上下文,而不是列举每种情况:

I am wondering, if the d3.keys logic makes sense, if it can be applied to the below context too, instead of enumerating each case:

legend.append("text")
         .attr("x", width + 5)
          .attr("y", 9)
          .attr("dy", ".35em")
          .style("text-anchor", "start")
              .text(function(d, i) {
                for(var j =0; j<4; j++){
                   switch (i) {

                      case j: return d3.keys[j]

//                switch (i) {
//            
//                  case 0: return "orange"
//                  case 1: return "apple"
//                  case 2: return "blueberry"
//                  case 3: return "lettuce"

              }
              }
            });

推荐答案

我最终只是将整个图形转换为d3 v5.以下是一些注释,这些注释基于我与自己的作品混合使用的许多资料来源:

I ended up just converting the entire graph to d3 v5. Below is some notes based off a lot of sources I looked at mixed with my own work:

堆积条的更好做法是使用

Better practice for stacked bar is to use

  .data(d3.stack().keys(keys)(data))

其中

 var keys = d3.keys(data[0]).filter(function(d){
          return d != "orchard";
        });         

或换句话说:

   var keys = d3.keys(data[0]).filter(d => d != "orchard")

这对于用javascript预解析的数据很有用.假设您在csv中只有几列:

This is useful for data that is pre-parsed in javascript. Say you have just columns in a csv:

var keys = csv.columns.slice(0);

很有用,但适用于堆叠的相同原理.

is useful, but same philosophy for stacking applies.

一个小问题:如果您稍后在数据中产生新的类别,即数据[1]而不是数据[0]的一部分是新的水果菠萝,则密钥将无法识别菠萝.它仅响应第一个条目的数据对象.

Slight issue: if you have new categories arising later on in the data, i.e. a new fruit pineapple is part of data[1] but not data[0], key will not identify pineapple. It only responds to the data object of the first entry.

在保持相同过滤器的情况下,不依赖data[1], data[0], etc.,data[0], data[1], etc.的累积"键:

To not rely on data[1], data[0], etc., and "accumulate" keys for data[0], data[1], etc. while maintaining the same filter:

  var key = [];
  for(var i =0; i < d3.keys(data).length; i++){
     var joinin = d3.keys(data[i]).filter(d => d != "orchard")
     var key = key.concat(joinin)
//     console.log(key)  
 }

最有可能编写该代码的一种更好的方法,但解释是:

There's most likely a better way of writing that code, but the explanation is:

如果您编写了这样的内容,您将只获得一组数据的密钥:

If you wrote something like this you'd get keys for only one set of data:

  var key = d3.keys(data[2]).filter(function(d){
          return d != "orchard";
        }); 

如果您编写了此代码,则将获得每次数据迭代的密钥:

If you wrote this you get the keys for each iteration of data:

  var key = [];
  for(var i =0; i < d3.keys(data).length; i++){
     var key = d3.keys(data[i]).filter(d => d != "orchard")
     console.log(key)
     key.push(key);
  }

因此,诀窍是使用for循环获取数据的每次迭代,但将其合并到一个没有重复的单数列表中.

So the trick is to use a for loop to get each iteration of data but concat that into one singular list, which has no repeats.

如果您想要为每个键提供值该怎么办?同样,这是针对这样的数据结构的,这有点不符合常规:

What if you wanted the value given to each key? Again, this is for a data structure like this, which is a little unconventional:

  data = [ 
              {0:
                {"Apple": 1}
                {"orchard": xx}
              }
              {1:
                {"Apple": 2}
                {"orchard": xx}
              }
           ]

您可以使用以下内容,其中key将返回["Apple"],而key_values将返回[1, 2].基本上,过滤器d> 0可防止任何字符串,例如果园名称"xx".与过滤果园相同.

You can use the below, where key will return ["Apple"], and key_values will return [1, 2]. Basically the filter d > 0 prevents any strings, so like names of orchards "xx". Does the same as filtering out orchards.

  var key = [];
  var key_values = [];
  for(var i =0; i < d3.keys(data).length; i++){
     var key_value = d3.entries(data[i]).map(d => d.value).filter(d => d > 0)
     var key_values = key_values.concat(key_value)
     var joinin = d3.keys(data[i]).filter(d => d != "orchard")
     var key = key.concat(joinin)
 }

(EDIT2)关于图例.

(EDIT2) About the legend..

我只是将代码替换为,我知道d3v5可以简化以下(?),

I just replaced my code with, and I know d3v5 can simplify the below(?),

 var legend = svg.selectAll(".legend")
  .data(color.domain())
  .enter()
  .append("g")
  .attr("class","legend")
  .attr("transform",function(d,i) {
    return "translate(1300," + i * 15 + ")";
  });

在我的情况下,输入变量是离散的,例如"Apple"等,而不是整数,因此我们使用scaleOrdinal并仅对域使用"keys".不过,您实际上并不需要编写该代码,我认为它默认为离散变量的输入列表?不知道为什么会这样.

In my case input variables are discrete, like "Apple" etc., not integers, so we use scaleOrdinal and just use "keys" for the domain. You don't really need to write that though, I think it defaults to the input list of discrete variables? Not sure why it works.

  var color =  d3.scaleOrdinal()
       .domain(keys)
    // .range (whatever you want)

这篇关于避免在d3.layout.stack()["group 1","group 2"]中枚举组名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-26 23:26