最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

How do you clear an SVG in d3.js in javascript - Stack Overflow

programmeradmin0浏览0评论

I just created my first test program in d3.js. It works ok so far. It creates rects to illustrate data it reads from a .csv file and it loads a new dataset if the user picks different data. But it writes it on top of what is already there,

This code snippet writes new graphs without clearing what is already there

    barsM = svg.selectAll(".bar").data(dataMale).enter();


    barsF = svg.selectAll(".bar").data(dataFemale).enter()


    barsM.append("rect")
        .attr("class", "bar1")
        .attr("x", function (d) { return x(d.age_group); })
        .attr("width", x.rangeBand() / 2)
        .attr("y", function (d) { return y(d.mean * 100); })
        .attr("height", function (d, i, j) { return height - y(d.mean *100); });

    barsF.append("rect")
        .attr("class", "bar2")
        .attr("x", function (d) { return x(d.age_group) + x.rangeBand() / 2; })
        .attr("width", x.rangeBand() / 2)
        .attr("y", function (d) { return y(d.mean * 100); })
        .attr("height", function (d, i, j) { return height - y(d.mean * 100); });

You can see the program in action here

/

How do I clear out the graphs? I do not understand the code for using datum instead of data.

I would assume that this would work

svg.selectAll(".bar").data(data).exit().remove();

barsM = svg.selectAll(".bar").data(dataMale).enter();
barsF = svg.selectAll(".bar").data(dataFemale).enter();

or this

svg.selectAll(".bar").data(dataMale).exit().remove();                       
svg.selectAll(".bar").data(dataFemale).exit().remove();

barsM = svg.selectAll(".bar").data(dataMale).enter();
barsF = svg.selectAll(".bar").data(dataFemale).enter();

I would think that if there is an append,there would be a remove. But staring at this code and pondering how to put the right code before this block did not yield any results

 barsM.append("rect")
    .attr("class", "bar1")
    .attr("x", function (d) { return x(d.age_group); })
    .attr("width", x.rangeBand() / 2)
    .attr("y", function (d) { return y(d.mean * 100); })
    .attr("height", function (d, i, j) { return height - y(d.mean *100); });

barsF.append("rect")
    .attr("class", "bar2")
    .attr("x", function (d) { return x(d.age_group) + x.rangeBand() / 2; })
    .attr("width", x.rangeBand() / 2)
    .attr("y", function (d) { return y(d.mean * 100); })
    .attr("height", function (d, i, j) { return height - y(d.mean * 100); });

When I tried this

svg.selectAll("*").remove();

It removed the SVG and it did not e back. I assume this is because I set the margins and size of the thing in the javascript and so using this trick would involve rewriting and moving the code I have all around.

Here is the entire javascript file. Please tell me what to change to make this work. The code snippits and the refresh button content to clearing out the svg is not working.

var margin = {top: 20, right: 50, bottom: 100, left: 75},
    width = 740 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

var x = d3.scale.ordinal()
    .rangeRoundBands([0, width], .1);

var y = d3.scale.linear().domain([300, 1100]).range([height, 0]);

var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom");

var yAxisLeft = d3.svg.axis().scale(y).ticks(4).orient("left");

var svg = d3.select("#chart-svg").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .append("g")
    .attr("class", "graph")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

var _location = "USA";
var _year = "1990";
var _metric = "obese";

function loadCountry(inputcountry)
{
    //d3.selectAll("svg > *").remove();
    _location = inputcountry;
    load();
}

function loadYear(inputyear)
{
    //d3.selectAll("svg > *").remove();
    _year = inputyear;
    load();
}

function loadMetric(inputmetrice)
{

    _metric = inputmetrice;
    load();
}

var headers = [ "Male", "Female"];

