javascript 改进 D3 序列森伯斯特示例

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24582083/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 03:05:12  来源:igfitidea点击:

Improving D3 Sequence Sunburst Example

javascriptsvgd3.jslegendsunburst-diagram

提问by VividD

This D3example served as my starting point:

这个D3例子是我的起点:

http://bl.ocks.org/kerryrodden/7090426

http://bl.ocks.org/kerryrodden/7090426

enter image description here

在此处输入图片说明



I wanted to change data that feeds the diagram, and I made following new example:

我想更改提供图表的数据,并制作了以下新示例

http://jsfiddle.net/ZGVK3/

http://jsfiddle.net/ZGVK3/

enter image description here

在此处输入图片说明

One can notice at least two problems:

人们至少可以注意到两个问题:

  1. Legend is wrong. This is because it still contains 'hardcoded' names from original example.
  2. All nodes are colored black. This is because the color scheme is also 'hardcoded' only for node names from original example.
  1. 传说错了。这是因为它仍然包含来自原始示例的“硬编码”名称。
  2. 所有节点都为黑色。这是因为配色方案也仅针对原始示例中的节点名称进行了“硬编码”。

How to improve the original example (or my jsfiddle, it doesn't matter) so that legend and coloring are self-adjusted to the data that feeds the diagram?

如何改进原始示例(或我的 jsfiddle,无关紧要),以便图例和着色能够根据提供图表的数据进行自我调整?

回答by jshanley

You can use an ordinal scale to map colors to the different node names. Implementing it would only require a few minor changes to your existing code.

您可以使用序数比例将颜色映射到不同的节点名称。实现它只需要对现有代码进行一些小的更改。

Step 1. Create an ordinal scale for the colors

步骤 1. 为颜色创建一个序数比例

Instead of having colorsbe simply a list of color names, hard-coded to specific names, use d3.scale.ordinal(), and set the .range()to be an array of the colors you want to use. For example:

而不是colors简单的颜色名称列表,硬编码为特定名称,使用d3.scale.ordinal(),并将 设置为.range()您想要使用的颜色数组。例如:

var colors = d3.scale.ordinal()
  .range(["#5687d1","#7b615c","#de783b","#6ab975","#a173d1","#bbbbbb"]);

This would create an ordinal scale that uses the same colors as the original visualization. Since your data would require more colors, you would want to add a few more to your range, otherwise colors will be repeated.

这将创建一个使用与原始可视化相同颜色的序数比例。由于您的数据需要更多颜色,因此您需要在范围内添加更多颜色,否则颜色会重复。

As a shortcut, you can use d3.scale.category20()to let d3 choose a range 20 categorical colors for you.

作为一种快捷方式,您可以使用d3.scale.category20()让 d3 为您选择 20 种分类颜色。

Now when setting the fill colors for your pathelement arcs and also your breadcrumbs, you would simply use colors(d.name)instead of colors[d.name].

现在为您设置填充颜色时,path元素弧线,也是你的面包屑,你会简单地使用colors(d.name)代替colors[d.name]

Step 2. Use your data to construct the domain of the scale

步骤 2. 使用您的数据构建尺度域

The .domain()of this scale will be set once we have the data, since it will depend on a list of the unique names contained in the data. To do this, we can loop through the data, and create an array of the unique names. There are probably several ways to do this, but here's one that works well:

.domain()这个规模将被设置一旦我们得到的数据,因为这将取决于独特的名单上包含的数据。为此,我们可以遍历数据,并创建一个唯一名称数组。可能有几种方法可以做到这一点,但这里有一种效果很好:

var uniqueNames = (function(a) {
  var output = [];
  a.forEach(function(d) {
    if (output.indexOf(d.name) === -1) {
      output.push(d.name);
    }
  });
  return output;
})(nodes);

This creates an empty array, then loops through each element of the nodesarray and if the node's name doesn't already exist in the new array, it is added.

这将创建一个空数组,然后遍历数组的每个元素,nodes如果新数组中不存在该节点的名称,则会添加它。

Then you can simply set the new array to be the domain of the color scale:

然后您可以简单地将新数组设置为色标的域:

colors.domain(uniqueNames);

Step 3. Use the scale's domain to build the legend

步骤 3. 使用比例的域来构建图例

Since the legend is going to depend on the domain, make sure the drawLegend()function is called after the domain is set.

由于图例将取决于域,因此请确保在drawLegend()设置域后调用该函数。

You can find the number of elements in the domain (for setting the height of the legend) by calling colors.domain().length. Then for the legend's .data(), you can use the domain itself. Finally, to set the fill color for the legend boxes, you call the color scale on dsince each element in the domain is a name. Here's what those three changes to the legend look like in practice:

您可以通过调用来查找域中的元素数量(用于设置图例的高度)colors.domain().length。然后对于图例的.data(),您可以使用域本身。最后,要设置图例框的填充颜色,请调用色标 on,d因为域中的每个元素都是name. 以下是图例的这三个更改在实践中的样子:

var legend = d3.select("#legend").append("svg:svg")
  .attr("width", li.w)
  .attr("height", colors.domain().length * (li.h + li.s));

var g = legend.selectAll("g")
  .data(colors.domain())
  .enter().append("svg:g")
  .attr("transform", function(d, i) {
     return "translate(0," + i * (li.h + li.s) + ")";
  });

g.append("svg:rect")
  .attr("rx", li.r)
  .attr("ry", li.r)
  .attr("width", li.w)
  .attr("height", li.h)
  .style("fill", function(d) { return colors(d); });

And that's about it. Hope that helps.

就是这样。希望有帮助。

Here's the updated JSFiddle.

这是更新的JSFiddle