Reputation: 191
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
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