0

In my graph, i have added the tooltip to the path. but at present i am just showing the mouse value with the object label. instead of showing the mouse value how to show the exact array value ( drawing value ) at the point?

any one help me here please?

var datas = [
  {"date":1404075600000,"ActualPercentage" : 10, "PlanPercentage" : 5},
  {"date":1404680400000,"ActualPercentage" : 20, "PlanPercentage" : 15},
  {"date":1405285200000,"ActualPercentage" : 30, "PlanPercentage" : 25},
  {"date":1405890000000,"ActualPercentage" : 40, "PlanPercentage" : 35},
  {"date":1406494800000,"ActualPercentage" : 50, "PlanPercentage" : 45},
  {"date":1407099600000,"ActualPercentage" : 60, "PlanPercentage" : 55},
  {"date":1407704400000,"ActualPercentage" : 70, "PlanPercentage" : 65},
  {"date":1408309200000,"ActualPercentage" : 80, "PlanPercentage" : 85},
  {"date":1408914000000,"ActualPercentage" : 90, "PlanPercentage" : 90},
  {"date":1409518800000,"ActualPercentage" : 100, "PlanPercentage" :95}
]



var margin = {top: 20, right: 80, bottom: 30, left: 50},
    width = 960 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

var parseDate = d3.time.format( "%Y%m%d" ).parse;

var x = d3.time.scale().range([0, width]);
var y = d3.scale.linear().range([height, 0]);

var toolTipScale = d3.scale.linear().domain([height + 80, 80]).range([0, 100]);
var iScale = d3.scale.linear().domain([width + 80, 80]).range([datas.length, 0]);

var color = d3.scale.ordinal()
      .domain(["ActualPercentage", "PlanPercentage"])
      .range(["#FF0000", "#009933"]);

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

var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left"); 

var line = d3.svg.line()
    .interpolate("basis")
    .x(function(d) { return x(d.date); })
    .y(function(d) { return y(d.temperature); }); 


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

var div = d3.select("body").append("div")
            .attr("class", "tooltips")
            .style("opacity", 0);

  color.domain(d3.keys(datas[0]).filter(function(key) { return key !== "date"; }));

  datas.forEach(function(d) {
    
    var date = new Date(d.date);
    
  });

  var cities = color.domain().map(function(name) {
    return {
      name: name,
      values: datas.map(function(d) {
        return {date: d.date, temperature: +d[name]};
      })
    };
  });
  

  x.domain(d3.extent(datas, function(d) { return d.date; }));

  y.domain([
    d3.min(cities, function(c) { return d3.min(c.values, function(v) { return v.temperature; }); }),
    d3.max(cities, function(c) { return d3.max(c.values, function(v) { return v.temperature; }); })
  ]);

  svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis);

  svg.append("g")
      .attr("class", "y axis")
      .call(yAxis)
    // .append("text")
    //   .attr("transform", "rotate(-90)")
    //   .attr("y", 6)
    //   .attr("dy", ".71em")
    //   .style("text-anchor", "end")
    //   .text("Temperature (ºF)");

  var city = svg.selectAll(".city")
      .data(cities)
      .enter().append("g")
      .attr("class", "city");

  var path = city.append("path")
      .attr("class", "line")
      .style('cursor', 'pointer')
      .attr("d", function(d) { return line(d.values); })
      .style("stroke", function(d) { return color(d.name); });
      
  var totalLength = [path[0][0].getTotalLength()];
  
  path
      .attr("stroke-dasharray", totalLength + " " + totalLength)
      .attr("stroke-dashoffset", totalLength)
      .transition()
      .duration(2000)
      .ease("linear")
      .attr("stroke-dashoffset", 0);
      
 var circles = city.selectAll("circle")
        
         .data(function(d) {
           return d.values
         })
         .enter()
         .append("circle")
         .attr('class', 'circle')
         .attr("r", 3.5)
         .attr("cx", function(d, i) {
           return x(d.date)
         })
         .attr("cy", function(d) {
           return y(d.temperature)
         })
         .attr("fill", "transparent")
         .attr("stroke", "black")
         .attr("stroke-width", 0)
         .transition()
         .duration(3000)
         .attr("stroke-width", 2);
         
         path.on("mouseover", function (d, i) {
      
      div.transition()
                .duration(200)
                .style("opacity", 0.9);

            div.html(d.name +" : " +  Math.ceil(toolTipScale( d3.event.pageY)) )
                .style("left", (d3.event.pageX) + "px")
                .style("top", (d3.event.pageY - 28) + "px");

     })
     .on("mouseout", function (d, i) {
               
               div.transition()
                .duration(500)
                .style("opacity", 0);

     })
