javascript - d3js图表点和区域不更新

标签 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 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);
            })

    });
});

这仅部分有效,因为我得到以下结果:enter image description here

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

最佳答案

当你这样做时:

svg.select("circle")

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

Selects the first element that matches the specified selector string. (emphasis mine)

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

总而言之,应该是:

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

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

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

对于线和面,同样操作:先绑定(bind)数据,然后更改其d属性:

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

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

此外,由于您要重新绑定(bind)数据,因此您必须更改此设置:

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

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

关于javascript - d3js图表点和区域不更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44023127/

相关文章:

javascript - 在数据输入链中为每个对象属性添加任意数量的标签

javascript - 坐标三 Angular 学 - 计算飞行路径弧线的中点

javascript - D3.js 在图表之间转换

javascript - 如何在搜索功能中处理 'No Results Found'

javascript - 无法在 Three.js 中选择 div 内的文本

javascript - jQuery.parseHTML 的反向

d3.js - dc.js geoChoroplethChart 不显示图例

javascript - 使用 <TR> 上的 jquery 触发器使链接在行内可用

javascript - 单击reactjs表行中的 'Edit'按钮时如何保存我的用户数据

javascript - d3.js 树状图 : How to toggle visibility of nodes by click