xxxxxxxxxx
<html lang="en">
<head>
<meta charset="utf-8">
<title>Doctor Who Earth Time Travel Journeys: Plotting Negative Values(PRE-SORTED)</title>
<script type="text/javascript" src="https://d3js.org/d3.v3.js"></script>
<style type="text/css">
body {
background-color: #E0E1DD;
margin: 0;
font-family: sans-serif;
}
h1 {
font-family: fantasy;
font-size: 36px;
line-height: 40px;
position: relative;
left: 10px;
color: #333333;
}
h2, p {
position: relative;
left: 10px;
color: #333333;
}
.bar.positive {
fill: #5B8F22;
}
.bar.negative {
fill: #7D5CC6;
}
.axis text {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
</style>
</head>
<body>
<script type="text/javascript">
var margin = {top: 20, right: 20, bottom: 20, left: 20};
var body = d3.select('body');
body.append('h1')
.text('Doctor Who Earth Time Travel Journeys')
body.append('h2')
.text('Hartnell (DW1) through Smith (DW11)')
body.append('p')
.text('This is a test page to create a PRE-SORTED Horizontal Bar Chart in D3 that accounts for the Negative Values in my Doctor Who CSV data')
</script>
</body>
<body>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script>
//Create the Positive and Negative Scales per Mike Bostock https://bl.ocks.org/mbostock/2368837 AND https://github.com/mbostock/d3/wiki/Ordinal-Scales#ordinal_rangeBands
//Say your dataset is an array of numbers, and includes both positive and negative values. Use two scales to construct the bar chart:
//a quantitative scale (such as a linear scale) to compute the bar positions along the x-axis, and an ordinal scale with rangeBands to
//compute the bar positions along the y-axis.
//For the y-axis, use rangeRoundBands to divide the vertical space into bands for each bar and specify the amount of padding between
//bars. The input (domain) to the ordinal scale is some identifying data—such as a name or a unique id. A simple such identifier
//is the data’s index - per MB
var margin = {top: 20, right: 20, bottom: 20, left: 20},
width = 600 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
var x = d3.scale.linear()
.range([0, width])
var y = d3.scale.ordinal()
.rangeRoundBands([0, height], .2);
var xAxis = d3.svg.axis()
.scale(x)
.orient("top");
//Create the SVG
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 + ")");
//Load in contents of PRESORTED CSV file (can't get the sort descending fuction to work properly)
//The chart needs to note the multiple time jumps in a single DW Episode - Keys are EpTitle & TimeJumpYrs
//Problem 1: some of the TimeJumpYrs values are in the billions, trillions
//Problem 2: Sometimes DW appears on Earth in a particular Earth Year, but doesn't make another time jump
//For the quantitative scale, compute the data domain (the minimum and maximum value) using d3.extent - per MB:
//Additional Note: This iteration of the code appears to drop the extremely high values at either end of the data scale (LJE)
d3.csv("Doctor Who EARTH Time Travel Journeys_LE_SortDesc.csv", type, function(error, data) {
x.domain(d3.extent(data, function(d) { return d.TimeJumpYrs; })).nice();
y.domain(data.map(function(d) { return d.TimeJumpYrs; }));
//Use both scales to position the bars. This is made slightly tricky in that SVG rects are positioned (the x and y attributes)
//by their top-left corner and cannot have a negative width or height. So, we must use the x- and y-scales to compute
//the position of the top-left corner, depending on whether the associated value is positive or negative:
//if the value is positive, then the data value determines the right edge of the bar,
//while if it’s negative, it determines the left edge of the bar. Hence the conditionals: (- Per MB)
svg.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", function(d) { return d.TimeJumpYrs < 0 ? "bar negative" : "bar positive"; })
.attr("x", function(d) { return x(Math.min(0, d.TimeJumpYrs)); })
.attr("y", function(d) { return y(d.TimeJumpYrs); })
.attr("width", function(d) { return Math.abs(x(d.TimeJumpYrs) - x(0)); })
.attr("height", y.rangeBand());
//Add x-axis line
svg.append("g")
.attr("class", "x axis")
.call(xAxis);
//Add y-axis line
svg.append("g")
.attr("class", "y axis")
.append("line")
.attr("x1", x(0))
.attr("x2", x(0))
.attr("y2", height);
});
function type(d) {
d.TimeJumpYrs = +d.TimeJumpYrs;
return d;
}
</script>
</body>
</html>
Modified http://d3js.org/d3.v3.js to a secure url
Modified http://d3js.org/d3.v3.min.js to a secure url
https://d3js.org/d3.v3.js
https://d3js.org/d3.v3.min.js