【问题标题】:Combining ordinal scales to produce a single axis组合序数比例以产生单轴
【发布时间】:2016-09-15 13:22:06
【问题描述】:

我创建了一个由分组数据组成的条形图。每个组都有自己的序数比例,使用rangeBands 来定位条形:

使用两个比例可以调整每组中的条之间的间距,以及组之间的间距。

如果我将其中一个刻度传递给d3.svg.axis,则抽动完美地位于每对条的中心,但显然范围仅涵盖一组。

如何生成一个覆盖整个 X 范围且抽动在正确位置的轴?

我尝试将来自scale.range() 的每个序数刻度的值合并,但如果这样做,轴不会到达图表的任一端。


简化示例

我想在以下代码中从两个刻度创建一个轴。

const scale1 = d3.scale.ordinal()
  .rangeRoundBands([20, 180], 0.1)
  .domain(["one", "two"]);

const scale2 = d3.scale.ordinal()
  .rangeRoundBands([180, 420], 0.1)
  .domain(["three", "four", "five"]);

d3.select(".one").call(d3.svg.axis().scale(scale1));
d3.select(".two").call(d3.svg.axis().scale(scale2));
.axis path,
.axis line {
  fill: none;
  stroke: black;
  shape-rendering: crispEdges;
}
.one {
  transform: translate(0, 10px);
}
.two {
  transform: translate(0, 30px);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

<div>
  <svg width="440" height="100">
    <g class="axis one"></g>
    <g class="axis two"></g>
  </svg>
</div>

【问题讨论】:

  • 我无法在没有看到任何代码的情况下为您提供帮助,但这是我的 2 美分:您可以调用 2 个不同的 x 轴。
  • @Gerardo 我在我的问题中添加了一个简化示例。如果可能,我宁愿不渲染多个 X 轴。

标签: javascript d3.js


【解决方案1】:

以下是我设法将两个序数比例结合起来的方法。

  • 每个刻度需要偏移每个柱宽度的一半,即rangeBand() / 2
  • 为了使轴到达刻度的任一端,需要在范围的任一端添加额外的点,并将相应的null 值添加到域中。

const [rangeStart, rangeEnd] = [20, 420];

const scale1 = d3.scale.ordinal()
  .rangeRoundBands([rangeStart, 180], 0.1)
  .domain(["one", "two"]);

const scale2 = d3.scale.ordinal()
  .rangeRoundBands([180, rangeEnd], 0.1)
  .domain(["three", "four", "five"]);

const combined = [scale1, scale2].reduce((prev, curr) => {
  const offset = curr.rangeBand() / 2;
  return {
    range: [...prev.range, ...curr.range().map(x => x + offset)],
    domain: [...prev.domain, ...curr.domain()]
  };
}, {
  range: [],
  domain: []
});

const scaleFull = d3.scale.ordinal()
  .range([rangeStart, ...combined.range, rangeEnd])
  .domain([null, ...combined.domain, null]);

d3.select(".one").call(d3.svg.axis().scale(scale1));
d3.select(".two").call(d3.svg.axis().scale(scale2));
d3.select(".full").call(d3.svg.axis().scale(scaleFull));
.axis path,
.axis line {
  fill: none;
  stroke: black;
  shape-rendering: crispEdges;
}
.one {
  transform: translate(0, 10px);
}
.two {
  transform: translate(0, 30px);
}
.full {
  transform: translate(0, 60px);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

<div>
  <svg width="440" height="100">
    <g class="axis one"></g>
    <g class="axis two"></g>
    <g class="axis full"></g>
  </svg>
</div>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-04
    • 1970-01-01
    • 2019-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多