d3js图表点和区域不更新

时间:2017-05-17 11:07:42

标签: javascript d3.js

我有一个函数,我调用它来呈现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));

});

结果如下:enter image description here

您看到的侧边按钮是要更改csv网址,以便图表在点击时更新,我这样做:

$('.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);
            })

    });
});

这只是部分工作,因为我得到了这个结果:enter image description here

我试图找出原因,但我无法得到它......任何想法?

1 个答案:

答案 0 :(得分:2)

执行此操作时:

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选择中删除。