本文介绍了d3:通过退出/删除/合并更新图表无法正确处理更改的标签文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于基于 https://bl.ocks的d3.js(d3.v4.js). org/mbostock/3884955 (多系列折线图),如果必须处理新数据,我需要更新标签文本.

For d3.js (d3.v4.js) based on https://bl.ocks.org/mbostock/3884955 (Multi-Series Line Chart), I need to update the label text, if new data has to be processed.

该示例几乎可以正常工作.出现了某种错误,因为旧标签文本(Old York)和新标签文本(New York)在图表中仍然可见.

The example is almost working. Something is just wrong as the old label text (Old York) is still visible in the chart together with the new label text (New York).

这是我的代码:

    <script src="https://d3js.org/d3.v4.min.js"></script>
    <style>
        .axis--x path {
            display: none;
        }
            
        .line {
            fill: none;
            stroke: steelblue;
            stroke-width: 1.5px;
        }
            
    </style>
    <button>Click me</button>
    <svg width="960" height="500"></svg>
    <!--<script src="d3.v4.js"></script>-->
            
    <script>
        var svg = d3.select("svg"),
            margin = {
                top: 20,
                right: 80,
                bottom: 30,
                left: 50
            },
            width = svg.attr("width") - margin.left - margin.right,
            height = svg.attr("height") - margin.top - margin.bottom,
            g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
            
        var parseTime = d3.timeParse("%Y%m%d");
            
        var x = d3.scaleTime().range([0, width]),
            y = d3.scaleLinear().range([height, 0]),
            z = d3.scaleOrdinal(d3.schemeCategory10);
            
        var line = d3.line()
            .curve(d3.curveBasis)
            .x(function (d) {
                return x(d.date);
            })
            .y(function (d) {
                return y(d.temperature);
            });
            
        var data = [{
            "date": "1136156400000",
            "Old York": 63.4,
            "San Francisco": 62.7,
            "Austin": 72.2
        }, {
            "date": "1167692400000",
            "Old York": 58.0,
            "San Francisco": 59.9,
            "Austin": 67.7
        }, {
            "date": "1199228400000",
            "Old York": 53.3,
            "San Francisco": 59.1,
            "Austin": 69.4
        }, {
            "date": "1230850800000",
            "Old York": 55.7,
            "San Francisco": 58.8,
            "Austin": 68.0
        }, {
            "date": "1262386800000",
            "Old York": 62.3,
            "San Francisco": 55.1,
            "Austin": 71.9
        }];
            
        var data2 = [{
            "date": "1136156400000",
            "New York": 263.4,
            "San Francisco": 262.7,
            "Austin": 372.2
        }, {
            "date": "1167692400000",
            "New York": 458.0,
            "San Francisco": 259.9,
            "Austin": -367.7
        }, {
            "date": "1199228400000",
            "New York": 153.3,
            "San Francisco": 259.1,
            "Austin": 369.4
        }, {
            "date": "1230850800000",
            "New York": 155.7,
            "San Francisco": 258.8,
            "Austin": 368.0
        }, {
            "date": "1262386800000",
            "New York": 162.3,
            "San Francisco": 255.1,
            "Austin": 371.9
        }];
    
    
        // d3.tsv("data.tsv", type, function (error, data) {
        //     if (error) throw error;
    
        data.columns = ["date", "Old York", "San Francisco", "Austin"];
    
        var cities = data.columns.slice(1).map(function (id) {
            return {
                id: id,
                values: data.map(function (d) {
                    return {
                        date: d.date,
                        temperature: d[id]
                    };
                })
            };
        });
    
        x.domain(d3.extent(data, function (d) {
            return d.date;
        }));
    
        y.domain([
            d3.min(cities, function (c) {
                return d3.min(c.values, function (d) {
                    return d.temperature;
                });
            }),
            d3.max(cities, function (c) {
                return d3.max(c.values, function (d) {
                    return d.temperature;
                });
            })
        ]);
        g.append("g")
            .attr("class", "axis axis--x")
            .attr("transform", "translate(0," + height + ")")
            .call(d3.axisBottom(x));
        g.append("g")
            .attr("class", "axis axis--y")
            .call(d3.axisLeft(y))
            .append("text")
            .attr("transform", "rotate(-90)")
            .attr("y", 6)
            .attr("dy", "0.71em")
            .attr("fill", "#000")
            .text("Temperature, ºF");
    
        update();
        d3.select("button").on("click", function () {
            // cities.splice(0, 1);
            data = data2;
            data.columns = ["date", "New York", "San Francisco", "Austin"];
            //            console.log(JSON.stringify(cities));
            update();
        });
    
        function update() {
    //        data.columns = ["date", "New York", "San Francisco", "Austin"];
            cities = data.columns.slice(1).map(function (id) {
                return {
                    id: id,
                    values: data.map(function (d) {
                        return {
                            date: d.date,
                            temperature: d[id]
                        };
                    })
                };
            });
    
    
            x.domain(d3.extent(data, function (d) {
                return d.date;
            }));
            y.domain([
                d3.min(cities, function (c) {
                    return d3.min(c.values, function (d) {
                        return d.temperature;
                    });
                }),
                d3.max(cities, function (c) {
                    return d3.max(c.values, function (d) {
                        return d.temperature;
                    });
                })
            ]);
            z.domain(cities.map(function (c) {
                return c.id;
            }));
    
            var city = g.selectAll(".city")
                .data(cities);
    
            city.append("text")
                .datum(function (d) {
                    return {
                        id: d.id,
                        value: d.values[d.values.length - 1]
                    };
                })
                .attr("transform", function (d) {
                    return "translate(" + x(d.value.date) + "," + y(d.value.temperature) + ")";
                })
                .attr("x", 3)
                .attr("dy", "0.35em")
                .style("font", "10px sans-serif")
                .text(function (d) {
                    return d.id;
                });
    
            // var text = g.selectAll(".text")
            //     .data(texts);
    
            city.exit().remove();
    
            var cityEnter = city.enter().append("g")
                .attr("class", "city");
    
            cityEnter.append("path")
                .attr("class", "line")
                .attr("d", function (d) {
                    return line(d.values);
                })
                .style("stroke", function (d) {
                    return z(d.id);
                });
    
    
            city = cityEnter.merge(city);
    
            cityEnter.append("text")
            //        city.append("text")
                .datum(function (d) {
                    return {
                        id: d.id,
                        value: d.values[d.values.length - 1]
                    };
                })
                .attr("transform", function (d) {
                    return "translate(" + x(d.value.date) + "," + y(d.value.temperature) + ")";
                })
                .attr("x", 3)
                .attr("dy", "0.35em")
                .style("font", "10px sans-serif")
                .text(function (d) {
                    return d.id;
                });
    
    
            city.select("path")
            //            .transition().duration(1000)
                .attr("d", function (d) {
                    return line(d.values);
                });
    
            city.select("text").datum(function (d) {
                return {
                    id: d.id,
                    value: d.values[d.values.length - 1]
                };
            })
            //            .transition().duration(1000)
                .attr("transform", function (d) {
                    return "translate(" + x(d.value.date) + "," + y(d.value.temperature) + ")";
                });
    
            svg.select(".axis--y")
            //            .transition().duration(1000)
                .call(d3.axisLeft(y));
        }
    
    </script>