body {
  font: 10px sans-serif;
}

.axis path,
.axis line {
  fill: none;
  stroke: #000;
  shape-rendering: crispEdges;
}

.x.axis path {
  display: none;
}

.line {
  fill: none;
  stroke: steelblue;
  stroke-width: 1.5px;
}

body > div.tooltips {
 
 position: absolute;
 text-align: center;
 padding: 1em;
 font: 1.2em sans-serif;
 background: #02335D;
 border: 1px solid #fff;
 border-radius: 0.8em;
 pointer-events: none;
 color: #fff;
 white-space: no-wrap;
}
 
.overlay {
 fill: none;
 pointer-events: all;
}

.focus circle{
 fill: none;
 stroke: steelblue;

}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
3gwebtrain
  • 14,640
  • 25
  • 121
  • 247

1 Answers1

2

I am not sure if there is some possibility of showing the values accurately on mouse over of path. However it is possible to show the tool tip values on mouse over of circles.

Hope this is helpful.

Working Code Snippet:

var datas = [{
  "date": 1404075600000,
  "ActualPercentage": 10,
  "PlanPercentage": 5
}, {
  "date": 1404680400000,
  "ActualPercentage": 20,
  "PlanPercentage": 15
}, {
  "date": 1405285200000,
  "ActualPercentage": 30,
  "PlanPercentage": 25
}, {
  "date": 1405890000000,
  "ActualPercentage": 40,
  "PlanPercentage": 35
}, {
  "date": 1406494800000,
  "ActualPercentage": 50,
  "PlanPercentage": 45
}, {
  "date": 1407099600000,
  "ActualPercentage": 60,
  "PlanPercentage": 55
}, {
  "date": 1407704400000,
  "ActualPercentage": 70,
  "PlanPercentage": 65
}, {
  "date": 1408309200000,
  "ActualPercentage": 80,
  "PlanPercentage": 85
}, {
  "date": 1408914000000,
  "ActualPercentage": 90,
  "PlanPercentage": 90
}, {
  "date": 1409518800000,
  "ActualPercentage": 100,
  "PlanPercentage": 95
}]



var margin = {
    top: 20,
    right: 150,
    bottom: 30,
    left: 50
  },
  width = 960 - margin.left - margin.right,
  height = 500 - margin.top - margin.bottom;

var parseDate = d3.time.format("%Y%m%d").parse;

var x = d3.time.scale().range([0, width]);
var y = d3.scale.linear().range([height, 0]);

var toolTipScale = d3.scale.linear().domain([height + 80, 80]).range([0, 100]);
var iScale = d3.scale.linear().domain([width + 80, 80]).range([datas.length, 0]);

var color = d3.scale.ordinal()
  .domain(["ActualPercentage", "PlanPercentage"])
  .range(["#FF0000", "#009933"]);

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

var yAxis = d3.svg.axis()
  .scale(y)
  .innerTickSize(-width)
  .orient("left");

var line = d3.svg.line() 
  .x(function(d) {
    return x(d.date);
  })
  .y(function(d) {
    return y(d.temperature);
  });


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

var div = d3.select("body").append("div")
  .attr("class", "tooltips")
  .style("opacity", 0);

color.domain(d3.keys(datas[0]).filter(function(key) {
  return key !== "date";
}));

datas.forEach(function(d) {

  var date = new Date(d.date);

});

var cities = color.domain().map(function(name) {
  return {
    name: name,
    values: datas.map(function(d) {
      return {
        date: d.date,
        temperature: +d[name]
      };
    })
  };
});


x.domain(d3.extent(datas, function(d) {
  return d.date;
}));

y.domain([
  d3.min(cities, function(c) {
    return d3.min(c.values, function(v) {
      return v.temperature;
    });
  }),
  d3.max(cities, function(c) {
    return d3.max(c.values, function(v) {
      return v.temperature;
    });
  })
]);

