Built with blockbuilder.org
xxxxxxxxxx
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
line {
stroke: black;
stroke-opacity: 0.4;
stroke-dasharray: 10;
}
svg {
margin: 20px;
background: rgba(0,0,0,0.05);
}
circle {
fill-opacity: 0.8;
stroke: black;
stroke-opacity: 0.3;
}
div {
font-family: arial;
}
div > * {
margin:5px;
padding: 5px;
}
</style>
</head>
<body>
<div>
<div>Choose which axis to bin on</div>
<button onclick="transform('cx','x')">X-Axis</button>
<button onclick="transform('cy','y')">Y-Axis</button>
<button onclick="transform(null, 'both')">Both</button>
</div>
<script>
const length = 300;
const radius = 15;
const margin = 20;
const transitionDuration = 500;
// Feel free to change or delete any of the code you see in this editor!
var svg = d3.select("body").append("svg")
.attr("width", length)
.attr("height", length);
const axisData = {
'both': [
{id:"horizontal", x1: 0, x2: length, y1: length/2, y2:length/2},
{id: "vertical", x1: length/2, x2: length/2, y1: 0, y2:length},
],
'x': [{id:"vertical", x1: 0, x2: length, y1: length/2, y2:length/2}],
'y': [{id:"horizontal", x1: length/2, x2: length/2, y1: 0, y2:length}]
};
const scalePos = d3.scaleQuantize()
.domain([0, 100])
.range(d3.range(margin, length - margin, margin));
const randomScale = d3.scaleQuantize()
.domain([0, 1])
.range(d3.range(0, 100, margin));
const colorScale = d3.scaleOrdinal(["#FE96BD","#E4A9E0","#B8BEF6","#83D2FA","#55E2EB","#55ECCD","#81F2A6","#B7F382","#EFEE6A" ]);
const rand = () => randomScale(Math.random());
let data = [
{id: "c1", "cx": rand(), "cy": rand()},
{id: "c2", "cx": rand(), "cy": rand()},
{id: "c3", "cx": rand(), "cy": rand()},
{id: "c4", "cx": rand(), "cy": rand()},
{id: "c5", "cx": rand(), "cy": rand()},
{id: "c6", "cx": rand(), "cy": rand()},
{id: "c7", "cx": rand(), "cy": rand()},
{id: "c8", "cx": rand(), "cy": rand()},
{id: "c9", "cx": rand(), "cy": rand()}
]
/* data = [
{id: "c1", "cx": 0, "cy": 10},
{id: "c2", "cx": 10, "cy": 20},
{id: "c3", "cx": 0, "cy": 30},
{id: "c4", "cx": 10, "cy": 40},
{id: "c5", "cx": 80, "cy": 50},
{id: "c6", "cx": 90, "cy": 60},
{id: "c7", "cx": 80, "cy": 70},
{id: "c8", "cx": 90, "cy": 80},
{id: "c9", "cx": 50, "cy": 70}
] */
function drawAxis(data) {
const d = svg.selectAll("line")
.data(data);
d.exit()
.transition()
.duration(transitionDuration)
.style("stroke-opacity", 0)
d
.transition()
.duration(transitionDuration)
.style("stroke-opacity", 0.4)
.attr("x1", d => d.x1)
.attr("x2", d => d.x2)
.attr("y1", d => d.y1)
.attr("y2", d => d.y2);
d.enter()
.append("line")
.attr("x1", d => d.x1)
.attr("x2", d => d.x2)
.attr("y1", d => d.y1)
.attr("y2", d => d.y2)
.transition()
.duration(transitionDuration)
.style("stroke-opacity", "auto");
}
function drawCircle(data) {
const d = svg.selectAll("circle").data(data, d => d.id);
d
.transition()
.ease(d3.easeBounceOut)
.duration(transitionDuration * 1.5)
.attr("cx", d => scalePos(d.cx))
.attr("cy", d => scalePos(d.cy))
.attr("id", d => d.id);
d.enter()
.append("circle")
.attr("cx", d => scalePos(d.cx))
.attr("cy", d => scalePos(d.cy))
.attr("r", radius)
.style("fill", (d,i) => colorScale(i))
.attr("id", d => d.id);
}
drawAxis(axisData['both']);
drawCircle(data);
function transform(parameter, axis) {
drawAxis(axisData[axis]);
drawCircle(axis === 'both' ? data : generateBinsData(data, parameter, axis));
}
function generateBinsData(data, parameter, orientation) {
var histogram = d3.histogram()
.value(function(d) { return d[parameter]; })
.domain(scalePos.domain())
.thresholds(margin);
const result = [];
var bins = histogram(data);
bins.forEach(d => {
if(d.length > 0) {
d.reverse().forEach((binData,i) => {
console.log(binData)
const point = {
id: binData.id,
cx: orientation === 'x' ? d.x0 : 50 - i * 8,
cy: orientation === 'y' ? d.x0 : 50 - i * 8,
};
result.push(point);
});
}
});
return result;
}
</script>
</body>
https://d3js.org/d3.v4.min.js