<html>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<button onclick="changeData()">Update data</button>
<svg width="550" height="250" id="data-viz">
<g transform="translate(30, 100)"></g>
</svg>
<script>
let initialRender = true;
let selectedData1 = true;
const margin = {
top: 10,
right: 30,
bottom: 30,
left: 30,
},
width = 550 - margin.left - margin.right,
height = 150 - margin.top - margin.bottom;
function printChart(asd, data, dataGradients) {
console.clear();
const svg = d3.select('#data-viz');
// const isZoomed = map.getZoom() > zoomThreshold;
// if (isZoomed !== changedZoom) {
// initialRender = true;
// changedZoom = isZoomed;
// }
// X axis and scale ------------->>>>>>>>>>>>>>>>>>>>
const xScale = d3
.scaleLinear()
.domain(d3.extent(data.map((d) => d.value)))
.range([0, width]);
const xAxisCall = d3
.axisBottom(xScale)
.tickFormat(d3.format('.2s'))
.ticks(5)
.tickSizeOuter(0);
let xAxis = null;
if (initialRender) {
d3.select('.axis-x').remove();
xAxis = svg
.append('g')
.attr('class', 'axis-x')
.attr('transform', 'translate(0,' + 115 + ')');
initialRender = false;
} else {
xAxis = d3.select('.axis-x');
}
xAxis.transition().duration(2000).ease(d3.easeSinInOut).call(xAxisCall);
// X axis and scale <<<<<<<<<<<<<<<<-----------------------------
const binMin = 5;
const binMax = 150;
const tDuration = 3000;
// Just to calculate max elements in each bin ---------->>>>>>>>>>>>>>>>>>
let histogram = d3
.histogram()
.value((d) => d.value)
.domain(xScale.domain())
.thresholds(xScale.ticks(10));
let bins = histogram(data).filter((d) => d.length > 0);
//console.log(bins);
const max = d3.max(bins.map((bin) => bin.length));
const maxBinSize = max <= 10 ? 10 : max;
// Just to calculate max elements in each bin <<<<<<<<<<<<----------------
// Decide parameters for histogram ------------>>>>>>>>>>>>>>>>>
const dotSizeScale = d3
.scaleLinear()
.domain([binMin, binMax])
.range([10, 4]);
const dotSize = dotSizeScale(maxBinSize);
const dotSpacingScale = d3
.scaleLinear()
.domain([binMin, binMax])
.range([12, 6]);
const dotSpacing = dotSpacingScale(maxBinSize);
const thresholdScale = d3
.scaleLinear()
.domain([binMin, binMax])
.range([10, 100]);
const threshold = thresholdScale(maxBinSize);
const yTransformMarginScale = d3
.scaleLinear()
.domain([binMin, binMax])
.range([100, 100]);
const yTransformMargin = yTransformMarginScale(maxBinSize);
/*
if (dotSize !== 10) {
d3.selectAll('.gBin').remove()
d3.selectAll('rect').remove()
}
*/
histogram = d3
.histogram()
.value((d) => d.value)
.domain(xScale.domain())
.thresholds(xScale.ticks(threshold));
bins = histogram(data).filter((d) => d.length > 0);
// Decide parameters for histogram <<<<<<<<<<<<<<<<<<<<--------------------------
// Y axis scale -------------------->>>>>>>>>>>>>>>>>>>>
var yScale = d3.scaleLinear().range([height, 0]);
yScale.domain([0, d3.max(bins, (d) => d.length)]);
svg.append('g').attr('class', 'axis-y').call(d3.axisLeft(yScale));
d3.select('.axis-y').remove();
// Y axis scale <<<<<<<<<<<<<<<<<<<<<<<-----------------
const binGroup = svg.selectAll('.gBin').data(bins, (d) => {
//console.log('id 1', d.x0)
return d.x0;
});
binGroup.exit().transition().duration(2000).style('opacity', 0).remove();
const binGroupEnter = binGroup
.enter()
.append('g')
.merge(binGroup)
.attr('class', 'gBin')
.attr('x', 1)
.attr('transform', function (d) {
return 'translate(' + xScale(d.x0) + ',' + yTransformMargin + ')';
})
.attr('width', 10);
const elements = binGroupEnter.selectAll('rect').data(
(d) =>
d.map((p, i) => ({
id: p.id,
idx: i,
value: p.value,
})),
function (d) {
//console.log('id 2', d)
return d.id;
}
);
let eex = elements
.exit()
.transition()
.duration(tDuration)
.style('opacity', 0)
.remove();
console.log("rects exiting", eex.nodes().map(e => "rect" + e.getAttribute('id')))
let een = elements
.enter()
.append('rect')
.attr('id', (d) => d.value);
console.log("rects entering", een.nodes().map(e => "rect" + e.getAttribute('id')))
let eem = een
.merge(elements);
console.log("rects merge", eem.nodes().map(e => "rect" + e.getAttribute('id')))
eem
.attr('y', -(height + margin.top))
// .on("mouseover", tooltipOn)
// .on("mouseout", tooltipOff)
.transition()
.delay(function (d, i) {
return 50 * i;
})
.duration(tDuration)
.attr('y', (d, i) => -(i * dotSpacing))
.attr('width', dotSize)
.attr('height', dotSize)
// .style("fill", (d) => getBinColor(d.value, dataGradients))
.style('fill', 'red');
}
const data1 = [
{
id: 1,
value: 14,
},
{
id: 13,
value: 12,
},
{
id: 2,
value: 50,
},
{
id: 32,
value: 142,
},
];
const data2 = [
{
id: 1,
value: 135,
},
{
id: 7,
value: 2,
},
{
id: 2,
value: 50,
},
{
id: 32,
value: 50,
},
];
printChart(null, data1, null);
function changeData() {
selectedData1
? printChart(null, data2, null)
: printChart(null, data1, null);
selectedData1 = !selectedData1;
}
</script>
</html>