Built with blockbuilder.org
xxxxxxxxxx
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-time-format.v2.min.js"></script>
<style>
.axis path,
.axis line {
fill: none;
stroke: #020202;
shape-rendering: crispEdges;
}
.axis text {
font: 10px sans-serif;
}
.cells path {
fill: none;
pointer-events: all;
}
.dropdown {
position: absolute;
}
</style>
</head>
<body>
<select id="speciesDropdown" class="dropdown"></select>
<script>
//global veriables
var margin = { top: 40, right: 121, bottom: 102, left: 40};
var width = 960 - margin.left - margin.right;
var height = 500 - margin.top - margin.bottom;
var parseDate = d3.timeParse("%d-%b-%y");
var commonName = 'Carob Tree';
Array.prototype.unique = function() {
return this.filter(function (value, index, self) {
return self.indexOf(value) === index;
});
}
//append svg to body
var svg = d3.select('body')
.append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
//append group element to svg
var g = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
//define x-scale
var x = d3.scaleTime()
.range([0, width])
//axis generator
var axis = d3.axisBottom()
.scale(x)
.ticks(20);
//load data
d3.csv("trees.csv", function(error, data) {
if (error) throw error;
//convert date and numbers strings to numberical
data.forEach(function(d) {
d.Planted = parseDate(d.Planted);
d.NumberofTrees = +d.NumberofTrees;
d.TreeID = +d.TreeID;
})
//define domain of x-scale
x.domain(d3.extent(data, function(d) { return d.Planted;}));
var species = data.map(function(data) {
return data.CommonName;
})
species = species.unique();
species.sort();
var speciesDropdown = d3.select('#speciesDropdown')
.on('change',onChange);
var options = speciesDropdown
.selectAll('option')
.data(species).enter()
.append('option')
.attr('value', function(d, i){return i;})
.text(function (d) { return d; });
//call axis
g.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(" + [0, height-margin.bottom] + ")")
.call(axis);
var cells = g.append("g")
.attr("class", "cells");
function onChange() {
//connects the value of the dropdown to the data
var selectedOptionValue = speciesDropdown.property('value');
selectedOptionValue = species[selectedOptionValue];
var filteredData = data.filter(function(d) {return d.CommonName === selectedOptionValue});
//simulate
var simulation = d3.forceSimulation(filteredData)
.force("x", d3.forceX(function(d) { return x(d.Planted); }).strength(1))
.force("y", d3.forceY(height / 2))
.force("collide", d3.forceCollide(4))
.stop();
//force iterations: tick 120 times
for (var i = 0; i < 120; ++i) simulation.tick();
cells.selectAll("g").remove();
var cell = cells.selectAll("g")
.data(d3.voronoi()
.extent([[-margin.left, -margin.top], [width + margin.right, height + margin.top]])
.x(function(d) { return d.x; })
.y(function(d) { return d.y; })
.polygons(filteredData), function(d, i) {return i});
var liveCell = cell.enter().append("g");
//append circles to voronoi cells
liveCell.append("circle")
.attr("r", 3)
.attr("cx", function(d) { return d.data.x;})
.attr("cy", function(d) { return d.data.y;})
.style("opacity", 1)
.style("fill", "darkseagreen")
// cell.append("path")
// .attr("d", function(d) { return "M" + d.join("L") + "Z"; });
}
});
</script>
</body>
https://d3js.org/d3.v4.min.js
https://d3js.org/d3-time-format.v2.min.js