不希望的闪烁效果使用D3创建相邻的矩形

Undesired shimmering effect using D3 to create adjacent rectangles

本文关键字:创建 D3 闪烁 希望      更新时间:2023-09-26

我正在使用D3通过推动矩形彼此相邻来生成音乐波形。这里是小提琴:http://jsfiddle.net/s4dML/

var data = [ 0.0534973, /* ...lots and lots of data... */ 0.290771];
data = data.filter(function(datum, index){
    return index % 3 == 0;
});
var width      = 340,
    height     = 70,
    svg        = d3
        .select('body')
        .append('svg')
        .attr('width', width)
        .attr('height', height);
svg
    .selectAll('rect')
    .data(data.map(function(datum){
        return (datum * height)/2;
    }))
    // .data(dataset)
    .enter()
    .append('rect')
    .attr('x', function(d, i){
        return i * (width / data.length);
    })
    .attr('y', function(d){
        return (height /2) - d ;
    })
    .attr('width', function(d, i){
        return width / data.length;
    })
    .attr('height', function(d){
        return d*2;
    })
    .attr('fill', 'teal');

有谁知道为什么结果不是预期的单一、平坦的颜色吗?有一种闪烁的效果贯穿始终。这可能是可取的,但无论如何,我想知道它是如何在那里的,以及如何摆脱它,如果我有这样的倾向。

这是SVG渲染(或者实际上是任何矢量图形渲染)的产物。假设你有两个矩形在一个像素的40%处相交。然后,第一个矩形将以40%的不透明度绘制到像素上,第二个矩形将以60%的不透明度绘制,这意味着像素只有(40 + 0.6 * 60 =)76%的颜色,尽管逻辑上它100%被彩色形状覆盖。

解决这个问题的方法是将图形定义为单个<path>对象,跟踪顶部和底部边缘,在矩形之间没有像这样的"裂缝"。

我不熟悉D3,但在普通的Javascript:

var path = "M 0," + (height / 2);
for(var i = 0; i < data.length; i++) {
  var x = (i + 1) * (width / data.length);
  var y = height / 2 - (data[i] * height)/2;
  path += " V " + y + " H " + x;
}
for(var i = data.length - 1; i >= 0; i--) {
  var x = i * (width / data.length);
  var y = height / 2 + (data[i] * height)/2;
  path += " V " + y + " H " + x;
}
path += " Z";

Russell的回答很好,尽管你最终会得到一条可怕的路径。这应该不是太大的问题。

前几天,当我试图使用非常细的条形图制作大约500个数据点的条形图时,我遇到了同样的问题。这样做的好处是,使鼠标悬停突出显示单个条要容易得多。在这种情况下,我发现你必须为宽度和x位置使用整数值。

对于您的示例,将宽度和间隔设置为1完全解决了这个问题,而只使其缩短了大约10%:

http://jsfiddle.net/s4dML/1/

.attr('x', function(d, i){
    return i;// * (width / data.length);
})
.attr('y', function(d){
    return (height /2) - d ;
})
.attr('width', function(d, i){
    return 1;
})

当然,这不是一个可扩展的解决方案——只是取决于您对小部件的计划。为了演示,我在上面的例子中添加了鼠标悬停。