D3:图例缩放问题 [英] D3: issue with legend scaling

查看:183
本文介绍了D3:图例缩放问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试修改适用于美国失业合唱地图 https://github.com/d3/d3-scale-chromatic =nofollow noreferrer> D3 scale chromatic 。

I am trying to amend M Bostock's US unemployment choropleth map that applies D3 scale chromatic.

我现在可以根据需要修改桶大小来绘制我的数据,但是当我这样做时,传说似乎成倍增长,我无法使其适合所需的宽度并适当缩放间隔。

I am now able to amend the bucket-sizes as I please to plot my data, however when I do so the legend seems to grow in size exponentially and I am unable to make it fit to a desired width and scale the intervals appropriately.

请参阅随附的 jsfiddle 我展示了遇到的问题。我想以两种方式修改图例:

Please see the attached jsfiddle where I demonstrate the issue encountered. I would like to amend the legend in two ways:


  1. 刻度线之间的空格是固定的,例如: 50px

  2. 刻度之间的空格是比例的函数,但是图例仍然适合所需的宽度(例如500px)

我的问题是我似乎无法修改以下代码行中的参数(我希望这不是缩放色彩脚本中的默认值。)

My problem is that I do not seem to be able to amend parameters in the following line of code (I am hoping this is not a default in the scale chromatic script..)

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


推荐答案

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

There are only two problems in your code, both easy to fix.

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

The first problem is the domain here:

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

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

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

As you can see, you're passing an array with several values. However, for a linear scale with just two values in the range, you have to pass an array with just two values.

因此,它应该是:

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 是一个包含多个值的数组,你在这里传递第二个值。但是你不想要第二个值,你想要最后值。

Since myDomain is an array with several values, you're passing the second value here. But you don't want the second value, you want the last value.

因此,它应该是:

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

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

Here is the code with those changes (I removed the map, we don't need it for this answer, and also moved the legend to the left, so it better fits S.O. snippet):

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>

这篇关于D3:图例缩放问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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