|
<!DOCTYPE html> |
|
<meta charset="utf-8"> |
|
<style> |
|
|
|
svg { |
|
font: 10px sans-serif; |
|
} |
|
|
|
|
|
.axis path, |
|
.axis line { |
|
fill: none; |
|
stroke: #000; |
|
shape-rendering: crispEdges; |
|
} |
|
|
|
.y.axis path { |
|
fill: none; |
|
stroke: #000; |
|
shape-rendering: crispEdges; |
|
} |
|
|
|
.brush .extent { |
|
stroke: #fff; |
|
fill-opacity: .125; |
|
shape-rendering: crispEdges; |
|
} |
|
|
|
.line { |
|
fill: none; |
|
} |
|
|
|
</style> |
|
|
|
|
|
<body> |
|
<script src="http://d3js.org/d3.v3.min.js"></script> |
|
<script> |
|
|
|
|
|
|
|
//setting up margin space around |
|
var margin = {top: 10, right: 10, bottom: 100, left: 40}, |
|
margin2 = {top: 430, right: 10, bottom: 20, left: 40}, |
|
width = 960 - margin.left - margin.right, |
|
height = 500 - margin.top - margin.bottom, |
|
height2 = 500 - margin2.top - margin2.bottom; |
|
|
|
var color = d3.scale.category10(); //default color range |
|
|
|
var parseDate = d3.time.format("%Y%m%d").parse; |
|
|
|
//setting up actual size of graph within the margins |
|
var x = d3.time.scale().range([0, width]), |
|
x2 = d3.time.scale().range([0, width]), |
|
y = d3.scale.linear().range([height, 0]), |
|
y2 = d3.scale.linear().range([height2, 0]); |
|
|
|
//referring to division of x axis |
|
var xAxis = d3.svg.axis().scale(x).orient("bottom"), |
|
xAxis2 = d3.svg.axis().scale(x2).orient("bottom"), |
|
yAxis = d3.svg.axis().scale(y).orient("left"); |
|
|
|
//thickness of graph lines x2 |
|
var brush = d3.svg.brush() |
|
.x(x2) |
|
.on("brush", brush); |
|
|
|
var line = d3.svg.line() |
|
.defined(function(d) { return !isNaN(d.bande); }) // valid temp value |
|
.interpolate("cubic") //makes graph slightly smoother |
|
.x(function(d) { return x(d.date); }) |
|
.y(function(d) { return y(d.bande); }); // x and y var for line |
|
|
|
//must refer to graph underneath |
|
var line2 = d3.svg.line() |
|
.defined(function(d) { return !isNaN(d.bande); }) |
|
.interpolate("cubic") |
|
.x(function(d) {return x2(d.date); }) |
|
.y(function(d) {return y2(d.bande); }); |
|
|
|
//appending body to svg element to apply transformations |
|
var svg = d3.select("body").append("svg") |
|
.attr("width", width + margin.left + margin.right) |
|
.attr("height", height + margin.top + margin.bottom); |
|
|
|
svg.append("defs").append("clipPath") |
|
.attr("id", "clip") |
|
.append("rect") |
|
.attr("width", width) |
|
.attr("height", height); |
|
|
|
|
|
|
|
|
|
|
|
|
|
//tooltips |
|
const tooltip = d3.select('#tooltip') |
|
const tooltipLine = svg.append('line') |
|
|
|
//t tipBox; |
|
|
|
let tipBox = svg.append('rect') |
|
.attr('width', width) |
|
.attr('height', height) |
|
.attr('opacity', 0) |
|
.on('mousemove', drawTooltip) |
|
.on('mouseout', removeTooltip); |
|
|
|
function removeTooltip() { |
|
if (tooltip) tooltip.style('display', 'none'); |
|
if (tooltipLine) tooltipLine.attr('stroke', 'none'); |
|
} |
|
|
|
function drawTooltip() { |
|
const year = Math.floor((x.invert(d3.mouse(tipBox.node())[0]) + 5) / 10) * 10; |
|
//} |
|
|
|
|
|
/*parsing csv with javascript*/ |
|
// states.sort((a, b) => { |
|
// return b.history.find(h => h.year == year).population - a.history.find(h => h.year == year).population; |
|
|
|
//}) |
|
|
|
tooltipLine.attr('stroke', 'black') |
|
.attr('x1', x(year)) // |
|
//.attr('x2', x(d.date)) |
|
.attr('y1', 0) |
|
.attr('y2', height); |
|
|
|
/* |
|
tooltip.html(date) |
|
.style('display', 'block') |
|
.style('left', d3.event.pageX + 20) |
|
.style('top', d3.event.pageY - 20) |
|
.selectAll() |
|
//.data(states).enter() |
|
.append('div') |
|
.style('color', d => d.color) |
|
.html(d => d.name + ': ' + d.history.find(h => h.year == year).population); |
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
//focus |
|
var focus = svg.append("g") |
|
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); |
|
|
|
var context = svg.append("g") |
|
.attr("transform", "translate(" + margin2.left + "," + margin2.top + ")"); |
|
|
|
d3.csv("bandes - Sheet1.csv", function(error, data) { |
|
|
|
color.domain(d3.keys(data[0]).filter(function(key) { return key !== "date"; })); |
|
|
|
data.forEach(function(d) { |
|
d.date = parseDate(d.date); |
|
}); |
|
|
|
var sources = color.domain().map(function(name) { |
|
return { |
|
name: name, |
|
values: data.map(function(d) { |
|
return {date: d.date, bande: +d[name]}; |
|
}) |
|
}; |
|
}); |
|
|
|
x.domain(d3.extent(data, function(d) { return d.date; })); |
|
y.domain([d3.min(sources, function(c) { return d3.min(c.values, function(v) { return v.bande; }); }), |
|
d3.max(sources, function(c) { return d3.max(c.values, function(v) { return v.bande; }); }) ]); |
|
x2.domain(x.domain()); |
|
y2.domain(y.domain()); |
|
|
|
var focuslineGroups = focus.selectAll("g") |
|
.data(sources) |
|
.enter().append("g"); |
|
|
|
var focuslines = focuslineGroups.append("path") |
|
.attr("class","line") |
|
.attr("d", function(d) { return line(d.values); }) |
|
.style("stroke", function(d) {return color(d.name);}) |
|
.attr("clip-path", "url(#clip)"); |
|
|
|
focus.append("g") |
|
.attr("class", "x axis") |
|
.attr("transform", "translate(0," + height + ")") |
|
.call(xAxis); |
|
|
|
focus.append("g") |
|
.attr("class", "y axis") |
|
.call(yAxis); |
|
|
|
var contextlineGroups = context.selectAll("g") |
|
.data(sources) |
|
.enter().append("g"); |
|
|
|
var contextLines = contextlineGroups.append("path") |
|
.attr("class", "line") |
|
.attr("d", function(d) { return line2(d.values); }) |
|
.style("stroke", function(d) {return color(d.name);}) |
|
.attr("clip-path", "url(#clip)"); |
|
|
|
context.append("g") |
|
.attr("class", "x axis") |
|
.attr("transform", "translate(0," + height2 + ")") |
|
.call(xAxis2); |
|
|
|
context.append("g") |
|
.attr("class", "x brush") |
|
.call(brush) |
|
.selectAll("rect") |
|
.attr("y", -6) |
|
.attr("height", height2 + 6); |
|
|
|
|
|
}); |
|
|
|
function brush() { |
|
x.domain(brush.empty() ? x2.domain() : brush.extent()); |
|
focus.selectAll("path.line").attr("d", function(d) {return line(d.values)}); |
|
focus.select(".x.axis").call(xAxis); |
|
focus.select(".y.axis").call(yAxis); |
|
} |
|
|
|
var body = d3.select('body') |
|
body.append('input') |
|
.attr('type','text') |
|
.attr('name','textInput') |
|
.attr('value','input text here') |
|
|
|
|
|
|
|
|
|
|
|
//tooltip logic |
|
/* |
|
var tooltip = d3.select("body") |
|
.append("div") |
|
.style("postion", "absolute") |
|
.style("z-index", "10") |
|
.style("visibility", "hidden") |
|
.style("background", "#000") |
|
.text("simple tooltip") |
|
|
|
d3.select("body") |
|
.selectAll("div") |
|
.data(data) |
|
.enter().append("div") |
|
.style("width", function(d) { return x(d) + "px"; }) |
|
*/ |
|
|
|
|
|
|
|
|
|
} |
|
</script> |