将整数量化为离散桶

时间:2015-02-12 20:09:50

标签: d3.js charts quantile quantization

我有一个约7500个项目的列表,它们都有类似的签名:

{
    revenue: integer,
    title: string,
    sector: string
}

收入将介于0到10亿之间。我想构建一个规模,以便给定一个特定公司的收入......它返回相对于以下“桶”的位置:

$0-5 Million
$5-10 Million
$10-25 Million
$25-50 Million
$50-100 Million
$100-250 Million
> $250 Million

我相信我应该能够在d3中使用量化或分位数量表来实现这一目标,但是在获得预期结果方面遇到了困难。到目前为止,我有类似的东西:

var max_rev = 1000000000 // 1 Billion
scale = d3.scale.quantize().domain(_.range(max_rev)).range([5000000, 10000000, 25000000, 50000000, 100000000, 250000000])

一个明显的问题是调用_.range(max_rev)创建一个10亿个项目的数组,所以我想知道如何更有效地做这个(类似.domain([0,1000000000])?)

定义此比例的最佳方法是什么,比例(75000000)将返回50000000.一旦我有了,我可以检查它与哈希并返回正确的标签:

{
    ...
    ...
    50000000: "$50-100 Million",
    100000000: "$100-250 Million",
    ...

}

非常感谢!如果我能提供任何其他信息,请告诉我。

1 个答案:

答案 0 :(得分:5)

在这种情况下,量化比例不会起作用,因为您的域和范围不会均匀分割。相反,您可以使用threshold比例。

以下是一个例子:



var dollars = d3.format("$,d"),
  data = d3.range(100).map(function(d, i) {
      return {
          revenue: parseInt(Math.random() * 1000000000),
          title: "Company " + i,
          sector: "Sector " + parseInt(Math.random() * 10)
      }
  }),
  quantize = d3.scale.threshold()
                     .domain([5000000, 10000000, 25000000, 50000000, 100000000, 250000000])
                     .range([0, 5000000, 10000000, 25000000, 50000000, 100000000, 250000000]);

var table = d3.select("#info").append("table");

table.append("thead").append("tr").selectAll("th")
    .data(['company', 'sector', 'revenue', 'quantized_revenue'])
  .enter()
    .append("td")
    .text(function(d) {
      return d;
    });

var rows = table.append("tbody").selectAll("tr")
    .data(data)
  .enter()
    .append("tr")
    .attr("class", "company")

rows.append("td").text(function(d) {
    return d.title;
});
rows.append("td").text(function(d) {
    return d.sector;
});
rows.append("td").text(function(d) {
    return dollars(d.revenue);
});
rows.append("td").text(function(d) {
    return dollars(quantize(d.revenue));
});

table {
    width: 100%;
}
thead {
    background-color: #ccc;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="info"></div>
&#13;
&#13;
&#13;

有趣的是:

  quantize = d3.scale.threshold()
                     .domain([5000000, 10000000, 25000000, 50000000, 100000000, 250000000])
                     .range([0, 5000000, 10000000, 25000000, 50000000, 100000000, 250000000]);

domain设置输入值与之比较的阈值,range定义输出。恰好在这种情况下,range基本上与domain相同,但它并非必须如此。 range可以是颜色值列表,用于定义条形高度的像素等等。

你甚至可以这样做,并避免在哈希表中查找结果:

&#13;
&#13;
var dollars = d3.format("$,d"),
  data = d3.range(100).map(function(d, i) {
      return {
          revenue: parseInt(Math.random() * 1000000000),
          title: "Company " + i,
          sector: "Sector " + parseInt(Math.random() * 10)
      }
  }),
  quantize = d3.scale.threshold()
                     .domain([5000000, 10000000, 25000000, 50000000, 100000000, 250000000])
                     .range(["$0-5", "$5-10", "$10-25", "$25-50", "$50-100", "$100-250",  "> $250"].map(function(d) { return d + " Million"; }));

var table = d3.select("#info").append("table");

table.append("thead").append("tr").selectAll("th")
    .data(['company', 'sector', 'revenue', 'quantized_revenue'])
  .enter()
    .append("td")
    .text(function(d) {
      return d;
    });

var rows = table.append("tbody").selectAll("tr")
    .data(data)
  .enter()
    .append("tr")
    .attr("class", "company")

rows.append("td").text(function(d) {
    return d.title;
});
rows.append("td").text(function(d) {
    return d.sector;
});
rows.append("td").text(function(d) {
    return dollars(d.revenue);
});
rows.append("td").text(function(d) {
    return quantize(d.revenue);
});
&#13;
table {
    width: 100%;
}
thead {
    background-color: #ccc;
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="info"></div>
&#13;
&#13;
&#13;