fenec
fenec

Reputation: 5806

how can i get a label on my lines in a line graph using d3.js

<!DOCTYPE html>
<meta charset="utf-8">
  <head>
    <title>Simple Line Graph using SVG and d3.js</title>
    <script src="http://d3js.org/d3.v3.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
    <style>
      /* tell the SVG path to be a thin blue line without any area fill */
      svg {
        border: 1px solid red;
      }

      .text-anchor{
      font-size: 15px;
      }

      path {
        stroke: steelblue;
        stroke-width: 1;
        fill: none;
      }

      .axis {
        shape-rendering: crispEdges;
      }

      .x.axis line {
        stroke: lightgrey;
      }

      .x.axis .minor {
        stroke-opacity: .5;
      }

      .x.axis path {
        display: none;
      }

      .y.axis line, .y.axis path {
        fill: none;
        stroke: #000;
      }
    </style>
  </head>
  <body>


  <div id="graph" class="aGraph" style="position:absolute;top:0px;left:0; float:left;"></div>


  <script>
    /* implementation heavily influenced by http://bl.ocks.org/1166403 */

    //var json=[{"created_at":1385481173,"ranking":[["#OBAMA",88],["#TCOT",82]]},{"created_at":1385481233,"ranking":[["#OBAMA",86],["#TCOT",62]]},{"created_at":1385481293,"ranking":[["#OBAMA",82],["#TCOT",42]]},{"created_at":1385481353,"ranking":[["#OBAMA",67],["#TCOT",62]]},{"created_at":1385481413,"ranking":[["#OBAMA",88],["#TCOT",22]]}];

   var json = ["{\"created_at\":1385481755,\"rankings\":[[\"#OBAMA\",91],[\"#TCOT\",65],[\"#OBAMACARE\",26],[\"#IRAN\",25],[\"#MTVSTARS\",20],[\"#BENGHAZI\",17],[\"#TEAPARTY\",16],[\"#LNYHBT\",12],[\"#PJNET\",11],[\"#CARAMEL\",11]]}","{\"created_at\":1385481749,\"rankings\":[[\"#OBAMA\",90],[\"#TCOT\",64],[\"#OBAMACARE\",26],[\"#IRAN\",25],[\"#MTVSTARS\",19],[\"#BENGHAZI\",17],[\"#TEAPARTY\",16],[\"#LNYHBT\",12],[\"#PJNET\",11],[\"#CARAMEL\",11]]}","{\"created_at\":1385481743,\"rankings\":[[\"#OBAMA\",90],[\"#TCOT\",64],[\"#OBAMACARE\",26],[\"#IRAN\",25],[\"#MTVSTARS\",18],[\"#BENGHAZI\",17],[\"#TEAPARTY\",16],[\"#LNYHBT\",12],[\"#PJNET\",11],[\"#CARAMEL\",11]]}","{\"created_at\":1385481737,\"rankings\":[[\"#OBAMA\",93],[\"#TCOT\",63],[\"#OBAMACARE\",28],[\"#IRAN\",27],[\"#MTVSTARS\",18],[\"#BENGHAZI\",17],[\"#TEAPARTY\",16],[\"#PJNET\",12],[\"#POPCORN\",11],[\"#CARAMEL\",11]]}","{\"created_at\":1385481731,\"rankings\":[[\"#OBAMA\",91],[\"#TCOT\",64],[\"#OBAMACARE\",29],[\"#IRAN\",27],[\"#MTVSTARS\",17],[\"#BENGHAZI\",17],[\"#TEAPARTY\",15],[\"#POPCORN\",11],[\"#CARAMEL\",11],[\"#IMMIGRATION\",11]]}","{\"created_at\":1385481725,\"rankings\":[[\"#OBAMA\",61],[\"#TCOT\",63],[\"#OBAMACARE\",28],[\"#IRAN\",26],[\"#MTVSTARS\",17],[\"#BENGHAZI\",16],[\"#TEAPARTY\",13],[\"#IMMIGRATION\",11],[\"#CARAMEL\",11],[\"#POPCORN\",11]]}","{\"created_at\":1385481719,\"rankings\":[[\"#OBAMA\",93],[\"#TCOT\",64],[\"#OBAMACARE\",28],[\"#IRAN\",26],[\"#MTVSTARS\",18],[\"#BENGHAZI\",16],[\"#TEAPARTY\",13],[\"#IMMIGRATION\",12],[\"#CARAMEL\",11],[\"#POPCORN\",11]]}","{\"created_at\":1385481713,\"rankings\":[[\"#OBAMA\",93],[\"#TCOT\",33],[\"#OBAMACARE\",28],[\"#IRAN\",26],[\"#MTVSTARS\",18],[\"#BENGHAZI\",16],[\"#TEAPARTY\",13],[\"#IMMIGRATION\",12],[\"#POPCORN\",11],[\"#CARAMEL\",11]]}","{\"created_at\":1385481707,\"rankings\":[[\"#OBAMA\",94],[\"#TCOT\",66],[\"#IRAN\",28],[\"#OBAMACARE\",28],[\"#MTVSTARS\",18],[\"#BENGHAZI\",16],[\"#TEAPARTY\",13],[\"#IMMIGRATION\",12],[\"#CARAMEL\",11],[\"#PJNET\",11]]}","{\"created_at\":1385481701,\"rankings\":[[\"#OBAMA\",94],[\"#TCOT\",66],[\"#IRAN\",28],[\"#OBAMACARE\",28],[\"#MTVSTARS\",16],[\"#BENGHAZI\",16],[\"#TEAPARTY\",13],[\"#PJNET\",12]]}"];

    // var temp_json;
    // $.ajax({
    //     type: 'GET',
    //     url: "http://localhost:4567/past_rankings.json", // JQuery loads serverside.php
    //     dataType: 'json',
    //     //data: json,
    //     async: false,
    //     success: function(json) { temp_json = json;}

    // });


    //comment this line if you want to use local data
    //json = temp_json ;

    //parse json
    $.each(json,function(index,value){
      json[index]= JSON.parse(value);
      // convert epoch time to js epoch time (milliseconds)
      json[index].created_at = json[index].created_at * 1000 ;
    });

    // define dimensions of graph
    var m = [80, 80, 80, 80]; // margins
    var w = 1200 - m[1] - m[3]; // width
    var h = 600 - m[0] - m[2]; // height
    var format = d3.time.format("%Y-%m-%d %H:%M:%S");

    //specify ranges and domains
    var color = d3.scale.category10();

    var x = d3.time.scale().domain( d3.extent(json,function (d){return d.created_at}) ).range([0, w]);

    var y = d3.scale.linear().domain([0, d3.max(json, function (d) {
            return Math.max(d.rankings[0][1],d.rankings[1][1]);
      })]).range([h, 0]);



    var line = d3.svg.line()
      // assign the X function to plot our line as we wish
      .x(function(d,i) { 
        //console.log(d);
        //console.log('Plotting X value for data point to be at: ' + d.created_at + ' using our xScale.');
        return x(d.created_at); 
      })
      .y(function(d) { 
        //console.log('Plotting Y value for data point to be at:' + d.rankings[0][1] + " using our yScale.");
        return y(d.rankings[0][1]); 
    })

    var line2 = d3.svg.line()
      // assign the X function to plot our line as we wish
      .x(function(d,i) { 
      //console.log(d);
        //console.log('Plotting X value for data point to be at: ' + d.created_at + ' using our xScale.');
        return x(d.created_at); 
      })
      .y(function(d) { 
        //console.log('Plotting Y value for data point to be at:' + d.rankings[0][1] + " using our yScale.");
        return y(d.rankings[1][1]); 
    })

    var line3 = d3.svg.line()
      // assign the X function to plot our line as we wish
      .x(function(d,i) { 
      //console.log(d);
        //console.log('Plotting X value for data point to be at: ' + d.created_at + ' using our xScale.');
        return x(d.created_at); 
      })
      .y(function(d) { 
        //console.log('Plotting Y value for data point to be at:' + d.rankings[0][1] + " using our yScale.");
        return y(d.rankings[2][1]); 
    })


    // Add an SVG element with the desired dimensions and margin.
    var graph = d3.select("#graph").append("svg:svg")
      .attr("width", w + m[1] + m[3])
      .attr("height", h + m[0] + m[2])
      .append("svg:g")
      .attr("transform", "translate(" + m[3] + "," + m[0] + ")");

    // create yAxis
    // var xAxis = d3.svg.axis().scale(x);//.ticks(-h).orient("bottom");//tickSize(-h).tickSubdivide(true);
    var xAxis = d3.svg.axis().scale(x).tickSize(-h).tickFormat(d3.time.format("%Y-%m-%d %H:%M:%S"));

    //collect all the rankings
    color.domain(d3.keys(json[0]).filter(function(key) { return key !== "date"; }));


    // Add the x-axis.
    graph.append("svg:g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + h + ")")
            .call(xAxis)
        .selectAll("text")  
      .attr("class","text-anchor")
      .attr("dx", "-2.48em")
      .attr("dy", ".15em")
      .attr("transform", function(d) {
        return "rotate(-65)" 
      });

      // create left yAxis
      var yAxisLeft = d3.svg.axis().scale(y).ticks(9).orient("left");
      // Add the y-axis to the left
      graph.append("svg:g")
      .attr("class", "y axis")
      .call(yAxisLeft);

      // Add the line by appending an svg:path element with the data line we created above
      // do this AFTER the axes above so that the line is above the tick-lines
      graph.append("svg:path").attr("d", line(json))
        .append("svg:g")
        .append("text")
        .attr("x", 10)
        .attr("y",10)
        .text("text");
      graph.append("svg:path").attr("d", line2(json)).style("stroke", "green");
      graph.append("svg:path").attr("d", line3(json)).style("stroke", "red");

  </script>



  </body>
