Last active
May 12, 2016 12:43
-
-
Save siddharthpolisiti/fce500057d7cf378cbbbb1718ea6a21c to your computer and use it in GitHub Desktop.
MultiLine Chart with legends and tooltips
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<head> | |
<style> | |
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; | |
} | |
div.tooltip { | |
position: absolute; | |
padding: 10px; | |
background: #f4f4f4; | |
border: 0px; | |
border-radius: 3px; | |
pointer-events: none; | |
font-size: 11px; | |
color: #000; | |
line-height: 16px; | |
border: 1px solid #d4d4d4; | |
} | |
</style> | |
<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script> | |
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script> | |
</head> | |
<body> | |
<script> | |
var maindata = [{ | |
"date": "21-APR-16 04:19 AM", | |
"Delhi": 30, | |
"Mumbai": 28 | |
}, { | |
"date": "21-APR-16 05:19 AM", | |
"Delhi": 32, | |
"Mumbai": 30 | |
}, { | |
"date": "21-APR-16 06:19 AM", | |
"Delhi": 34, | |
"Mumbai": 34 | |
}, { | |
"date": "21-APR-16 10:19 AM", | |
"Kolkata": 34 | |
}, { | |
"date": "21-APR-16 11:19 AM", | |
"Delhi": 42, | |
"Chennai": 40, | |
"Kolkata": 36 | |
}]; | |
var cities = [] | |
var parseDate = d3.time.format("%d-%b-%y %H:%M %p").parse; | |
maindata.forEach(function(d) { | |
cities.push(d3.keys(d).filter(function(key) { | |
return key !== "date" && key !== "maxLength"; | |
})); | |
}); | |
cities = d3.set(d3.merge(cities)).values(); | |
console.log(cities) | |
var myData = []; | |
var allValues = []; | |
var allDates =[]; | |
cities.forEach(function(city){ | |
var cityData = {}; | |
cityData.name = city; | |
cityData.values = []; | |
maindata.forEach(function(md){ | |
if (md[city]){ | |
allValues.push(md[city]) | |
allDates.push(parseDate(md.date)) | |
cityData.values.push({date: parseDate(md.date), value: md[city]}) | |
} | |
}) | |
myData.push(cityData) | |
}); | |
var that = this; | |
var deepClonedCopy = jQuery.extend(true, {}, maindata); | |
var data; | |
data = $.map(deepClonedCopy, function(el) { | |
return el | |
}); | |
var margin = { | |
top: 15, | |
right: 30, | |
bottom: 20, | |
left: 30 | |
}, | |
width = 960 - margin.left - margin.right, | |
height = 500 - margin.top - margin.bottom; | |
if (data.length >= 1) { | |
var parseDate = d3.time.format("%d-%b-%y %H:%M %p").parse; | |
var maxDate = d3.time.hour.offset(parseDate(d3.max(data, function(d) { | |
return d.date; | |
})), +1); | |
var minDate = d3.time.hour.offset(parseDate(d3.min(data, function(d) { | |
return d.date; | |
})), -1); | |
var div = d3.select("body").append("div") | |
.attr("class", "tooltip") | |
.style("opacity", 0); | |
var x = d3.time.scale() | |
.domain(d3.extent(allDates)) | |
.range([0, width]); | |
var y = d3.scale.linear() | |
.domain([0, d3.max(allValues)]) | |
.range([Math.ceil(height), 0]); | |
var color = d3.scale.category10(); | |
var xAxis = d3.svg.axis() | |
.scale(x) | |
.orient("bottom").ticks(4); | |
var yAxis = d3.svg.axis() | |
.scale(y) | |
.orient("left").ticks(4).tickSize(-width, 0, 0); | |
var line = d3.svg.line() | |
.x(function(d) { | |
return x(d.date); | |
}) | |
.y(function(d) { | |
return y(d.value); | |
}); | |
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 + ")"); | |
svg.append("g") | |
.attr("class", "x axis") | |
.attr("transform", "translate(0," + height + ")") | |
.call(xAxis); | |
svg.append("g") | |
.attr("class", "y axis") | |
.call(yAxis); | |
var wsf = svg.selectAll(".wsf") | |
.data(myData) | |
.enter().append("g") | |
.attr("class", "wsf"); | |
wsf.append("path") | |
.attr("class", "line") | |
.attr("d", function(d) { | |
return line(d.values); | |
}) | |
.style("stroke", function(d) { | |
return color(d.name); | |
}); | |
wsf.selectAll(".dot") | |
.data(function(d) { | |
return d.values; | |
}) | |
.enter().append("circle") | |
.attr("class", "dot") | |
.attr("r", 3) | |
.attr("cx", function(d) { | |
return x(d.date); | |
}) | |
.attr("cy", function(d) { | |
return y(d.value); | |
}) | |
.attr("stroke", function(d) { | |
return color(this.parentNode.__data__.name) | |
}) | |
.attr("fill", function(d) { | |
return color(this.parentNode.__data__.name) | |
}) | |
//.attr("fill-opacity", .5) | |
//.attr("stroke-width", 2) | |
.on("mouseover", function(d) { | |
formatDate = d3.time.format("%d-%m-%Y %H:%M %p"); | |
div.transition().duration(100).style("opacity", .9); | |
div.html(this.parentNode.__data__.name + "<br/>" +d.value+"°C on "+d.date ) | |
.style("left", (d3.event.pageX) + "px").style("top", (d3.event.pageY - 28) + "px").attr('r', 8); | |
d3.select(this).attr('r', 8) | |
}).on("mouseout", function(d) { | |
div.transition().duration(600).style("opacity", 0) | |
d3.select(this).attr('r', 3); | |
}); | |
var legend = svg.selectAll(".legend") | |
.data(cities) | |
.enter().append("g") | |
.attr("class", "legend") | |
.attr("transform", function(d, i) { | |
return "translate(0," + i * 20 + ")"; | |
}); | |
legend.append("rect") | |
.attr("x", width - 18) | |
.attr("width", 18) | |
.attr("height", 4) | |
.style("fill", function(d) { | |
return color(d); | |
}); | |
legend.append("text") | |
.attr("x", width - 24) | |
.attr("y", 6) | |
.attr("dy", ".35em") | |
.style("text-anchor", "end") | |
.text(function(d) { | |
return d; | |
}); | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Adopted from Mike Bostock’s Multiseries line chart.