<html>
<head>
<title>Weather App</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="main.css">
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<style>
.key {
padding: 10px;
display: inline-block;
}
.key-text {
vertical-align: super;
}
p {
display: inline-block;
margin: 20px;
}
</style>
</head>
<body>
<div id="keys">
<p>
<span class="key-text">Temperature</span>
<span class="key" id="temp-key"></span>
</p>
<p>
<span class="key-text">Rainfall</span>
<span class="key" id="rain-key"></span>
</p>
</div>
<script>
var w = 900;
var h = 440;
var margin = {
top: 50,
bottom: 90,
left: 70,
right: 70
};
var width = w - margin.left - margin.right;
var height = h - margin.top - margin.bottom;
var chart = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h)
.attr("id", "chart")
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var textData = chart.append("text")
.attr('id', 'text-data')
.attr("transform", "translate(" + width / 2 + ",0)")
.attr("dy", -25)
.style("text-anchor", "middle")
var temperatureScale = d3.scale.linear()
.range([height, 0]);
var rainScale = d3.scale.linear()
.range([height, 0]);
var timeScale = d3.time.scale()
.range([0 + 2, width - 2]);
var xAxis = d3.svg.axis()
.scale(timeScale)
.tickFormat(d3.time.format("%b %Y"))
.orient("bottom");
var yTempAxis = d3.svg.axis()
.scale(temperatureScale)
.tickFormat(function (d) {
return (parseInt(d) / 10).toString() + "." + (parseInt(d) % 10);
})
.orient("right");
var yRainAxis = d3.svg.axis()
.scale(rainScale)
.orient("left");
var line = d3.svg.line()
.x(function (d) {
return timeScale(createDate(d.DATE));
})
.y(function (d) {
return rainScale(d.PRCP);
})
.interpolate("linear");
var bisectDate = d3.bisector(function (d) {
return d.DATE;
}).left;
d3.select('#temp-key').style("background", "#95cddf");
d3.select('#rain-key').style("background", "#cc627a");
function drawAxis(params) {
this.append("g")
.classed("x axis", true)
.attr("transform", "translate(0," + height + ")")
.call(params.axis.x)
.selectAll("text")
.attr("transform", "rotate(45)")
.style("text-anchor", "start");
this.append("g")
.classed("axis yr", true)
.attr("transform", "translate(" + width + ", 0)")
.call(params.axis.yr);
this.append("g")
.classed("axis yl", true)
.call(params.axis.yl);
this.select(".x.axis")
.append("text")
.style("text-anchor", "middle")
.attr("transform", "translate(" + width / 2 + ",80)")
.text("Time");
this.select(".yr.axis")
.append("text")
.style("text-anchor", "start")
.attr("dy", -12)
.text("Temp (\u2103)");
this.select(".yl.axis")
.append("text")
.style("text-anchor", "end")
.attr("dy", -12)
.text("Rainfall");
}
function plot(params) {
drawAxis.call(this, params);
//enter()
//For Temperature
this.selectAll(".temperature")
.data(params.data)
.enter()
.append("line")
.classed("temperature", true);
//For Rain (PRCP)
this.selectAll(".rain")
.data([params.data])
.enter()
.append("path")
.classed("rain", true);
//update
//For Temperature
this.selectAll(".temperature")
.attr("x1", function (d) {
return params.scale.time(createDate(d.DATE))
})
.attr("y1", function (d) {
return params.scale.temperature(parseInt(d.TMIN))
})
.attr("x2", function (d) {
return params.scale.time(createDate(d.DATE))
})
.attr("y2", function (d) {
return params.scale.temperature(parseInt(d.TMAX))
});
//For Rain
this.selectAll(".rain")
.attr("d", function (d) {
return line(d);
});
//exit()
//For Temperature
this.selectAll(".temperature")
.data(params.data)
.exit()
.remove();
//For Rain
this.selectAll(".rain")
.data([params.data])
.exit()
.remove();
this.on("mousemove", function () {
var x = d3.mouse(this)[0];
var date = timeScale.invert(x);
var dateString = createString(date);
var i = bisectDate(params.data, dateString, 1);
var d = params.data[i];
if (!d) {
return;
}
var cursor = d3.select('#cursor');
if (cursor.empty()) {
cursor = d3.select(this).append("line")
.attr('id', 'cursor')
.attr('y1', 0)
.attr('y2', height);
}
cursor.attr('x1', x)
.attr('x2', x);
tempMin = d.TMIN;
tempMin = tempMin.substr(0, tempMin.length - 1) + '.' + tempMin.slice(-1);
tempMax = d.TMAX;
tempMax = tempMax.substr(0, tempMax.length - 1) + '.' + tempMax.slice(-1);
var displayDay = d3.time.format("%a., %b. %e, %Y")
var str = displayDay(date) + " Min Temp : " + tempMin + "\u2103" + " Max Temp : " + tempMax + "\u2103";
d3.select('#text-data').text(str);
});
}
function createDate(str) {
return d3.time.format("%Y%m%d").parse(str);
}
function createString(date) {
format = d3.time.format("%Y%m%d");
return format(date);
}
d3.csv("climate_data.csv", function (err, data) {
temperatureScale.domain([d3.min(data, function (d) {
return parseInt(d.TMIN)
}), d3.max(data, function (d) {
return parseInt(d.TMAX)
})]);
timeScale.domain(d3.extent(data, function (d) {
return createDate(d.DATE);
}));
rainScale.domain(d3.extent(data, function (d) {
return parseInt(d.PRCP)
}));
plot.call(chart, {
data: data,
scale: {
temperature: temperatureScale,
time: timeScale,
rain: rainScale,
},
axis: {
x: xAxis,
yr: yTempAxis,
yl: yRainAxis,
}
});
});
</script>
</body>
</html>
body, html {
margin:0;
padding:0;
font-family:"Arial", sans-serif;
font-size:0.95em;
text-align:center;
}
#chart {
background-color:#F5F2EB;
border: 1px solid #CCC;
}
.bar {
fill:purple;
shape-rendering:crispEdges;
}
.bar-label {
text-anchor:end;
fill:white;
}
.axis path,
.axis line {
fill:none;
stroke:#000;
shape-rendering:crispEdges;
}
.gridline path,
.gridline line {
fill: none;
stroke: #ccc;
shape-rendering: crispEdges;
}
.trendline {
fill: none;
stroke: #ccc;
stroke-width: 2;
/*stroke-dasharray:10;*/
}
.area {
fill: #ccc;
stroke: #ccc;
opacity: 0.25;
}
.donut {
opacity:0.1;
}
.axis-label {
text-anchor: middle;
}
.chart-header {
text-transform: capitalize;
font-size: 110%;
}
.temperature {
stroke:#95cddf;
stroke-width:2px;
}
.rain {
fill:none;
stroke:#cc627a;
stroke-width:0.5;
}
#cursor {
stroke: black;
}