首页 > 解决方案 > 使用带刻度的相同可重复字符串值

问题描述

我是 D3 的新手,想用 6 个水平条绘制图表。我的 xAxis 与它们的值是 scaleLinear。所以我希望 yAxis 只是一个包含每个条形名称的列表。所以对于 yScale,我有 6 个名称 - ['Games'、'Apps'、'Games'、'Apps'、'Games'、'Apps']

所以当我使用这个 yScale 时:

var params = ['Games', 'Apps', 'Games', 'Apps', 'Games', 'Apps'];
var yScale = d3.scaleBand()
 .domain(params)
 .range([0, 300])

我在 yAxis 上只看到一个“游戏”和一个“应用程序” 在此处输入图像描述 如何列出 yAxis 上的所有参数而不是跳过可重复的?

标签: javascriptd3.js

解决方案


您在这里看到的是任何序数比例的默认(和预期)行为:值必须是唯一的

如果您查看API,您会看到(强调我的):

域值内部存储在从字符串化值到索引的映射中;然后使用生成的索引来确定波段。因此,波段标度的值必须可强制转换为字符串,并且域值的字符串化版本唯一地标识相应的波段。

因此,这里的任何解决方案都将是一个 hacky 解决方案。话虽如此,一个简单的解决方案是为数组的每个元素添加一个无意义的唯一值。例如,使用数组中元素的索引:

const params = ['Games', 'Apps', 'Games', 'Apps', 'Games', 'Apps'].map(function(d, i) {
  return d + "-" + i;
});

然后我们只需删除那些用于创建轴的索引,使用tickFormat

const yAxis = d3.axisLeft(yScale)
    .tickFormat(function(d) {
        return d.split("-")[0];
    });

这是一个演示:

const svg = d3.select("svg");
const params = ['Games', 'Apps', 'Games', 'Apps', 'Games', 'Apps'].map(function(d,i) {
  return d + "-" + i;
});
const yScale = d3.scaleBand()
  .domain(params)
  .range([2, 148]);
const yAxis = d3.axisLeft(yScale)
  .tickFormat(function(d) {
    return d.split("-")[0];
  });
yAxis(svg.append("g").attr("transform", "translate(100,0)"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg></svg>


推荐阅读