d3js 图表点和区域未更新

网先生

我调用了一个函数来渲染d3js图表:

var tooltip = tooltipd3();
var svg = d3.select("svg#svg-day"),
    margin = {
        top: 20,
        right: 30,
        bottom: 30,
        left: 25,
        padding: 15
    },
    width = 700 - margin.left - margin.right,
    height = 300 - margin.top - margin.bottom;

// parse the periodo / time
var parseTime = d3.timeParse("%Y-%m-%d");

// set the ranges
var x = d3.scaleTime().range([0, width - margin.padding]);
var y = d3.scaleLinear().range([height, 0]);

// define the area
var area = d3.area()
    .x(function(d) {
        return x(d.periodo) + (margin.left + margin.padding);
    })
    .y0(height)
    .y1(function(d) {
        return y(d.guadagno);
    });

// define the line
var valueline = d3.line()
    .x(function(d) {
        return x(d.periodo) + (margin.left + margin.padding);
    })
    .y(function(d) {
        return y(d.guadagno);
    });

var div = d3.select("svg#svg-day")
    .append("div") // declare the tooltip div 
    .attr("class", "tooltip") // apply the 'tooltip' class
    .style("opacity", 0);

// get the data
d3.csv(base_url() + 'graph/getStatementsDaily/', function(error, data) {
    if (error) throw error;
    $('.graph-loading').hide();
    // format the data
    data.forEach(function(d) {
        d.periodo = parseTime(d.periodo)
        d.guadagno = +d.guadagno;
    });

    // scale the range of the data
    x.domain(d3.extent(data, function(d) {
        return d.periodo;
    }));
    y.domain([0, d3.max(data, function(d) {
        return d.guadagno + ((d.guadagno / 100) * 10); // 10% in più sulla scala numerica
    })]);

    // add the area
    svg.append("path")
        .data([data])
        .attr("class", "area")
        .attr("d", area);

    // add the valueline path.
    svg.append("path")
        .data([data])
        .attr("class", "line")
        .attr("d", valueline);

    // Add the scatterplot
    svg.selectAll("dot")
        .data(data)
        .enter().append("circle")
        .attr("class", "dot")
        .attr("r", 3)
        .attr("cx", function(d) {
            return x(d.periodo) + (margin.left + margin.padding);
        })
        .attr("cy", function(d) {
            return y(d.guadagno);
        })
        .on('mouseover', function(d) {
            var html = '<h5>' + d.guadagno + ' €</h5>';
            tooltip.mouseover(html); // pass html content
        })
        .on('mousemove', tooltip.mousemove)
        .on('mouseout', tooltip.mouseout);

    // add the X Axis
    svg.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(" + (margin.left + margin.padding) + "," + (height) + ")")
        .call(d3.axisBottom(x).tickFormat(d3.timeFormat("%d/%m")))

    // add the Y Axis
    svg.append("g")
        .attr("class", "y axis")
        .attr("transform", "translate (" + (margin.left + margin.padding) + " 0)")
        .call(d3.axisLeft(y));

});

这是结果:在此处输入图片说明

您看到的侧边按钮用于更改 csv url,以便图表在点击时更新,我这样做:

$('.input-number__increase, .input-number__decrease').on('click', function() {
    var where_at = $('#scroll-statement-day').val();
    $('.graph-loading').show();
    $('#svg').css({ 'opacity': 0.4 });

    var display_where_at = (where_at - 7) + '-' + where_at;
    if (parseInt(where_at) === 7) {
        display_where_at = where_at;
    }

    $('#data-days').html(display_where_at);

    var tooltip = tooltipd3();
    var svg = d3.select("svg#svg-day"),
        margin = {
            top: 20,
            right: 30,
            bottom: 30,
            left: 25,
            padding: 15
        },
        width = 700 - margin.left - margin.right,
        height = 300 - margin.top - margin.bottom;

    // parse the periodo / time
    var parseTime = d3.timeParse("%Y-%m-%d");

    // set the ranges
    var x = d3.scaleTime().range([0, width - margin.padding]);
    var y = d3.scaleLinear().range([height, 0]);

    // define the area
    var area = d3.area()
        .x(function(d) {
            return x(d.periodo) + (margin.left + margin.padding);
        })
        .y0(height)
        .y1(function(d) {
            return y(d.guadagno);
        });

    // define the line
    var valueline = d3.line()
        .x(function(d) {
            return x(d.periodo) + (margin.left + margin.padding);
        })
        .y(function(d) {
            return y(d.guadagno);
        });

    var div = d3.select("svg#svg-day")
        .append("div") // declare the tooltip div 
        .attr("class", "tooltip") // apply the 'tooltip' class
        .style("opacity", 0);

    var speed = 750;

    d3.csv(base_url() + 'graph/getStatementsDaily/' + where_at, function(error, data) {
        if (error) throw error;
        $('.graph-loading').hide();
        $('#svg').css({ 'opacity': 1 });
        // format the data
        data.forEach(function(d) {
            d.periodo = parseTime(d.periodo)
            d.guadagno = +d.guadagno;
        });

        // Scale the range of the data again 
        x.domain(d3.extent(data, function(d) {
            return d.periodo;
        }));
        y.domain([0, d3.max(data, function(d) {
            return d.guadagno + ((d.guadagno / 100) * 10); // 10% in più sulla scala numerica
        })]);

        // Select the section we want to apply our changes to
        var svg = d3.select("body").transition();

        // Make the changes
        svg.select(".line") // change the line
            .duration(speed)
            .attr("d", valueline(data));
        svg.selectAll("g.x.axis") // change the x axis
            .duration(speed)
            .call(d3.axisBottom(x).tickFormat(d3.timeFormat("%d/%m")));
        svg.selectAll("g.y.axis") // change the y axis
            .duration(speed)
            .call(d3.axisLeft(y));

        svg.select("path")
            .duration(speed)
            .attr("d", area);

        svg.select("circle")
            .duration(speed)
            .attr("r", 3)
            .attr("cx", function(d) {
                return x(d.periodo) + (margin.left + margin.padding);
            })
            .attr("cy", function(d) {
                return y(d.guadagno);
            })

    });
});

这仅部分起作用,因为我得到了这个结果:在此处输入图片说明

我试图找出原因,但我无法理解......有什么想法吗?

杰拉尔多·费塔朵

当你这样做时:

svg.select("circle")

您仅选择页面中的第一个圆圈(如果有)。根据API,select...

选择与指定选择器字符串匹配第一个元素。(强调我的)

话虽如此,你需要selectAll在这里。但这本身并不能解决问题:您必须重新绑定数据。由于我不知道您的数据结构,因此默认方法按索引绑定。

总之,应该是:

svg.selectAll("circle")
    .data(data)
    //etc...

由于这些圈子有一个名为 的类dot,您可以使用以下方法避免选择其他圈子:

svg.selectAll(".dot")
    .data(data)
    //etc...

关于线和面,也一样:先绑定数据,然后改变它们的d属性:

svg.select(".area")
    .data([data])
    .attr("d", area);

svg.select(".line")
    .data([data])
    .attr("d", valueline);

此外,由于您正在重新绑定数据,因此您必须更改此内容:

var svg = d3.select("body").transition();

因为svg.selectAll将是一个过渡选择。也就是说,在重新绑定数据后将过渡设置为每个单独的选择,将其从svg选择中删除

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章