block by micahstubbs aa933f60bd432f7f3eed

Oil & Gas Production Interactive Linegraph - Log Scale

Full Screen

##Oil & Gas Production Interactive Linegraph in d3js

find the R script and the source data for this chart at the project repository

index.html

<!-- an iteration on //bl.ocks.org/d3noob/e99a762017060ce81c76 -->
<!DOCTYPE html>
<meta charset="utf-8">
<style> /* set the CSS */

body { font: 12px Arial;}

path { 
    stroke: steelblue;
    stroke-width: 2;
    fill: none;
}

.axis path,
.axis line {
    fill: none;
    stroke: grey;
    stroke-width: 1;
    shape-rendering: crispEdges;
}

.legend {
    font-size: 16px;
    font-weight: bold;
    text-anchor: middle;
}
/*
body {
    background-color: #F2E2D1;
}
*/

</style>
<body>
 <h1>Oil & Gas Production Interactive Linegraph - Log Scale</h1>
<p>Production data from well 3501522889 of the US Department of Energy's former <a href="//www.rmotc.doe.gov/">Rocky Mountain Oilfield Testing Center</a></p><p>click a product name to hide or show the line for that product</p>
<!-- load the d3.js library -->    
<script src="https://d3js.org/d3.v3.min.js"></script>
 
<script>

// Set the dimensions of the canvas / graph
var margin = {top: 30, right: 20, bottom: 70, left: 50},
    width = 920 - margin.left - margin.right,
    height = 400 - margin.top - margin.bottom;

// Parse the date / time
var parseDate = d3.time.format("%m/%d/%Y").parse;

// Set the ranges
var x = d3.time.scale().range([0, width]);
var y = d3.scale.log().range([height, 0]);

// Define the axes
var xAxis = d3.svg.axis().scale(x)
    .orient("bottom").ticks(7);

var yAxis = d3.svg.axis().scale(y)
    .orient("left")
    .ticks(5, ",.1s")
    .tickSize(6, 0);


// Define the line
var valueline = d3.svg.line()   
    .x(function(d) { return x(d.date); })
    // adding one to values to fit use with the log scale
    .y(function(d) { return y(d.value + 1); }); 
    
// Adds the svg canvas
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 + ")");

// Get the data
d3.csv("single-well.csv", function(error, data) {
    data.forEach(function(d) {
        d.date = parseDate(d.date);
        d.value = +d.value;
    });

    // Scale the range of the data
    x.domain(d3.extent(data, function(d) { return d.date; }));
    y.domain([1, d3.max(data, function(d) { return d.value; })]);

    // Nest the entries by key
    var dataNest = d3.nest()
        .key(function(d) {return d.key;})
        .entries(data);

    // var color = d3.scale.category10();   // set the color scale

    var blueBlueGreen = ["#b2df8a", "#1f78b4", "#a6cee3"];
    var greenOrangeViolet = ["#1b9e77", "#d95f02", "#7570b3"]

    var color = d3.scale.ordinal()
        .range(greenOrangeViolet) 

    legendSpace = width/dataNest.length; // spacing for the legend

    // Loop through each key
    dataNest.forEach(function(d,i) { 

        svg.append("path")
            .attr("class", "line")
            .style("stroke", function() { // Add the colors dynamically
                return d.color = color(d.key); })
            .attr("id", 'tag'+d.key.replace(/\s+/g, '')) // assign ID
            .attr("d", valueline(d.values))
            .on("mousemove", mMove)
            .append("title");

        // Add the Legend
        svg.append("text")
            .attr("x", (legendSpace/2)+i*legendSpace)  // space legend
            .attr("y", height + (margin.bottom/2)+ 5)
            .attr("class", "legend")    // style the legend
            .style("fill", function() { // Add the colors dynamically
                return d.color = color(d.key); })
            .on("click", function(){
                // Determine if current line is visible 
                var active   = d.active ? false : true,
                newOpacity = active ? 0 : 1; 
                // Hide or show the elements based on the ID
                d3.select("#tag"+d.key.replace(/\s+/g, ''))
                    .transition().duration(1000) 
                    .style("opacity", newOpacity); 
                // Update whether or not the elements are active
                d.active = active;
                })  
            .text(d.key); 

    });

    // Add the X Axis
    svg.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis);

    // Add the Y Axis
    svg.append("g")
        .attr("class", "y axis")
        .call(yAxis);

    // Add the text label for the Y axis
    svg.append("text")
        .attr("transform", "rotate(0)")
        //.attr("y", 0 - margin.left)
        .attr("y", 0)
        //.attr("x",0 - (height / 2))
        .attr("x", 15)
        .attr("dy", "1em")
        .style("text-anchor", "middle")
        .text("bbls");

    function mMove(){
            var m = d3.mouse(this);
            var mouseoverValue = Math.round(y.invert(m[1]));
            var dateFormat = d3.time.format("%A, %B %e %Y")
            var mouseoverDate = dateFormat(x.invert(m[0]));
            d3.selectAll(".line").select("title").html(mouseoverValue + " bbls" + "\n" + mouseoverDate);
        }

});

</script>
</body>