根据父元素(组)中的出现设置圆的不透明度-D3.js

时间:2018-09-18 02:03:12

标签: d3.js

我一直在从事一个内部项目,该项目是根据年份和事故数量等显示气泡图的。我可以显示气泡,但是我们还有TRACE功能(复选框),可以显示圆圈不同年份-如果选中TRACE复选框,则圆圈会相互重叠。这类似于滑块范围功能。即根据日期范围等显示数据。这里的问题是我们要生成所有css类名称相同且透明度不同的圆。因此,我想我们需要在选择/容器中动态找到不同的CSS类名称,然后(动态)应用不透明度,以便顶部圆(根据日期范围最后生成的圆可以具有完全不透明度,而第一个圆(根据第一年生成的结果)在最后显示为z-index,但不透明度也较低。您能帮我编写合适的函数吗?

1)启用跟踪功能后,已添加以下代码。

plotPoints = plotPointsHolder.selectAll('circle')。data(stats.filter((d)=> d.year <= year));

2)如果TRACE功能为OFF,则将执行以下代码。

plotPoints = plotPointsHolder.selectAll('circle')。data(stats.filter((d)=> d.year === year));

有关更多信息,请参见以下功能。

const renderStats = (stats, year) => {
        if (tracemode) {
            plotPoints = plotPointsHolder.selectAll('circle').data(stats.filter((d) => d.year <= year));
        } else {
            plotPoints = plotPointsHolder.selectAll('circle').data(stats.filter((d) => d.year === year));
        }
        plotPoints.exit()
            .remove();

        plotPoints.enter()
            .append('circle')
            .style('stroke', 'black')
            .style('stroke-width', '1')
            .style('fill', d => `${d.colour}`)
            .attr('class', d => `${d.type}`)
            .on('mouseover', function() {
                renderInfoMarker(this, "Circle", this.style.fill);
            })
            .on('mouseout', function() {
                removeRenderMarker(this, "Circle");
            })
            .merge(plotPoints)
            //.transition()
            //.duration(100)
            .attr('cx', function(d) { return x(d.survival); })
            .attr('cy', function(d) { return y(d.death); })
            .attr('r', function(d) {

                return map_bubble_size(d.incidence, radiusVal.min_radius, radiusVal.max_radius, radiusVal.min_value, radiusVal.max_value, radiusVal.beta);

                //return radius(d.incidence);
            });
    }

2 个答案:

答案 0 :(得分:0)

  

这里的问题是我们要生成所有具有相同css类名称且透明度不同的圆。

将日期数据映射到刻度,然后将函数应用于fill-opacity属性,该函数返回0到1之间的值。

var dates = stats.map( function(d) { return d.year }); //map date data

var opacity = d3.scaleSqrt().domain([Math.min(...dates),Math.max(...dates)]).range([0.1, 0.9]); //scale map data with square root scale

plotPoints.enter()
        .append('circle')
        .style('stroke', 'black')
        .style('stroke-width', '1')
        .style('fill', d => `${d.colour}`)
        .attr('fill-opacity', function(d) { return opacity(d.year);})
        .attr('class', d => `${d.type}`)
        .on('mouseover', function() {
            renderInfoMarker(this, "Circle", this.style.fill);
        })
        .on('mouseout', function() {
            removeRenderMarker(this, "Circle");
        })
        .merge(plotPoints)
        //.transition()
        //.duration(100)
        .attr('cx', function(d) { return x(d.survival); })
        .attr('cy', function(d) { return y(d.death); })
        .attr('r', function(d) {

            return map_bubble_size(d.incidence, radiusVal.min_radius, radiusVal.max_radius, radiusVal.min_value, radiusVal.max_value, radiusVal.beta);

            //return radius(d.incidence);
        });

答案 1 :(得分:0)

我认为@ AF7TI在解决您的不透明度问题上是正确的,所以我将回答该问题的第二部分。

由于svg没有“ z-index”概念,因此元素的顺序很重要。幸运的是,d3允许您sort a selection,以便首先绘制较大的气泡(您可以将鼠标悬停在较小的气泡上)。因此,遵循这些原则的东西应该起作用(这是伪代码):

.merge(plotPoints).sort((a,b) => { map_bubble_size(a stuff) - map_bubble_size(b stuff)})