svg.append("g")
  .attr("class", "x axis")
  .attr("transform", "translate(0," + height + ")")
  .call(xAxis);

svg.append("g")
  .attr("class", "y axis")
  .call(yAxis);

var city = svg.selectAll(".city")
  .data(cities)
  .enter().append("g")
  .attr('id', function(d) {
    return d.name;
  })
  .attr("class", "city");

var path = city.append("path")
  .attr("class", "line")
  .style('cursor', 'pointer')
  .attr("d", function(d) {
    return line(d.values);
  })
  .style("stroke", function(d) {
    return color(d.name);
  });

var totalLength = [path[0][0].getTotalLength()];

path
  .attr("stroke-dasharray", totalLength + " " + totalLength)
  .attr("stroke-dashoffset", totalLength)
  .transition()
  .duration(2000)
  .ease("linear")
  .attr("stroke-dashoffset", 0);

var circles = city.selectAll("circle")
  .data(function(d) {
    return d.values
  })
  .enter()
  .append("circle")
  .attr('class', 'circle')
  .attr("r", 3.5)
  .attr("cx", function(d, i) {
    return x(d.date)
  })
  .attr("cy", function(d) {
    return y(d.temperature)
  })
  .attr("fill", "transparent")
  .attr("stroke", "black")
  .attr("stroke-width", 0);

circles.transition()
  .duration(3000)
  .attr("stroke-width", 2);

circles.on("mouseover", function(d, i) {

    div.transition()
      .duration(200)
      .style("opacity", 0.9);
    var data = d3.select(this.parentNode).select("path").data()[0];
    div.html(data.name + " : " + d.temperature)
      .style("left", (d3.event.pageX) + "px")
      .style("top", (d3.event.pageY - 28) + "px");

  })
  .on("mouseout", function(d, i) {

    div.transition()
      .duration(500)
      .style("opacity", 0);

  });

var legend = svg.selectAll('.legend')
  .data(cities);

var legends = legend
  .enter()
  .append('g')
  .attr('class', 'legend')
  .attr('transform', function(d, i) {
    return "translate(" + (width+20) + "," + (i * 20) + ")";
  });

legends
  .append('circle')
  .attr('r', 7)
  .style('fill', function(d) {
    return color(d.name);
  });

legends
  .append('text')
  .attr("dx", 10)
  .attr("dy", 3.5)
  .text(function(d) {
    return d.name
  });

legends.on('click', function(d) {
  var path = d3.select("#" + d.name);
  var visibility = path.style("opacity");
  path.style("opacity", visibility == 1 ? 0 : 1)
});
body {
  font: 10px sans-serif;
}
.axis path,
.axis line {
  fill: none;
  stroke: #000;
  shape-rendering: crispEdges;
}
.x.axis path {
  display: none;
}
.line {
  fill: none;
  stroke: steelblue;
  stroke-width: 1.5px;
}
body > div.tooltips {
  position: absolute;
  text-align: center;
  padding: 1em;
  font: 1.2em sans-serif;
  background: #02335D;
  border: 1px solid #fff;
  border-radius: 0.8em;
  pointer-events: none;
  color: #fff;
  white-space: no-wrap;
}
.overlay {
  fill: none;
  pointer-events: all;
}
.focus circle {
  fill: none;
  stroke: steelblue;
}
.tick line{
  opacity: 0.2;
  stroke-dasharray: 5,5;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
Gilsha
  • 14,431
  • 3
  • 32
  • 47
  • yes, this working fine. further to extending your help i need 2 buttons two switch `off` and switch `on` the path with circles. so user can view whatever status they want. can you please update that as well. - thank you for your extended help. – 3gwebtrain Feb 17 '16 at 13:55
  • not only circles including the path. example while clicking on green button i don't want to show the green line ( let animation revert ) with circles. ( toggling the data ) – 3gwebtrain Feb 17 '16 at 14:23
  • Updated the answer. No. am from Kerala – Gilsha Feb 17 '16 at 14:43
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/103742/discussion-between-3gwebtrain-and-gilsha). – 3gwebtrain Feb 17 '16 at 14:48
  • In the graph, when i passing the date values, all are correct. But when i see in the graph the date is showing less than one day. how to fix it? ex ( instead of `May 12` I am getting `May 11` - like all tickets getting lesser – 3gwebtrain Feb 18 '16 at 06:31