Published
Edited
Oct 19, 2020
Insert cell
md`# A simple bar chart with text. Every time you click, a bar and corresponding text are added.`
Insert cell
md`create the data`
Insert cell
mydata = [];
Insert cell
//create any data
{
for(var i = 0; i < 20; i++){
let randomNumber = Math.floor(Math.random()*25)
mydata.push(randomNumber)
}
return mydata
}
Insert cell
chart_height = 400
Insert cell
chart_width = 800
Insert cell
margin = 50
Insert cell
//create the scales
x_scale = d3.scaleBand()
.domain(d3.range(mydata.length))
.rangeRound([margin, chart_width])
.paddingInner(0.05)
Insert cell
y_scale = d3.scaleLinear()
.domain([0, d3.max(mydata, function(d){
return d
})])
.rangeRound([margin, chart_height])
Insert cell
//create the svg

svg = d3.create('svg')
//.append('svg')
.attr('height', chart_height)
.attr('width', chart_width)

Insert cell
d3.select('#theButton').on('click', function(){
//var mydata = [];
//create new data
/*for(var i = 0; i < 20; i++){
let randomNumber = Math.floor(Math.random()*25)
mydata.push(randomNumber)
}*/
let randomNumber = Math.floor(Math.random()*25)
mydata.push(randomNumber)
console.log(mydata)
//update the scales
x_scale.domain(d3.range(mydata.length))
y_scale.domain([0, d3.max(mydata, function(d){
return d
})])
//update the rects
var bars = svg.selectAll('rect')
.data(mydata)
bars.enter()
//create the extra rect(s)
.append('rect')
.attr('x', chart_width - x_scale.bandwidth()) //it's at the very end of the chart
.attr('y', function(d){
return chart_height - y_scale(d)
})
.attr('width', x_scale.bandwidth())
.attr('height', function(d){
return y_scale(d) - y_scale(0)
})
.attr('fill', 'red')
//merge old with new rects
.merge(bars)
.transition()
.duration(1000)
.delay(function(d, i){
return i/mydata.length * 1000
})
.ease(d3.easeElasticOut)
.attr('x', function(d, i){
return x_scale(i)
})
.attr('y', function(d){
return chart_height - y_scale(d)
})
.attr('width', x_scale.bandwidth())
.attr('height', function(d){
return y_scale(d) - y_scale(0)
})
.attr('fill', 'red')
var myTexts = svg.selectAll('text')
.data(mydata)
myTexts.enter()
.append('text')
.text(function(d){
return d
})
.attr('x', chart_width - x_scale.bandwidth())
.attr('y', function(d){
if(d<3){
return chart_height - y_scale(d)
} else {
return chart_height - y_scale(d)+15
}
//return chart_height - y_scale(d)+15
})
.attr('fill', 'black')
.attr('text-anchor', 'middle')
.merge(myTexts)
.transition()
.duration(1000)
.delay(function(d, i){
return i/mydata.length * 1000
})
.attr('x', function(d, i){
return x_scale(i) + x_scale.bandwidth()/2
})
.attr('y', function(d){
if(d<3){
return chart_height - y_scale(d)
} else {
return chart_height - y_scale(d)+15
}
//return chart_height - y_scale(d)+15
})
.attr('fill', 'black')
.attr('text-anchor', 'middle')
return svg.node()
})
Insert cell
//create the text
{
svg.selectAll('text')
.data(mydata)
.enter()
.append('text')
.text(function(d){
return d
})
.attr('x', function(d, i){
return x_scale(i) + x_scale.bandwidth()/2
})
.attr('y', function(d){
if(d<3){
return chart_height - y_scale(d)
} else {
return chart_height - y_scale(d)+15
}
})
.attr('fill', 'black')
.attr('text-anchor', 'middle')
return svg.node()
}
Insert cell
html`<button type="button" id="theButton">Click me</button>`
Insert cell
//create the rects
{
svg.selectAll('rect')
.data(mydata)
.enter()
.append('rect')
.attr('x', function(d, i){
return x_scale(i)
})
.attr('y', function(d){
return chart_height - y_scale(d)
})
.attr('width', x_scale.bandwidth())
.attr('height', function(d){
return y_scale(d) - y_scale(0)
})
.attr('fill', 'red')
return svg.node()
}
Insert cell
y_scale(2)
Insert cell
d3 = require("d3")
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