kdubs
kdubs

Reputation: 946

d3.select().append() doesn't work when used multiple times

I want to display multiple gantt charts on a webpage using code from this git repository. The first gantt chart renders correctly with <div id="DIV_MyVar"> containing the proper information from the d3.select(#DIV_MyVar").append("svg") in the <script>. But for all subsequent gantt charts, d3.select() doesn't append the <svg> section to <div id="DIV_MyVar"> so that <div> shows up empty and no gantt chart is created.

Can anyone tell why d3.select().append() works for the first gantt chart but not the ones after it?

The HTML code looks like this:

<html>

<head>
    <title>Search Results</title>
    <meta charset="utf-8">
    <script src="http://code.jquery.com/jquery-latest.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script src="http://d3js.org/d3.v3.min.js"></script>
    <script language="Javascript" type="text/javascript" src="{% static 'd3-timeline.js' %}"></script>

    <STYLE type="text/css">
        .axis path,
        .axis line {
          fill: none;
          stroke: black;
          shape-rendering: crispEdges;
        }
        .axis text {
          font-family: sans-serif;
          font-size: 10px;
        }
        .timeline-label {
          font-family: sans-serif;
          font-size: 12px;
        }
        #timeline2 .axis {
          transform: translate(0px,30px);
          -ms-transform: translate(0px,30px); /* IE 9 */
          -webkit-transform: translate(0px,30px); /* Safari and Chrome */
          -o-transform: translate(0px,30px); /* Opera */
          -moz-transform: translate(0px,30px); /* Firefox */
        }
        .coloredDiv {
          height:20px; width:20px; float:left;
        }
    </STYLE>

</head>
<body>
<script language="Javascript" type="text/javascript">
    window.onload = function() {
        var MyVar = [{label: "F7", times: [{"starting_time":1420228800000, "ending_time":1420257600000}]}]


    function drawtimeline_MyVar() {
    var chart = d3.timeline()
        .stack() // toggles graph stacking
        .rowSeperators("rgb(100,100,100)")
        .click(function (d, i, datum) {
                var myWindow=window.open("", "MsgWindow", "width=500, height=500");
                myWindow.document.write(d.info);
              })
        .scroll(function (x, scale) {
                $("#scrolled_date").text(scale.invert(x) + " to " + scale.invert(x+1000));
                })
        .showBorderFormat({marginTop:25, marginBottom:2, width:10, color:"rgb(0, 0, 0)"})
        .display("rect")
        .tickFormat({format: d3.time.format("%Y %j"), tickTime: d3.time.days, tickInterval: 1, tickSize: 12 })
        .margin({left:220, right:30, top:0, bottom:0})
        .width(1000)
            ;
    var svg = d3.select("#DIV_MyVar").append("svg").attr("width", 1000)
        .datum(MyVar).call(chart);
    }


    //Call the function
    drawtimeline_MyVar();
    }
</script>

<div>
   <h4><p class="text-center">Requests</p></h4>
   <div id="DIV_MyVar"></div>
</div>
<script language="Javascript" type="text/javascript">
    window.onload = function() {
        var MyVar2 = [{label: "F7", times: [{"starting_time":1420228800000, "ending_time":1420257600000}]}]


    function drawtimeline_MyVar2() {
    var chart = d3.timeline()
        .stack() // toggles graph stacking
        .rowSeperators("rgb(100,100,100)")
        .click(function (d, i, datum) {
                var myWindow=window.open("", "MsgWindow", "width=500, height=500");
                myWindow.document.write(d.info);
              })
        .scroll(function (x, scale) {
                $("#scrolled_date").text(scale.invert(x) + " to " + scale.invert(x+1000));
                })
        .showBorderFormat({marginTop:25, marginBottom:2, width:10, color:"rgb(0, 0, 0)"})
        .display("rect")
        .tickFormat({format: d3.time.format("%Y %j"), tickTime: d3.time.days, tickInterval: 1, tickSize: 12 })
        .margin({left:220, right:30, top:0, bottom:0})
        .width(1000)
            ;
    var svg = d3.select("#DIV_MyVar2").append("svg").attr("width", 1000)
        .datum(MyVar2).call(chart);
    }


    //Call the function
    drawtimeline_MyVar2();
    }
</script>
<div>
  <h4><p class="text-center">Requests2</p></h4>
   <div id="DIV_MyVar2"></div>
</div>
</body>
</html>

As a side note, I tried changing the variable names for the div IDs so that they were unique, but that made it so the second gantt chart rendered and not the first.

Upvotes: 4

Views: 1326

Answers (1)

Pvb
Pvb

Reputation: 436

You should render svg to different div containers.

var svg = d3.select("#DIV_MyVar1")
            .append("svg").attr("width", 1000)
            .datum(MyVar).call(chart);

And of course div container with specified id should be present in the html document.

<div id="DIV_MyVar1"></div>

Here is a full your code with modified function.

<html>

<head>
    <title>Search Results</title>
    <meta charset="utf-8">
    <script src="http://code.jquery.com/jquery-latest.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script src="http://d3js.org/d3.v3.min.js"></script>
    <script language="Javascript" type="text/javascript" src="{% static 'd3-timeline.js' %}"></script>

    <STYLE type="text/css">
        .axis path,
        .axis line {
          fill: none;
          stroke: black;
          shape-rendering: crispEdges;
        }
        .axis text {
          font-family: sans-serif;
          font-size: 10px;
        }
        .timeline-label {
          font-family: sans-serif;
          font-size: 12px;
        }
        #timeline2 .axis {
          transform: translate(0px,30px);
          -ms-transform: translate(0px,30px); /* IE 9 */
          -webkit-transform: translate(0px,30px); /* Safari and Chrome */
          -o-transform: translate(0px,30px); /* Opera */
          -moz-transform: translate(0px,30px); /* Firefox */
        }
        .coloredDiv {
          height:20px; width:20px; float:left;
        }
    </STYLE>

