改进D3序列旭日例子

Viv*_*idD 6 javascript svg legend d3.js sunburst-diagram

这个D3例子是我的出发点:

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

在此输入图像描述


我想更改提供图表的数据,我做了以下新示例:

http://jsfiddle.net/ZGVK3/

在此输入图像描述

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

  1. 传说是错的.这是因为它仍然包含原始示例中的"硬编码"名称.
  2. 所有节点都是黑色的.这是因为颜色方案也仅对原始示例中的节点名称进行"硬编码".

如何改进原始示例(或者我的jsfiddle,它没关系),以便图例和颜色可以自动调整到提供图表的数据?

jsh*_*ley 10

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

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

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

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

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

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

现在,在为path元素弧和面包屑设置填充颜色时,您只需使用colors(d.name)而不是colors[d.name].

步骤2.使用您的数据构建比例域

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

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

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

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

colors.domain(uniqueNames);
Run Code Online (Sandbox Code Playgroud)

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

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

您可以通过调用找到域中的元素数(用于设置图例的高度)colors.domain().length.然后对于图例.data(),您可以使用域本身.最后,要设置图例框的填充颜色,请调用颜色比例,d因为域中的每个元素都是a 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); });
Run Code Online (Sandbox Code Playgroud)

这就是它.希望有所帮助.

这是更新的JSFiddle.