Published
Edited
Nov 3, 2021
Insert cell
Insert cell
// priorities need to be mapped
mySvg = generateChart("priority", prioritiesMapped, dataByPriority)
Insert cell
scaleX('carla')
Insert cell
scaleX = d3.scaleBand()
.domain(prioritiesMapped.map(p => p.name).reverse())
.range([1, width])
.padding(0.1)
Insert cell
// statuses do not need to be mapped
svg2 = generateChart("status", statuses, dataByStatus)
Insert cell
function generateChart(propertyType, mappedPropertyList, dataByProperty){
// max todos in list
const maxTodoQty = d3.max(dataByProperty.map(t => t[1].length))
// create svg
let svg = d3.create('svg')
.attr('width', width + margin.right)
.attr('height', height + margin.bottom)

// scaleX
const scaleX = d3.scaleBand()
.domain(mappedPropertyList.map(p => p.name).reverse())
.range([1, width])
.padding(0.1)
// append scaleX to svg
svg.append('g')
.call(d3.axisBottom(scaleX).tickSizeOuter(0))
.attr('transform', `translate(${margin.left}, ${height + margin.top})`)

// scaleY
const scaleY = d3.scaleLinear()
.domain([maxTodoQty, 0])
.range([ 0, height])
.nice()
// append scaleY to svg
svg.append('g')
.call(d3.axisLeft(scaleY).ticks(maxTodoQty).tickFormat(d3.format("d")))
.attr('transform', `translate(${margin.left}, ${margin.top})`);

// create RectGroup
const rectGroup = svg.append('g')
.attr('transform', `translate(${margin.left}, ${margin.top})`)
// append Rect for each obj in data
const allRect = rectGroup.selectAll('rect')
.data(dataByProperty)
.enter()
.append('rect')
.attr('height', d => height - scaleY(d[1].length))
.attr('width', scaleX.bandwidth())
.attr('x', d => {
const property = mappedPropertyList.find(p => p[`${propertyType}TypeId`] == d[0])
return scaleX(property.name)
})
.attr('y', d => scaleY(d[1].length))
.attr('fill', (d) => {
return colors[d[1][0].priorityTypeId]
})

// create text group
const todoQty = svg.append("g")
.attr('transform', `translate(${margin.left}, ${margin.top})`)
.attr("font-family", "sans-serif")
.attr("font-size", 14)
.attr("font-weight", "bold")

// append text to each rectangle
todoQty
.selectAll("text")
.data(dataByProperty)
.join("text")
.attr('x', d => {
const property = mappedPropertyList.find(p => p[`${propertyType}TypeId`] == d[0])
return scaleX(property.name) + scaleX.bandwidth()/2 - 3
})
.attr('y', d => {
const distanceFromTop = scaleY(d[1].length)
const rectHeight = height - distanceFromTop
return height - (rectHeight / 2)
})
.text(d => d[1].length)
.style('fill', 'black')
return svg.node()
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
lowMediumHigh = ['#C38CAB', '#FF639C', '#CB1658'];
Insert cell
priorityColorsScale = d3.scaleOrdinal(lowMediumHigh);
Insert cell
priorityColorsScale(3)
Insert cell
colors = {
const obj = {}
obj[1] = '#C38CAB'
obj[2] = '#FF639C'
obj[3] = '#CB1658'

return obj
}
Insert cell
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