首页 > 解决方案 > 如何使用事件侦听器来切换我的 d3 条形图,我只能看到一个而不是两个?

问题描述

我有 2 个按钮,我想用它们来控制我用于条形图的数据集。现在我可以点击一个,它会毫无问题地显示我的 d3 图。但是当我想切换到另一个图表时,我单击按钮,它会在我之前的图表之上显示该图表。我如何做到这一点,以便当我在图表之间切换时,它只显示一个图表。

   var djockey = 'top5jockey.csv'
   var dtrainer = 'top5trainer.csv'

 // Define SVG area dimensions
 var svgWidth = 1500;
 var svgHeight = 1000;

 // Define the chart's margins as an object
 var chartMargin = {
 top: 30,
 right: 30,
 bottom: 130,
 left: 30
 };

 // Define dimensions of the chart area
 var chartWidth = svgWidth - chartMargin.left - chartMargin.right;
 var chartHeight = svgHeight - chartMargin.top - chartMargin.bottom;

// Select body, append SVG area to it, and set the dimensions
var svg = d3.select("body")
.append("svg")
.attr("height", svgHeight)
.attr("width", svgWidth);


// Append a group to the SVG area and shift ('translate') it to the right and to the bottom
var chartGroup = svg.append("g")
.attr("transform", `translate(${chartMargin.left}, ${chartMargin.top})`);

var btnj = document.getElementById("Jockey")
btnj.addEventListener('click', function(e){
    change(e.target.id)
})
var btnt = document.getElementById("Trainer")
btnt.addEventListener('click', function(e){
    change(e.target.id)
})

function change(value){
    if(value === 'Jockey'){
        update(djockey);
    }else if(value === 'Trainer'){
        update(dtrainer);
    }
}

function update(data){

    d3.csv(data).then(function(data) {

        console.log(data);
    
        // Cast the hours value to a number for each piece of tvData
        data.forEach(function(d) {
        d.Count = +d.Count;
        });
    
        // Configure a band scale for the horizontal axis with a padding of 0.1 (10%)
        var xScale = d3.scaleBand()
        .domain(data.map(d => d.Name))
        .range([0, chartWidth])
        .padding(0.1);
    
        // Create a linear scale for the vertical axis.
        var yLinearScale = d3.scaleLinear()
        .domain([0, d3.max(data, d => d.Count)])
        .range([chartHeight, 0]);
    
        // Create two new functions passing our scales in as arguments
        // These will be used to create the chart's axes
        var bottomAxis = d3.axisBottom(xScale);
        var leftAxis = d3.axisLeft(yLinearScale).ticks(10);
    
        // Append two SVG group elements to the chartGroup area,
        // and create the bottom and left axes inside of them
        chartGroup.append("g")
        .call(leftAxis);
    
        chartGroup.append("g")
        .attr("class", "x_axis")
        .attr("transform", `translate(0, ${chartHeight})`)
        .call(bottomAxis)
        .selectAll("text")  
        .style("text-anchor", "end")
        .attr("dx", "-.8em")
        .attr("dy", ".15em")
        .attr("transform", "rotate(-65)");
    
        // Create one SVG rectangle per piece of tvData
        // Use the linear and band scales to position each rectangle within the chart
        chartGroup.selectAll("#bar")
        .data(data)
        .enter()
        .append("rect")
        .attr("class", "bar")
        .attr("x", d => xScale(d.Name))
        .attr("y", d => yLinearScale(d.Count))
        .attr("width", xScale.bandwidth())
        .attr("height", d => chartHeight - yLinearScale(d.Count));
    
    }).catch(function(error) {
        console.log(error);
    })
};

标签: d3.jsaddeventlistener

解决方案


D3 具有允许您删除所有 svg 元素的功能。基本上,您选择 svg,然后在事件侦听器的顶部运行 .remove()。它将清除所有 svg 元素。


推荐阅读