</head>
<body>
<script language="Javascript" type="text/javascript">
    window.onload = function() {
        var MyVar = [{label: "F7", times: [{"starting_time":1420228800000, "ending_time":1420257600000}]}]


    function drawtimeline_MyVar(n) { //added parameter
    var chart = d3.timeline()
        .stack() // toggles graph stacking
        .rowSeperators("rgb(100,100,100)")
        .click(function (d, i, datum) {
                var myWindow=window.open("", "MsgWindow", "width=500, height=500");
                myWindow.document.write(d.info);
              })
        .scroll(function (x, scale) {
                $("#scrolled_date").text(scale.invert(x) + " to " + scale.invert(x+1000));
                })
        .showBorderFormat({marginTop:25, marginBottom:2, width:10, color:"rgb(0, 0, 0)"})
        .display("rect")
        .tickFormat({format: d3.time.format("%Y %j"), tickTime: d3.time.days, tickInterval: 1, tickSize: 12 })
        .margin({left:220, right:30, top:0, bottom:0})
        .width(1000)
            ;
    var svg = d3.select("#DIV_MyVar"+n).append("svg").attr("width", 1000)
        .datum(MyVar).call(chart);
    }


    //Call the function
    drawtimeline_MyVar(1);
    drawtimeline_MyVar(2);
    }
</script>

<div>
   <h4><p class="text-center">Requests</p></h4>
   <div id="DIV_MyVar1"></div><!-- changed id -->
</div>
<script language...>
  same script as above
</script>
<div>
  <h4><p class="text-center">Requests2</p></h4>
   <div id="DIV_MyVar2"></div><!-- changed id -->
</div>
</body>
</html>

Another version

<html>

<head>
    <title>Search Results</title>
    <meta charset="utf-8">
    <script src="http://code.jquery.com/jquery-latest.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script src="http://d3js.org/d3.v3.min.js"></script>
    <script language="Javascript" type="text/javascript" src="{% static 'd3-timeline.js' %}"></script>

    <STYLE type="text/css">
        .axis path,
        .axis line {
          fill: none;
          stroke: black;
          shape-rendering: crispEdges;
        }
        .axis text {
          font-family: sans-serif;
          font-size: 10px;
        }
        .timeline-label {
          font-family: sans-serif;
          font-size: 12px;
        }
        #timeline2 .axis {
          transform: translate(0px,30px);
          -ms-transform: translate(0px,30px); /* IE 9 */
          -webkit-transform: translate(0px,30px); /* Safari and Chrome */
          -o-transform: translate(0px,30px); /* Opera */
          -moz-transform: translate(0px,30px); /* Firefox */
        }
        .coloredDiv {
          height:20px; width:20px; float:left;
        }
    </STYLE>

</head>
<body>
<script language="Javascript" type="text/javascript">
    var MyVar = [{label: "F7", times: [{"starting_time":1420228800000, "ending_time":1420257600000}]}]

    function drawtimeline_MyVar() {
    var chart = d3.timeline()
        .stack() // toggles graph stacking
        .rowSeperators("rgb(100,100,100)")
        .click(function (d, i, datum) {
                var myWindow=window.open("", "MsgWindow", "width=500, height=500");
                myWindow.document.write(d.info);
              })
        .scroll(function (x, scale) {
                $("#scrolled_date").text(scale.invert(x) + " to " + scale.invert(x+1000));
                })
        .showBorderFormat({marginTop:25, marginBottom:2, width:10, color:"rgb(0, 0, 0)"})
        .display("rect")
        .tickFormat({format: d3.time.format("%Y %j"), tickTime: d3.time.days, tickInterval: 1, tickSize: 12 })
        .margin({left:220, right:30, top:0, bottom:0})
        .width(1000)
            ;
    var svg = d3.select("#DIV_MyVar").append("svg").attr("width", 1000)
        .datum(MyVar).call(chart);
    }
</script>

<div>
   <h4><p class="text-center">Requests</p></h4>
   <div id="DIV_MyVar"></div>
</div>
<script language="Javascript" type="text/javascript">
    var MyVar2 = [{label: "F7", times: [{"starting_time":1420228800000, "ending_time":1420257600000}]}]

    function drawtimeline_MyVar2() {
    var chart = d3.timeline()
        .stack() // toggles graph stacking
        .rowSeperators("rgb(100,100,100)")
        .click(function (d, i, datum) {
                var myWindow=window.open("", "MsgWindow", "width=500, height=500");
                myWindow.document.write(d.info);
              })
        .scroll(function (x, scale) {
                $("#scrolled_date").text(scale.invert(x) + " to " + scale.invert(x+1000));
                })
        .showBorderFormat({marginTop:25, marginBottom:2, width:10, color:"rgb(0, 0, 0)"})
        .display("rect")
        .tickFormat({format: d3.time.format("%Y %j"), tickTime: d3.time.days, tickInterval: 1, tickSize: 12 })
        .margin({left:220, right:30, top:0, bottom:0})
        .width(1000)
            ;
    var svg = d3.select("#DIV_MyVar2").append("svg").attr("width", 1000)
        .datum(MyVar2).call(chart);
    }

</script>
<div>
  <h4><p class="text-center">Requests2</p></h4>
   <div id="DIV_MyVar2"></div>
</div>
<script>
    window.onload = function() {
        //Call the function
        drawtimeline_MyVar();
        drawtimeline_MyVar2();
    }
</script>
</body>
</html>

Upvotes: 3

Related Questions