block by nivas8292 abc8c7bc645e002c9c2d

Weather App - Line / Bar Graph with Custom Tooltip

Full Screen

index.html

<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>

main.css

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;
}