Published
Edited
Dec 5, 2019
1 fork
Insert cell
Insert cell
height = 500
Insert cell
// Randomize the dataset
dataset = generate1DRandomDataSet(20, 50, 500);
Insert cell
// Create SVG
// Code pulled from https://observablehq.com/@sistrall/interacting-with-svg-drawings
svg = {
// Create an SVG element: width is a variable
// made available from the Observable standard lib.
const node = DOM.svg(width, height)
// Wrap the SVG element in a d3 object:
// it's pretty common when using d3.
const svg = d3.select(node)
// Finally, the block returns the SVG element, which is made
// available via the d3 `node` function.
return svg.node();
}
Insert cell
// Get the ordinal scale to our dataset and space them out evenly 5% space in between each data point over the width of the svg
aScale = d3.scaleBand()
.domain(d3.range(dataset.length))
.rangeRound([0, width])
.paddingInner(0.05);
Insert cell
d3.select(svg).on("contextmenu", function (d, i) { // On right click event
d3.event.preventDefault(); // Prevent context menu from popping up
dataset.pop(); // Pop off the last element
// Update the bars on the new dataset
updateBars(dataset);
})
.on("click", function(data, index){ // onClick event
// Add new value into the dataset
var newNumber = Math.floor(Math.random() * 451) + 50
dataset.push(newNumber);
// Update the bars on the new dataset
updateBars(dataset);
})
Insert cell
// Load the bars for the first time
updateBars(dataset)
Insert cell
// Update bars/text
function updateBars(dataset){
// Update the domain of the scale to the new dataset length
aScale.domain(d3.range(dataset.length))
// Pair each rectangle to the dataset
var bars = d3.select(svg)
.selectAll("rect")
.data(dataset);

// On data that is not yet plotted as bars yet
bars.enter()
.append("rect")
.attr("x", function(data, index) {
return width * 2;
})
.attr("y", function(data, index) {
return height - data;
})
.attr("width", aScale.bandwidth())
.attr("height", function(data, index) {
return data * 4;
})
.attr("fill", function(data, index) {
return "rgb(0, 0, " + (data / 3) + ")";
})
.merge(bars) // Apply all changes to bars after this point
.transition()
.duration(500)
.attr("x", function(data, index) {
return aScale(index);
})
.attr("y", function(data, index) {
return height - data;
})
.attr("width", aScale.bandwidth())
.attr("height", function(data, index) {
return data * 4;
})
.attr("fill", function(data, index) {
return "rgb(0, 0, " + (data / 3) + ")";
})

// Remove any bars that no longer have their data in the dataset
bars.exit()
.transition()
.duration(500)
.attr("x", width * 2)
.remove();

// Store the new update for text
let texts = d3.select(svg)
.selectAll("text")
.data(dataset)

// Append new texts for new data
texts.enter()
.append("text")
.text(function(data, index){
return data;
})
.attr("x", function(data, index) {
return width * 2;
})
.attr("y", function(data, index) {
return height - data + 15;
})
.attr("font-family", "sans-serif")
.attr("font-size", "11px")
.attr("fill", "white")
.attr("text-anchor", "middle")
.merge(texts)
.transition()
.duration(500)
.text(function(data, index){
return data;
})
.attr("x", function(data, index) {
return aScale(index) + aScale.bandwidth() / 2;
})
.attr("y", function(data, index) {
return height - data + 15;
})

texts.exit()
.transition()
.duration(500)
.attr("x", width * 2)
.remove();
}
Insert cell
Insert cell
// Import D3 library
d3 = require("https://d3js.org/d3.v5.min.js")
Insert cell
/* Function generates 1D array of size dataSetSize with values between minValue and maxValue INCLUSIVELY*/
function generate1DRandomDataSet(dataSetSize, minValue, maxValue) {
var dataset = []; //Initialize empty array
for (var i = 0; i < dataSetSize; i++) {
var newNumber = Math.random() * (maxValue - minValue + 1) + minValue;
newNumber = Math.floor(newNumber) // Round to nearest integer value
dataset.push(newNumber); //Add new number to array
}
return dataset
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more