Javascript D3 v6:如何按所选线段缩放堆叠条以仅拉伸所选线段并收缩其余线段(并保持初始图表宽度)?
我的水平堆叠条有问题 问题:有时我得到的值非常小,所以其中一个频带段(子频带?)的宽度非常小。(请看下面的图片,我称之为每种颜色的矩形部分): 在某些情况下,我甚至看不到图表上的这一部分。将来,我希望在每个段上显示文本(百分比值)。但由于段的宽度可能太小,我需要一个显示文本的解决方案 可能的解决方案:首先,我想设置最小段宽度。但在这之后,这张图表看起来就不好了。我还试着玩xScale:Javascript D3 v6:如何按所选线段缩放堆叠条以仅拉伸所选线段并收缩其余线段(并保持初始图表宽度)?,javascript,d3.js,Javascript,D3.js,我的水平堆叠条有问题 问题:有时我得到的值非常小,所以其中一个频带段(子频带?)的宽度非常小。(请看下面的图片,我称之为每种颜色的矩形部分): 在某些情况下,我甚至看不到图表上的这一部分。将来,我希望在每个段上显示文本(百分比值)。但由于段的宽度可能太小,我需要一个显示文本的解决方案 可能的解决方案:首先,我想设置最小段宽度。但在这之后,这张图表看起来就不好了。我还试着玩xScale: const maxX = 1.4; // this value selected experimentall
const maxX = 1.4; // this value selected experimentally
const xScale = d3.scaleLinear().range([ 0, width ]).domain([ 0, maxX ]);
但对于某些情况,段仍然太小(请看第三段,我用蓝色标记了它)
所以现在我选择的解决方案是按选定的线段缩放堆叠的条形图。例如,我想缩放红色部分,图表上的所有红色部分都应该拉伸,其余部分应该收缩。和带的总宽度应相同(与初始宽度相同)。所以图表的宽度应该是相同的
这是我的代码示例:
这里的问题是我不能正确地只缩放选定的线段。我尝试检测当前的一组段:
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
的所有段都保持其宽度,并且所选组拉伸过多,因此它移到了轴的外部(实际上在这之后,我改变了图表的宽度)
问题:如何修正缩放以只允许选定的组拉伸和组的其余部分收缩(并保持图表的初始宽度)
额外问题:是否存在其他方法来按比例显示分段,即使某些分段的值太小
更新:我在typescript上的初始项目,所以我忘了删除一些ts提示,这是一个稍微更新的示例:(从注释代码中删除了ts)好吧,最后我实现了我想要的 结果: 详细信息:首先,我决定删除第二个刻度,因为我只在运行时需要它。因此,我的缩放功能更改为:
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
transform,并在代码中添加了剩余的边距。但我认为我会把它归还,因为原生CSS速度更快。尽管文章的年龄,效果仍然很酷:-也许有些事情要考虑。FYI,Calk(True)也应该设置在原点XStand上: