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

时间:2013-06-14 20:30:01

标签: javascript d3.js

我通过将矩形彼此相邻推动使用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');

有谁知道为什么结果不像预期的单一,平坦的颜色?整个过程都有一种微光效果。这可能是可取的,但无论我想知道它是如何到达那里以及如果我倾向于如何摆脱它。

2 个答案:

答案 0 :(得分:2)

这是SVG渲染(或者实际上是任何矢量图形渲染)的工件。假设您有两个符合40%进入像素的rects。然后第一个rect将绘制到具有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";

答案 1 :(得分:2)

拉塞尔的回答是好的,尽管你最终会走上一条可怕的道路。这不应该是一个太大的问题。

前几天我尝试使用非常细的条形图制作大约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;
})

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