</html>

I am Trying to get a label at the end of each line the same way as they do it here but it doesn't seem to work, i have these part that is suppose to draw a text but it is not working:

graph.append("svg:path").attr("d", line(json))
 .append("svg:g")
 .append("text")
 .attr("x", 10)
 .attr("y",10)
 .text("text");

Upvotes: 2

Views: 5699

Answers (2)

sam
sam

Reputation: 2486

I accept @Alex answer for writting the text along the path.. but

The Example you shown is a multiline graph which draws the line and text at the end one by one..

Likewise you tried to include lines manually one by one.. In such case you need to append the text also the same way one by one after drawing each line..

graph.append("svg:path").attr("d", line(json))
        .append("svg:g")
        .append("text")
        .attr("x", 10)
        .attr("y",10)
        .text("text");

This wont append the text at the end... Instead try something like this

graph.append("svg:path").attr("d", line2(json)).style("stroke", "green");



graph.append("text")
      .datum(function(d) { return {value: d.values[d.values.length - 1]}; })
      .attr("transform", function(d) { return "translate(" + x(d.value.xvalue) + "," +       y(d.value.yvalue) + ")"; })
      .attr("x", 3)
      .attr("dy", ".35em")
      .text("Text");

I will explain you what exactly i did...

.datum(function(d) { return {value: d.values[d.values.length - 1]}; })

I am returning the last point (x,y) values.. this changes according to your json format.. here (values) is a key for me..

.attr("transform", function(d) { return "translate(" + x(d.value.xvalue) + "," +       y(d.value.yvalue) + ")"; })

It transforms the text to that last(x,y)value... It gives you the desired output of appending the text at the end of the path(line)

Hope it Helps!

This is the code according to your json..It works check it out

    linesGroup.append("text")
      .datum(function(d) {return linedata.points[0] ; })
        .attr("transform", function(d) {console.log(d);console.log("translate(" + x(d.created_at) + "," + y(d.rate) + ")"); return "translate(" + x(d.created_at) + "," +       y(d.rate) + ")"; })
      .attr("x", 3)
      .attr("dy", ".35em")
    .text(function(d){return (d.tag);});

};

Upvotes: 1

Alex Reynolds
Alex Reynolds

Reputation: 96967

Take a look at this Gist (demo code) which shows the use of svg:textPath to label a path. The example shows a generic curved path, but it should just as easily apply to your line element.

Upvotes: 2

Related Questions