function load() {

    d3.csv("../database/IHME_GBD_2013_OBESITY_PREVALENCE_1990_2013_Y2014M10D08.CSV", type, function (error, data)

    {
        var dataMale = data.filter(function (d) {
                 return (d.location == _location) &&
                        (d.year == _year) &&
                        (d.metric == _metric) &&
                        (d.sex_id == 1)
                     });

        var dataFemale = data.filter(function (d) {
                  return (d.location == _location) &&
                       (d.year == _year) &&
                       (d.metric == _metric) &&
                       (d.sex_id == 2)
                      });


        x.domain(data.map(function (d) { return d.age_group; }));
        y.domain([0, d3.max(data, function (d) { return d.mean * 100; })]);

        svg.append("g")
            .attr("class", "x axis")
            .attr("transform", "translate(0," + height + ")")
            .call(xAxis)
                    .selectAll("text")
                        .style("text-anchor", "end")
                        .attr("dx", "-.16em")
                        .attr("dy", ".15em")
                        .attr("transform", function(d) {
                            return "rotate(-65)"
                });

        svg.append("g")
            .attr("class", "y axis axisLeft")
            .attr("transform", "translate(0,0)")
            .call(yAxisLeft)
          .append("text")
            .attr("y", 6)
            .attr("dy", "-2em")
            .style("text-anchor", "end")
            .text("Mean");

        svg.selectAll(".bar").data(data).exit().remove();


        barsM = svg.selectAll(".bar").data(dataMale).enter();
        barsF = svg.selectAll(".bar").data(dataFemale).enter();

        barsM.append("rect")
            .attr("class", "bar1")
            .attr("x", function (d) { return x(d.age_group); })
            .attr("width", x.rangeBand() / 2)
            .attr("y", function (d) { return y(d.mean * 100); })
            .attr("height", function (d, i, j) { return height - y(d.mean *100); });

        barsF.append("rect")
            .attr("class", "bar2")
            .attr("x", function (d) { return x(d.age_group) + x.rangeBand() / 2; })
            .attr("width", x.rangeBand() / 2)
            .attr("y", function (d) { return y(d.mean * 100); })
            .attr("height", function (d, i, j) { return height - y(d.mean * 100); });



        var color = d3.scale.ordinal()
            .domain([0, 1])
            .range(["#ff0000", "#0000ff"]);

        var legend = svg.selectAll(".legend")
            .data(headers.slice().reverse())
                .enter().append("g")
                .attr("class", "legend")
                .attr("transform", function (d, i) { return "translate(-20," + i * 20 + ")"; });

        legend.append("rect")
            .attr("x", width - 18)
            .attr("width", 18)
            .attr("height", 18)
            .style("fill", color);

        legend.append("text")
              .attr("x", width - 24)
              .attr("y", 9)
              .attr("dy", ".35em")
              .style("text-anchor", "end")
              .text(function (d) { return d; });


        var tooltip = svg.append("g")
            .attr("class", "tooltip");

        tooltip.append("rect")
            .attr("width", 30)
            .attr("height", 20)
            .attr("fill", "red")
            .style("opacity", 0.5);

        tooltip.append("text")
            .attr("x", 15)
            .attr("dy", "1.2em")
            .style("text-anchor", "middle")
            .attr("font-size", "12px")
            .attr("font-weight", "bold");
    });

    function type(d) {
        d.mean = +d.mean;
        return d;
    }
}

EDIT:

I tried a solution offered here and it did not work

Here is the url

/

The HTML

<html>
<head>
<link rel="stylesheet" type="text/css" href="stylefile.css">
</head>
<body>

<script type="text/javascript" src=".v2.min.js"></script>
<script type="text/javascript" src=".8/jquery.min.js"></script>
<script type="text/javascript" src="thejsfile.js"></script>
<svg id="graphContainer" class="graphContainer">
  <circle r="10" cx="50" cy="50" ></circle>
</svg>

<button>
remove svg contents
</button>

</body>
</html>

Here is the javascript file

var svg = d3.select('svg');
var btn = d3.select('button');


btn.on('click', ()=>{
    svg.selectAll("*").remove();
});

and here is the css file

svg{
  height:500px;
  width:500px;
  background: gray;
}
path.link {
    fill: none;
    stroke: #666;
    stroke-width: 1.5px;
}   

circle {
    fill: #ccc;
    stroke: #333;
    stroke-width: 1.5px;
}

text {
    font: 10px sans-serif;
    pointer-events: none;
}

text.shadow {
    stroke: #fff;
    stroke-width: 3px;
    stroke-opacity: .8;
}

body {
    background-color: white;
    margin: 0px;
}

.graphContainer {
    text-shadow: -1px -1px 0 white, 1px -1px 0 white, -1px 1px 0 white, 1px 1px 0 white;
}

When I loaded this on the internet and clicked the button, it did not do anything.

I think my next step will try to find this example code you talk of that used this update cycle. As PatelGatnan said, I think I am missing the Enter and Exit parts

These additions did nothing. The program still does not refresh after a new selection.

I just created my first test program in d3.js. It works ok so far. It creates rects to illustrate data it reads from a .csv file and it loads a new dataset if the user picks different data. But it writes it on top of what is already there,

This code snippet writes new graphs without clearing what is already there

    barsM = svg.selectAll(".bar").data(dataMale).enter();


    barsF = svg.selectAll(".bar").data(dataFemale).enter()


    barsM.append("rect")
        .attr("class", "bar1")
        .attr("x", function (d) { return x(d.age_group); })
        .attr("width", x.rangeBand() / 2)
        .attr("y", function (d) { return y(d.mean * 100); })
        .attr("height", function (d, i, j) { return height - y(d.mean *100); });

    barsF.append("rect")
        .attr("class", "bar2")
        .attr("x", function (d) { return x(d.age_group) + x.rangeBand() / 2; })
        .attr("width", x.rangeBand() / 2)
        .attr("y", function (d) { return y(d.mean * 100); })
        .attr("height", function (d, i, j) { return height - y(d.mean * 100); });

