Published
Edited
Jun 4, 2019
1 fork
Insert cell
md`# AAO Test`
Insert cell
chart = {
const svg = d3.select(DOM.svg(width, height));
svg.append("g").call(xAxis)
for (let i = 0; i < yAxes.length; i++) {
svg.append("g")
.call(yAxes[i])
.selectAll(".tick:not(:first-of-type) line")
.attr("opacity", "0")
}
for (let i = 0; i < levels.length; i++) {
svg.append("text")
.attr("x", width/2)
.attr("y", yRanges[i] + 20)
.text(levels[i])
}
let circles = svg.append("g")
.attr("fill", "steelblue")
.selectAll("circle")
.data(coords)
.join("circle")
.attr("cx", d => x(d.x))
.attr("cy", 5)
.attr("r", 4)
let i = 0
d3.interval(function() {
drop_group(circles, i)
i++
}, 2500)
return svg.node();
}
Insert cell
function drop_group(selection, i) {
selection.filter(d => d.level === levels[i])
.transition()
.ease(d3.easeLinear)
.delay(d => d.y * 100)
.duration(300)
.attr('cy', d => yDomains[i](d.y * 0.5))
.transition()
//.delay(d => d.y * 10)
.duration(5500)
.attr('fill', colors[i])
}
Insert cell
yBuffer = 10
Insert cell
colors = ['firebrick', 'orange', 'forestgreen']
Insert cell
margin = ({top: 50, right: 20, bottom: 100, left: 40})
Insert cell
d3 = require("d3@5")
Insert cell
function getX(arr) {
let al = arr.length
return Array(al).fill((arr.x0 + arr.x1) /2)
}
Insert cell
function getY(arr) {
return Array.from({length: arr.length}, (x, i) => i)
}
Insert cell
data = d3.csv("https://gist.githubusercontent.com/daranzolin/577daf0a9773999734e904b60902b237/raw/11ee8ce892c3d253706df8cc016ea5feb34a3bab/test_hist_rain2.csv", d => {
d.vals = +d.vals
d.Applied = d.level1 === "TRUE" ? true : false
d.Admitted = d.level2 == "TRUE" ? true : false
d.Enrolled = d.level3 == "TRUE" ? true : false
delete d.level1
delete d.level2
delete d.level3
return d
})
Insert cell
data.id = Array.from({length: 100},(x, i) => i)
Insert cell
levels = {
let x = Object.keys(data[0])
return x.slice(1, x.length)
}
Insert cell
height = 500
Insert cell
width = 500
Insert cell
x = d3.scaleLinear()
.domain(d3.extent(data, d => +d.vals)).nice()
.range([margin.left, width - margin.right])
Insert cell
xAxis = g => g
.attr("transform", `translate(0, ${height - (margin.bottom /2)})`)
.call(d3.axisBottom(x)
.tickPadding(15)
.tickValues([d3.min(coords, d => +d.x), d3.mean(coords, d => +d.x), d3.max(coords, d => +d.x)])
//.tickValues(d3.extent(coords, d => d.x))
.tickSize(0))
//.call(g => g.select(".domain").remove());
Insert cell
nLevels = levels.length
Insert cell
partition_heights = (height - margin.bottom) / nLevels
Insert cell
yBins = {
let bins_arr = []
for (let i = 0; i < levels.length; i++) {
let col = levels[i]
let colData = data.filter(d => d[col]).map(d => d.vals)
let b = d3.histogram()
.domain(x.domain())
.thresholds(x.ticks(20))
(colData)
bins_arr.push(b.map(d => d.sort()))
}
return bins_arr
}
Insert cell
yDomains = {
let domains_arr = []
for (let i = 0; i < levels.length; i++) {
let rb = partition_heights * (i + 1)
let rt = i === 0 ? yBuffer : (partition_heights * i) - yBuffer
let dom = d3.scaleLinear()
.domain([0, d3.max(yBins[0], d => d.length)]).nice()
.range([rb, rt])
domains_arr.push(dom)
}
return domains_arr
}
Insert cell
yAxes = {
let yaxes = []
for (let i = 0; i < yDomains.length; i++) {
let yax = g => g
.attr("transform", `translate(${margin.left},0)`)
.call(d3.axisLeft(yDomains[i]).ticks(1))
.call(g => g.selectAll(".tick line").clone()
.attr("stroke-opacity", 0.3)
.attr("x2", width - margin.right))
.attr('transform', `translate(0, 5)`)
.call(g => g.select(".domain").remove())
yaxes.push(yax)
}
return yaxes
}
Insert cell
coords = {
let yArr = []
let xArr = []
let lArr = []
for (let i = 0; i < levels.length; i++) {
let y_scale_inds = yBins[i].map(d => getY(d)).flat()
let x_scale_vals = yBins[i].map(d => getX(d)).flat()
let l_vals = Array(y_scale_inds.length).fill(levels[i])
yArr.push(y_scale_inds)
xArr.push(x_scale_vals)
lArr.push(l_vals)
yArr = yArr.flat()
xArr = xArr.flat()
lArr = lArr.flat()
}
let arrObj = []
for (let i = 0; i < yArr.length; i++) {
let obj = {}
obj.x = xArr[i]
obj.y = yArr[i]
obj.level = lArr[i]
arrObj.push(obj)
}
return arrObj
}
Insert cell
yRanges = yDomains.map(d => d.range()).map(d => d[0])
Insert cell
y = d3.scaleBand()
.domain(levels)
.range(d3.extent(yRanges))
Insert cell
yAxis = g => g
.attr("transform", `translate(${margin.left},0)`)
.call(d3.axisLeft(y))
.call(g => g.selectAll(".tick line").clone()
.attr("stroke-opacity", 0.2)
.attr("x2", width - margin.right))
.attr('transform', `translate(0, 0)`)
.call(g => g.select(".domain").remove())
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more