Desi Delite
Desi Delite

Reputation: 191

D3 line chart does not show tool tip and data points properly

I designed line graph using D3.js . Then I set data points and tool tips for it. There was a line drew. But it doesn't show data points and tool tips yet. Can anyone show me where I was wrong? Thank you. Here is my code....

<html>
<head>
<title>myD3Trial1</title>
<script src="http://mbostock.github.com/d3/d3.v2.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> 
<script src="jquery.tipsy.js"></script>     
<link href="tipsy.css" rel="stylesheet" type="text/css" />       
<style>
.axis path,
.axis line{
    fill: none;
    stroke: blue;
     stroke-width: 2px;
  }

.line{
    fill: none;
    stroke: black;
    stroke-width: 1px;
  }

.tick text{
    font-size: 12px;
  }

.tick line{
    opacity: 0.2;
  }  
</style>    
</head>
<body>
<script>
    
    var xAxisGroup = null,
	    dataCirclesGroup = null,
	    dataLinesGroup = null; 
    
    var maxDataPointsForDots = 50,
	    transitionDuration = 1000; 
    
   var pointRadius = 4; 
      
    var data = [{
            "creat_time": "2013-03-12 05:09:04",
            "record_status": "ok",
            "roundTripTime": "0"
        }, {
            "creat_time": "2013-03-12 14:59:06",
            "record_status": "ok",
            "roundTripTime": "0"
        }, {
            "creat_time": "2013-03-12 14:49:04",
            "record_status": "ok",
            "roundTripTime": "0"
        }, {
            "creat_time": "2013-03-13 14:39:06",
            "record_status": "ok",
            "roundTripTime": "0"
        },{
            "creat_time": "2013-03-12 14:29:03",
            "record_status": "ok",
            "roundTripTime": "0"
    }];
    var margin = {top: 20, right: 20, bottom: 30, left: 50};
    var width = 960 - margin.left - margin.right;
    var height = 100 - margin.top - margin.bottom;
    var parseDate = d3.time.format("%Y-%m-%d %H:%M:%S").parse;
    var x = d3.time.scale()
        .range([0, width]);

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

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

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

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


    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 + ")");

    data.forEach(function(d) {
        d.creat_time = parseDate(d.creat_time);
        d.roundTripTime = +d.roundTripTime;
    });

    x.domain(d3.extent(data, function(d) { return d.creat_time; }));
    y.domain(d3.extent(data, function(d) { return d.roundTripTime;}));

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

    

    svg.append("path")
          .datum(data)
          .attr("class", "line")
          .attr("d", line);
    
   
    // Draw the points
    
	if (!dataCirclesGroup) {
		dataCirclesGroup = svg.append('svg:g');
	}

	var circles = dataCirclesGroup.selectAll('.data-point')
		.data(data);

	circles
		.enter()
			.append('svg:circle')
				.attr('class', 'data-point')
				.style('opacity', 1e-6)
				.attr('cx', function(d) { return xAxis(d.x) })
				.attr('cy', function() { return yAxis(d.y) })
				.attr('r', function() { return (data.length <= maxDataPointsForDots) ? pointRadius : 0 })
			.transition()
			.duration(transitionDuration)
				.style('opacity', 1)
				.attr('cx', function(d) { return xAxis(d.x) })
				.attr('cy', function(d) { return yAxis(d.y) });

	circles
		.transition()
		.duration(transitionDuration)
			.attr('cx', function(d) { return xAxis(d.x) })
			.attr('cy', function(d) { return yAxis(d.y) })
			.attr('r', function() { return (data.length <= maxDataPointsForDots) ? pointRadius : 0 })
			.style('opacity', 1);

	circles
		.exit()
			.transition()
			.duration(transitionDuration)
				// Leave the cx transition off. Allowing the points to fall where they lie is best.
				//.attr('cx', function(d, i) { return xAxis(i) })
				.attr('cy', function() { return y(0) })
				.style("opacity", 1e-6)
				.remove();

      $('svg circle').tipsy({ 
        gravity: 'width', 
        html: true, 
        title: function() {
          var d = this.__data__;
	  //var pDate = d.x;
          return d.x; 
        }
      });    

</script>    
</body>
</html>

