javascript - D3 v6:如何按选定段缩放堆叠条以仅拉伸选定段并缩小其余段(并保持初始图表宽度)?
问题描述
我的水平堆叠条有问题。
问题:有时我得到的值非常小,因此带段之一(子带?)的宽度非常小。(请看下面的图片,我称之为段的每种颜色的矩形):
在某些情况下,我什至看不到图表上的这一部分。将来我想在每个段上显示文本(百分比值)。但由于段的宽度可能太小,我需要一个显示文本的解决方案。
可能的解决方案:首先我想设置最小的段宽度。但似乎在此之后图表看起来不太好。我也尝试过玩 xScale:
const maxX = 1.4; // this value selected experimentally
const xScale = d3.scaleLinear().range([ 0, width ]).domain([ 0, maxX ]);
但是对于某些情况,段仍然太小(请看第三段,我用蓝色标记了它)。
所以现在我选择按选定段缩放堆叠条的解决方案。例如,我想放大红色段,图表上的所有红色段都应该被拉伸,其余的段应该被缩小。并且带的总宽度应该相同(与初始宽度相同)。所以图表的宽度应该相同。
这是我的代码示例:https ://jsfiddle.net/8d1te7cb/2/
这里的问题是我无法正确缩放选定的片段。我试图检测当前的细分组:
const currentNode = d3.select(event.sourceEvent.target).node();
const currentGroup = d3.select(currentNode.parentNode).node();
然后我尝试仅重新调整与以下相关的段currentGroup
:
group.selectAll("rect.segment")
// .attr("transform", event.transform.toString())
.attr("x", (d, i, n) => {
if (n[i].parentNode === currentGroup) {
return xScale(d[0]) + PADDING_TO_SHOW_TEXT;
}
return xScale2(d[0]) + PADDING_TO_SHOW_TEXT;
})
.attr("width", (d, i, n) => {
if (n[i].parentNode === currentGroup) {
return xScale(d[1]) - xScale(d[0])
}
return xScale2(d[1]) - xScale2(d[0])
});
但实际上所有段都没有currentGroup
保持它们的宽度和选定的组拉伸太多,所以它移到了轴之外(实际上在那之后我改变了图表的宽度)。
问题:如何修复缩放以仅允许选定的组拉伸和其余组收缩(并保持图表的初始宽度)?
额外的问题:是否存在其他按比例显示细分的方式,即使其中一些价值太小?
更新:我在打字稿上的初始项目,所以我忘了删除一些 ts 提示,这是一个更新的示例:https ://jsfiddle.net/8d1te7cb/3/ (从注释代码中删除了 ts)
解决方案
好吧,最后我实现了我想要的。
结果: https ://jsfiddle.net/2yqbvrwp/
详细信息:首先,我决定删除第二个比例,因为我只在运行时需要它。因此,我的缩放功能更改为:
d3.zoom().scaleExtent([ 1, 10 ])
// I am not sure if I need the line below since code works same without it
// I think below is default value
//.translateExtent([ [ 0, 0 ], [ width, height ] ])
.on("zoom", (event) => {
const transform = event.transform;
// the new scale I use for runtime
// the important part here is clamp method. It prevents from moving
// segments outside of axis
const newScaleX = transform.rescaleX(xScale).clamp(true);
// so I just applied new scale to current axis
xAxis.scale(newScaleX)
svg.select("g.axis-x").call(xAxis);
svg.selectAll("rect.segment")
.attr("x", (d) => newScaleX(d[0]))
.attr("width", (d) => newScaleX(d[1]) - newScaleX(d[0]));
})
svg.call(zoom);
我还从 css 中删除了rect
变换,并在代码中添加了边距。但我想我会把它退回来,因为原生 css 更快。
推荐阅读
- machine-learning - 在 learningcurve.m 中包含 lambda 时,在 linearRegCostFunction.m 中出现 lambda 未定义错误
- javascript - ESLint 排序导入多行换行
- javascript - 如何将解析器动态导入流星中的模式?
- python - 类型错误:save() 缺少 1 个必需的位置参数:在 DRF 中使用模型集时“自我”
- printing - ESC/POS:单行打印图像+文本
- python - Pandas 无法过滤“不在”列表中的数据框
- java - 如何生成 Java tink 密钥?
- python - 列表在 selenium python 中没有属性'send_keys'
- javascript - 如何在自动播放的 React Awesome Slider 中隐藏计时器
- javascript - Jquery 克隆只重复一次。需要重复多次