You can see the program in action here

http://www.gelsana./IHME/blog/

How do I clear out the graphs? I do not understand the code for using datum instead of data.

I would assume that this would work

svg.selectAll(".bar").data(data).exit().remove();

barsM = svg.selectAll(".bar").data(dataMale).enter();
barsF = svg.selectAll(".bar").data(dataFemale).enter();

or this

svg.selectAll(".bar").data(dataMale).exit().remove();                       
svg.selectAll(".bar").data(dataFemale).exit().remove();

barsM = svg.selectAll(".bar").data(dataMale).enter();
barsF = svg.selectAll(".bar").data(dataFemale).enter();

I would think that if there is an append,there would be a remove. But staring at this code and pondering how to put the right code before this block did not yield any results

 barsM.append("rect")
    .attr("class", "bar1")
    .attr("x", function (d) { return x(d.age_group); })
    .attr("width", x.rangeBand() / 2)
    .attr("y", function (d) { return y(d.mean * 100); })
    .attr("height", function (d, i, j) { return height - y(d.mean *100); });

barsF.append("rect")
    .attr("class", "bar2")
    .attr("x", function (d) { return x(d.age_group) + x.rangeBand() / 2; })
    .attr("width", x.rangeBand() / 2)
    .attr("y", function (d) { return y(d.mean * 100); })
    .attr("height", function (d, i, j) { return height - y(d.mean * 100); });

When I tried this

svg.selectAll("*").remove();

It removed the SVG and it did not e back. I assume this is because I set the margins and size of the thing in the javascript and so using this trick would involve rewriting and moving the code I have all around.

Here is the entire javascript file. Please tell me what to change to make this work. The code snippits and the refresh button content to clearing out the svg is not working.

var margin = {top: 20, right: 50, bottom: 100, left: 75},
    width = 740 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

var x = d3.scale.ordinal()
    .rangeRoundBands([0, width], .1);

var y = d3.scale.linear().domain([300, 1100]).range([height, 0]);

var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom");

var yAxisLeft = d3.svg.axis().scale(y).ticks(4).orient("left");

var svg = d3.select("#chart-svg").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .append("g")
    .attr("class", "graph")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

var _location = "USA";
var _year = "1990";
var _metric = "obese";

function loadCountry(inputcountry)
{
    //d3.selectAll("svg > *").remove();
    _location = inputcountry;
    load();
}

function loadYear(inputyear)
{
    //d3.selectAll("svg > *").remove();
    _year = inputyear;
    load();
}

function loadMetric(inputmetrice)
{

    _metric = inputmetrice;
    load();
}

var headers = [ "Male", "Female"];

function load() {

    d3.csv("../database/IHME_GBD_2013_OBESITY_PREVALENCE_1990_2013_Y2014M10D08.CSV", type, function (error, data)

    {
        var dataMale = data.filter(function (d) {
                 return (d.location == _location) &&
                        (d.year == _year) &&
                        (d.metric == _metric) &&
                        (d.sex_id == 1)
                     });

        var dataFemale = data.filter(function (d) {
                  return (d.location == _location) &&
                       (d.year == _year) &&
                       (d.metric == _metric) &&
                       (d.sex_id == 2)
                      });


        x.domain(data.map(function (d) { return d.age_group; }));
        y.domain([0, d3.max(data, function (d) { return d.mean * 100; })]);

        svg.append("g")
            .attr("class", "x axis")
            .attr("transform", "translate(0," + height + ")")
            .call(xAxis)
                    .selectAll("text")
                        .style("text-anchor", "end")
                        .attr("dx", "-.16em")
                        .attr("dy", ".15em")
                        .attr("transform", function(d) {
                            return "rotate(-65)"
                });

        svg.append("g")
            .attr("class", "y axis axisLeft")
            .attr("transform", "translate(0,0)")
            .call(yAxisLeft)
          .append("text")
            .attr("y", 6)
            .attr("dy", "-2em")
            .style("text-anchor", "end")
            .text("Mean");

        svg.selectAll(".bar").data(data).exit().remove();


        barsM = svg.selectAll(".bar").data(dataMale).enter();
        barsF = svg.selectAll(".bar").data(dataFemale).enter();

        barsM.append("rect")
            .attr("class", "bar1")
            .attr("x", function (d) { return x(d.age_group); })
            .attr("width", x.rangeBand() / 2)
            .attr("y", function (d) { return y(d.mean * 100); })
            .attr("height", function (d, i, j) { return height - y(d.mean *100); });

        barsF.append("rect")
            .attr("class", "bar2")
            .attr("x", function (d) { return x(d.age_group) + x.rangeBand() / 2; })
            .attr("width", x.rangeBand() / 2)
            .attr("y", function (d) { return y(d.mean * 100); })
            .attr("height", function (d, i, j) { return height - y(d.mean * 100); });



        var color = d3.scale.ordinal()
            .domain([0, 1])
            .range(["#ff0000", "#0000ff"]);

        var legend = svg.selectAll(".legend")
            .data(headers.slice().reverse())
                .enter().append("g")
                .attr("class", "legend")
                .attr("transform", function (d, i) { return "translate(-20," + i * 20 + ")"; });

        legend.append("rect")
            .attr("x", width - 18)
            .attr("width", 18)
            .attr("height", 18)
            .style("fill", color);

        legend.append("text")
              .attr("x", width - 24)
              .attr("y", 9)
              .attr("dy", ".35em")
              .style("text-anchor", "end")
              .text(function (d) { return d; });


        var tooltip = svg.append("g")
            .attr("class", "tooltip");

        tooltip.append("rect")
            .attr("width", 30)
            .attr("height", 20)
            .attr("fill", "red")
            .style("opacity", 0.5);

        tooltip.append("text")
            .attr("x", 15)
            .attr("dy", "1.2em")
            .style("text-anchor", "middle")
            .attr("font-size", "12px")
            .attr("font-weight", "bold");
    });

    function type(d) {
        d.mean = +d.mean;
        return d;
    }
}

