Built with blockbuilder.org
xxxxxxxxxx
<meta charset="utf-8">
<style>
body {
font-family: sans-serif;
}
</style>
<div>
<p>Choose band width:
<select>
<option value="None">None</option>
<option value="2.5">2.5</option>
<option value="5">5</option>
<option value="10">10</option>
<option value="20">20</option>
</select>
</p>
</div>
<div>
<svg width="800" height="400"></svg>
</div>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
const inputData = d3.range(500).map(d3.randomNormal(50,10));
inputData.sort();
var data = [];
var domainMin, domainMax, domainRange, noOfBands, maxIndex;
var xAxisValues = [];
var wheat = true;
var select = d3.select("select");
select.property("value", 10)
select.on("change", function(d){
var selectedBand = d3.select("select").property("value");
if (selectedBand == "None") {
wheat = false;
drawChart();
} else {
wheat = true;
selectedBand = +selectedBand;
updateData(selectedBand);
drawChart();
};
})
var f = d3.format(".1f");
var svg = d3.select("svg"),
margin = {top: 10, right: 30, bottom: 30, left: 30},
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom,
g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
const bandWidth = 10;
updateData(bandWidth);
drawChart();
function updateData (newBandwidth) {
let bandWidth = newBandwidth;
domainMin = thisBand(inputData[0], bandWidth);
domainMax = thisBand(inputData[inputData.length - 1], bandWidth) + bandWidth;
domainRange = domainMax - domainMin;
noOfBands = domainRange/bandWidth;
let n = 0;
let groupI = -1;
let currentGroup = domainMin;
if (data.length == 0) { //create initial dataset
for (n; n < inputData.length; n++) {
if (currentGroup == thisBand(inputData[n], bandWidth)) {
groupI = groupI + 1;
} else {
groupI = 0;
currentGroup = thisBand(inputData[n], bandWidth);
};
let datum = {}
datum.group = thisBand(inputData[n], bandWidth);
datum.id = n;
datum.groupIndex = groupI;
datum.value = inputData[n];
data.push(datum);
};
} else { //update established dataset
for (n; n < inputData.length; n++) {
if (currentGroup == thisBand(inputData[n], bandWidth)) {
groupI = groupI + 1;
} else {
groupI = 0;
currentGroup = thisBand(inputData[n], bandWidth);
};
data[n].group = thisBand(inputData[n], bandWidth);
data[n].groupIndex = groupI;
};
};
maxIndex = d3.max(data, function(d){ return d.groupIndex });
xAxisValues = [];
let i = 0;
for (i; i < (noOfBands + 1); i++) {
let axisValue = domainMin + (i * bandWidth);
xAxisValues.push(axisValue);
};
};
function drawChart() {
d3.select(".x-axis").remove();
const x = d3.scaleLinear()
.rangeRound([0, width])
.domain([0, 100]);
let xAxis = d3.axisBottom(x)
.tickFormat(f)
.tickValues(xAxisValues);
let xAxisG = g.append("g")
.attr("class", "x-axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
xAxisG.selectAll("line")
.attr("y1", -height)
.style("stroke", "lightgrey");
xAxisG.select(".domain")
.remove();
const y = d3.scaleLinear()
.domain([0, maxIndex])
.range([height, 0]);
var circles = g.selectAll("circle")
.data(data, function(d) { return d.id; })
circles.enter()
.append("circle")
.merge(circles)
.attr("r", 2)
.style("fill", "none")
.style("stroke", "MediumVioletRed")
.style("opacity", 0.5)
.attr("cx", function(d){ return x(d.value) })
.transition()
.duration(500)
.attr("cy", function(d){
return wheat ? y(d.groupIndex) : y(15);
});
};
function thisBand(n, bandwidth) {
return Math.floor(n / bandwidth) * bandwidth;
};
</script>
https://d3js.org/d3.v4.min.js