D3:图例缩放问题

时间:2018-01-07 14:53:25

标签: javascript d3.js

我正在尝试修改适用US unemployment choropleth map的M博斯托克D3 scale chromatic

我现在可以根据需要修改铲斗尺寸以绘制我的数据,但是当我这样做时,图例似乎呈指数级增长,我无法使其适合所需宽度并缩放间隔适当。

请参阅随附的jsfiddle,其中我展示了遇到的问题。我想以两种方式修改传奇:

  1. 刻度之间的空间是固定的,例如50px
  2. 刻度之间的间距是刻度的函数,但图例仍然适合所需的宽度(例如500px)
  3. 我的问题是我似乎无法修改以下代码行中的参数(我希望这不是缩放色彩脚本中的默认值。)

    g.call(d3.axisBottom(x)
        .tickSize(13)
        .tickFormat(function(x, i) { return i ? x : x + "%"; })
        .tickValues(color.domain()))
      .select(".domain")
        .remove();
    

1 个答案:

答案 0 :(得分:4)

您的代码中只有两个问题,都很容易修复。

第一个问题是这里的域名:

var myDomain = [1, 5, 8, 9, 12, 18, 20, 25]

var x = d3.scaleLinear()
    .domain(myDomain)
    .rangeRound([600, 860]);

如您所见,您传递的数组包含多个值。但是,对于只有两个值的线性刻度,您必须传递一个只有两个值的数组。

因此,它应该是:

var myDomain = [1, 5, 8, 9, 12, 18, 20, 25]

var x = d3.scaleLinear()
    .domain(d3.extent(myDomain))//just two values here
    .rangeRound([600, 860]);

第二个问题在这里:

if (d[1] == null) d[1] = x.domain()[1];
//this is the second element -------^

由于myDomain是一个包含多个值的数组,因此您在这里传递第二个值。但是你不想要第二个值,你想要最后值。

因此,它应该是:

if (d[1] == null) d[1] = x.domain()[x.domain().length - 1];
//now this is the last element --------------^

以下是包含这些更改的代码(我删除了地图,我们不需要它来获得此答案,并且还将图例移到左侧,因此它更适合S.O.代码段):

var svg = d3.select("svg"),
    width = +svg.attr("width"),
    height = +svg.attr("height");

var myDomain = [1, 5, 8, 9, 12, 18, 20, 25]

var x = d3.scaleLinear()
    .domain(d3.extent(myDomain))
    .rangeRound([200, 460]);

var color = d3.scaleThreshold()
    .domain(myDomain)
    .range(d3.schemeBlues[9]);

var g = svg.append("g")
    .attr("class", "key");

g.selectAll("rect")
  .data(color.range().map(function(d) {
      d = color.invertExtent(d);
      if (d[0] == null) d[0] = x.domain()[0];
      if (d[1] == null) d[1] = x.domain()[x.domain().length - 1];
      return d;
    }))
  .enter().append("rect")
    .attr("height", 8)
    .attr("x", function(d) { return x(d[0]); })
    .attr("width", function(d) { return x(d[1]) - x(d[0]); })
    .attr("fill", function(d) { return color(d[0]); });

g.append("text")
    .attr("class", "caption")
    .attr("x", x.range()[0])
    .attr("y", -6)
    .attr("fill", "#000")
    .attr("text-anchor", "start")
    .attr("font-weight", "bold")
    .text("Unemployment rate");

g.call(d3.axisBottom(x)
    .tickSize(13)
    .tickFormat(function(x, i) { return i ? x : x + "%"; })
    .tickValues(color.domain()))
  .select(".domain")
    .remove();
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
<svg width="600" height="200"></svg>