EDIT:

I tried a solution offered here and it did not work

Here is the url

http://www.gelsana./IHME/echonax/

The HTML

<html>
<head>
<link rel="stylesheet" type="text/css" href="stylefile.css">
</head>
<body>

<script type="text/javascript" src="http://d3js/d3.v2.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis./ajax/libs/jquery/1.8/jquery.min.js"></script>
<script type="text/javascript" src="thejsfile.js"></script>
<svg id="graphContainer" class="graphContainer">
  <circle r="10" cx="50" cy="50" ></circle>
</svg>

<button>
remove svg contents
</button>

</body>
</html>

Here is the javascript file

var svg = d3.select('svg');
var btn = d3.select('button');


btn.on('click', ()=>{
    svg.selectAll("*").remove();
});

and here is the css file

svg{
  height:500px;
  width:500px;
  background: gray;
}
path.link {
    fill: none;
    stroke: #666;
    stroke-width: 1.5px;
}   

circle {
    fill: #ccc;
    stroke: #333;
    stroke-width: 1.5px;
}

text {
    font: 10px sans-serif;
    pointer-events: none;
}

text.shadow {
    stroke: #fff;
    stroke-width: 3px;
    stroke-opacity: .8;
}

body {
    background-color: white;
    margin: 0px;
}

.graphContainer {
    text-shadow: -1px -1px 0 white, 1px -1px 0 white, -1px 1px 0 white, 1px 1px 0 white;
}

When I loaded this on the internet and clicked the button, it did not do anything.

I think my next step will try to find this example code you talk of that used this update cycle. As PatelGatnan said, I think I am missing the Enter and Exit parts

These additions did nothing. The program still does not refresh after a new selection.

Share Improve this question edited Dec 3, 2016 at 11:45 xarzu asked Nov 30, 2016 at 10:38 xarzuxarzu 9,51945 gold badges120 silver badges172 bronze badges 4
  • You are missing the update and exit part. bl.ocks/mbostock/3808218 – Pavel Gatnar Commented Nov 30, 2016 at 10:45
  • Or do not use enter/update/exit pattern by using datum instead of data method. – Pavel Gatnar Commented Nov 30, 2016 at 10:48
  • I am new to all this and I do not understand the datam inststead of data method. I do not understand the update and exit. I looked at the code you linked to and tried to replicate what is there in my code and it did nothing. – xarzu Commented Nov 30, 2016 at 12:22
  • Can you again try my updated answer. I gave specific ids to every element now. – eko Commented Dec 3, 2016 at 10:56
Add a ment  | 

2 Answers 2

Reset to default 7

As mentioned in the ment by @PavelGatnar you should use the enter/update/exit pattern. But to answer your question you clear the contents of the svg (everything under svg) with:

d3.select(".graph").selectAll("*").remove();

Example: https://jsfiddle/rqqko9hd/3/

adding this function and calling it whenever a control was called fixed the issue. The graph is reset and pletely redrawn. It would be nice if the graph was animated and the bars moved whenever a new selection was made, but this was good enough:

function resetchart()
{
    d3.select("svg").remove();
    svg = d3.select("#chart-svg").append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
        .append("g")
        .attr("class", "graph")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
}
发布评论

评论列表(0)

  1. 暂无评论