推荐答案

您要在更新选择中附加新的<text>.由于您要更新组合选择中的文本,因此甚至不需要更新文本值.您只需删除此部分即可:

You are appending a new <text> in the update select. Since you are updating the text in the combined selection, you do not even need to update the text value. You can just remove this part:

   city.append("text")
                .datum(function (d) {
                    return {
                        id: d.id,
                        value: d.values[d.values.length - 1]
                    };
                })
                .attr("transform", function (d) {
                    return "translate(" + x(d.value.date) + "," + y(d.value.temperature) + ")";
                })
                .attr("x", 3)
                .attr("dy", "0.35em")
                .style("font", "10px sans-serif")
                .text(function (d) {
                    return d.id;
                });

您还需要更新文本:

 city.select("text").datum(function (d) {
        return {
            id: d.id,
            value: d.values[d.values.length - 1]
        };
    })
    .text(function (d) {
        return d.id;
    })

这是更新的代码:

    <script src="https://d3js.org/d3.v4.min.js"></script>
    <style>
        .axis--x path {
            display: none;
        }
            
        .line {
            fill: none;
            stroke: steelblue;
            stroke-width: 1.5px;
        }
            
    </style>
    <button>Click me</button>
    <svg width="960" height="500"></svg>
    <!--<script src="d3.v4.js"></script>-->
            
    <script>
        var svg = d3.select("svg"),
            margin = {
                top: 20,
                right: 80,
                bottom: 30,
                left: 50
            },
            width = svg.attr("width") - margin.left - margin.right,
            height = svg.attr("height") - margin.top - margin.bottom,
            g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
            
        var parseTime = d3.timeParse("%Y%m%d");
            
        var x = d3.scaleTime().range([0, width]),
            y = d3.scaleLinear().range([height, 0]),
            z = d3.scaleOrdinal(d3.schemeCategory10);
            
        var line = d3.line()
            .curve(d3.curveBasis)
            .x(function (d) {
                return x(d.date);
            })
            .y(function (d) {
                return y(d.temperature);
            });
            
        var data = [{
            "date": "1136156400000",
            "Old York": 63.4,
            "San Francisco": 62.7,
            "Austin": 72.2
        }, {
            "date": "1167692400000",
            "Old York": 58.0,
            "San Francisco": 59.9,
            "Austin": 67.7
        }, {
            "date": "1199228400000",
            "Old York": 53.3,
            "San Francisco": 59.1,
            "Austin": 69.4
        }, {
            "date": "1230850800000",
            "Old York": 55.7,
            "San Francisco": 58.8,
            "Austin": 68.0
        }, {
            "date": "1262386800000",
            "Old York": 62.3,
            "San Francisco": 55.1,
            "Austin": 71.9
        }];
            
        var data2 = [{
            "date": "1136156400000",
            "New York": 263.4,
            "San Francisco": 262.7,
            "Austin": 372.2
        }, {
            "date": "1167692400000",
            "New York": 458.0,
            "San Francisco": 259.9,
            "Austin": -367.7
        }, {
            "date": "1199228400000",
            "New York": 153.3,
            "San Francisco": 259.1,
            "Austin": 369.4
        }, {
            "date": "1230850800000",
            "New York": 155.7,
            "San Francisco": 258.8,
            "Austin": 368.0
        }, {
            "date": "1262386800000",
            "New York": 162.3,
            "San Francisco": 255.1,
            "Austin": 371.9
        }];
    
    
        // d3.tsv("data.tsv", type, function (error, data) {
        //     if (error) throw error;
    
        data.columns = ["date", "Old York", "San Francisco", "Austin"];
    
        var cities = data.columns.slice(1).map(function (id) {
            return {
                id: id,
                values: data.map(function (d) {
                    return {
                        date: d.date,
                        temperature: d[id]
                    };
                })
            };
        });
    
        x.domain(d3.extent(data, function (d) {
            return d.date;
        }));
    
        y.domain([
            d3.min(cities, function (c) {
                return d3.min(c.values, function (d) {
                    return d.temperature;
                });
            }),
            d3.max(cities, function (c) {
                return d3.max(c.values, function (d) {
                    return d.temperature;
                });
            })
        ]);
        g.append("g")
            .attr("class", "axis axis--x")
            .attr("transform", "translate(0," + height + ")")
            .call(d3.axisBottom(x));
        g.append("g")
            .attr("class", "axis axis--y")
            .call(d3.axisLeft(y))
            .append("text")
            .attr("transform", "rotate(-90)")
            .attr("y", 6)
            .attr("dy", "0.71em")
            .attr("fill", "#000")
            .text("Temperature, ºF");
    
        update();
        d3.select("button").on("click", function () {
            // cities.splice(0, 1);
            data = data2;
            data.columns = ["date", "New York", "San Francisco", "Austin"];
            //            console.log(JSON.stringify(cities));
            update();
        });
    
        function update() {
    //        data.columns = ["date", "New York", "San Francisco", "Austin"];
            cities = data.columns.slice(1).map(function (id) {
                return {
                    id: id,
                    values: data.map(function (d) {
                        return {
                            date: d.date,
                            temperature: d[id]
                        };
                    })
                };
            });
    
    
            x.domain(d3.extent(data, function (d) {
                return d.date;
            }));
            y.domain([
                d3.min(cities, function (c) {
                    return d3.min(c.values, function (d) {
                        return d.temperature;
                    });
                }),
                d3.max(cities, function (c) {
                    return d3.max(c.values, function (d) {
                        return d.temperature;
                    });
                })
            ]);
            z.domain(cities.map(function (c) {
                return c.id;
            }));
    
            var city = g.selectAll(".city")
                .data(cities);        
    
            // var text = g.selectAll(".text")
            //     .data(texts);
    
            city.exit().remove();
    
            var cityEnter = city.enter().append("g")
                .attr("class", "city");
    
            cityEnter.append("path")
                .attr("class", "line")
                .attr("d", function (d) {
                    return line(d.values);
                })
                .style("stroke", function (d) {
                    return z(d.id);
                });
    
    
            city = cityEnter.merge(city);
    
            cityEnter.append("text")
            //        city.append("text")
                .datum(function (d) {
                    return {
                        id: d.id,
                        value: d.values[d.values.length - 1]
                    };
                })
                .attr("transform", function (d) {
                    return "translate(" + x(d.value.date) + "," + y(d.value.temperature) + ")";
                })
                .attr("x", 3)
                .attr("dy", "0.35em")
                .style("font", "10px sans-serif")
                .text(function (d) {
                    return d.id;
                });
    
    
            city.select("path")
            //            .transition().duration(1000)
                .attr("d", function (d) {
                    return line(d.values);
                });
    
            city.select("text").datum(function (d) {
                return {
                    id: d.id,
                    value: d.values[d.values.length - 1]
                };
            })
            .text(function (d) {
                return d.id;
            })
            //            .transition().duration(1000)
                .attr("transform", function (d) {
                    return "translate(" + x(d.value.date) + "," + y(d.value.temperature) + ")";
                });
    
            svg.select(".axis--y")
            //            .transition().duration(1000)
                .call(d3.axisLeft(y));
        }
    
    </script>

这篇关于d3:通过退出/删除/合并更新图表无法正确处理更改的标签文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-03 02:46