Upvotes: 2

Views: 611

Answers (1)

Mark
Mark

Reputation: 108512

First, the scale functions x and y should be used to position your circles, not the xAxis and yAxis functions.

Second, you keep using d.x and d.y but your data does not have x and y properties (hint, it does have "creat_time" and "roundTripTime" though).

Third, you are very confused about how to handle the enter and update pattern. On enter just do the append. On update do the positioning.

Forth, only put the things you wish to transition after the .transition() call (ie the opacity).

Putting all the advice together:

<html>
<head>
<title>myD3Trial1</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.js" charset="utf-8"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> 
<script src="https://rawgit.com/jaz303/tipsy/master/src/javascripts/jquery.tipsy.js"></script>     
<link href="https://rawgit.com/jaz303/tipsy/master/src/stylesheets/tipsy.css" rel="stylesheet" type="text/css" />       
<style>
.axis path,
.axis line{
    fill: none;
    stroke: blue;
     stroke-width: 2px;
  }

.line{
    fill: none;
    stroke: black;
    stroke-width: 1px;
  }

.tick text{
    font-size: 16px;
  }

.tick line{
    opacity: 0.2;
  }  
</style>    
</head>
<body>
<script>
    
    var xAxisGroup = null,
	    dataCirclesGroup = null,
	    dataLinesGroup = null; 
    
    var maxDataPointsForDots = 50,
	    transitionDuration = 1000; 
    
   var pointRadius = 4; 
      
    var data = [{
            "creat_time": "2013-03-12 05:09:04",
            "record_status": "ok",
            "roundTripTime": "0"
        }, {
            "creat_time": "2013-03-12 14:59:06",
            "record_status": "ok",
            "roundTripTime": "0"
        }, {
            "creat_time": "2013-03-12 14:49:04",
            "record_status": "ok",
            "roundTripTime": "0"
        }, {
            "creat_time": "2013-03-13 14:39:06",
            "record_status": "ok",
            "roundTripTime": "0"
        },{
            "creat_time": "2013-03-12 14:29:03",
            "record_status": "ok",
            "roundTripTime": "0"
    }];
    var margin = {top: 20, right: 20, bottom: 30, left: 50};
    var width = 960 - margin.left - margin.right;
    var height = 100 - margin.top - margin.bottom;
    var parseDate = d3.time.format("%Y-%m-%d %H:%M:%S").parse;
    var x = d3.time.scale()
        .range([0, width]);

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

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

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

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


    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 + ")");

    data.forEach(function(d) {
        d.creat_time = parseDate(d.creat_time);
        d.roundTripTime = +d.roundTripTime;
    });

    x.domain(d3.extent(data, function(d) { return d.creat_time; }));
    y.domain(d3.extent(data, function(d) { return d.roundTripTime;}));

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

    

    svg.append("path")
          .datum(data)
          .attr("class", "line")
          .attr("d", line);
    
   
    // Draw the points
    
	if (!dataCirclesGroup) {
		dataCirclesGroup = svg.append('svg:g');
	}

	var circles = dataCirclesGroup.selectAll('.data-point')
		.data(data);

	circles
		.enter()
			.append('svg:circle')
				.attr('class', 'data-point')
				.style('opacity', 1e-6);

	circles
		.attr('cx', function(d) { return x(d.creat_time) })
		.attr('cy', function(d) { return y(d.roundTripTime) })
		.attr('r', function() { return (data.length <= maxDataPointsForDots) ? pointRadius : 0 })
		.transition()
		.duration(transitionDuration)
		.style('opacity', 1);

	circles
		.exit()
			.transition()
			.duration(transitionDuration)
				// Leave the cx transition off. Allowing the points to fall where they lie is best.
				//.attr('cx', function(d, i) { return xAxis(i) })
				.attr('cy', function() { return y(0) })
				.style("opacity", 1e-6)
				.remove();

      $('svg circle').tipsy({ 
        gravity: 'width', 
        html: true, 
        title: function() {
          console.log(this.__data__);
          var d = this.__data__;
	  //var pDate = d.x;
          return d.creat_time.toLocaleDateString(); 
        }
      });

</script>    
</body>
</html>

Upvotes: 1

Related Questions