Published
Edited
Sep 10, 2020
1 fork
1 star
Insert cell
md`# SVG Waffle Charts

The goal is to create a little waffle chart for each chapter, where each type is represented by an SVG. I think the way to do this will to create a 'g' of svgs for each chapter, then combine those gs into a single svg with one axis?`
Insert cell
data = [
{
chapter: 1,
type: ["diamond", "circle", "square", "square", "circle", "diamond", "circle", "circle"]
},
{
chapter: 2,
type: ["square", "circle", "square", "circle", "square", "circle", "circle",
"diamond", "circle", "diamond", "square", "circle", "square"]
},
{
chapter: 3,
type: ["diamond", "circle", "square", "diamond", "diamond", "circle", "diamond", "diamond", "diamond", "circle", "diamond", "diamond", "square", "diamond", "diamond", "diamond"]
},
{
chapter: 4,
type: ["diamond", "circle", "square", "diamond", "diamond", "circle", "diamond", "diamond", "diamond", "circle", "diamond", "circle", "square", "diamond"]
}
]
Insert cell
md `# Get the three SVGs`
Insert cell
svgSize = 50
Insert cell
html `<svg width="${svgSize}" height="${svgSize}"><path transform="translate(25,50)" d="${diamondSVG}"></svg>`
Insert cell
diamondSVG = "M0,0 C-1,-15 -25,-30 -10,-50 C-10,-40 10,-40 10,-50 C25,-30 1,-15 0,0"
Insert cell
html `<svg width="${svgSize}" height="${svgSize}"><path transform="translate(25,50)" d="${circleSVG}"></svg>`
Insert cell
circleSVG = "M 0,0 C -10,-20 -20,-30 0,-50 C 20,-30 10,-20 0,0"
Insert cell
html `<svg width="${svgSize}" height="${svgSize}"><path transform="translate(25,50)" d="${squareSVG}"></svg>`
Insert cell
squareSVG = "M 0,0 C -10,-10 -30,-50 0,-50 C 30,-50 10,-10 0,0"
Insert cell
md `## Add the SVGs to our data`
Insert cell
function svgFunc(x) {
if (x === "diamond") return diamondSVG
else if (x === "circle") return circleSVG
return squareSVG
}
Insert cell
md `I was thinking we'd want to group the data into their chapters... Maybe? I try another approach lower`
Insert cell
segment = {
let segments = []
let i;
for (i = 0; i < (chartWidth/waffleWidth); i++) {
segments.push([i*waffleWidth, (i+1)*waffleWidth])
}
return segments
}
Insert cell
histoData = _.map(data, d => {
const path = d.type.map(x => svgFunc(x));
const chapter = d.chapter
const type = d.type
return {
chapter,
shape: _.times(type.length, i => {
return {
type: type[i],
path: path[i]
}
})
}
})
Insert cell
md `Note we have the right number of svgs inside each g! Nothing is plotting but that's still cool!`
Insert cell
md `## Plot Universe`
Insert cell
chartHeight = 300
Insert cell
chartWidth = 900
Insert cell
waffleWidth = chartWidth / data.length
Insert cell
cleanData = {
for (var i = 0; i < histoData.length; i++) {
histoData[i].segment = segment[i]
}
return histoData
}
Insert cell
{
const svg = DOM.svg(chartWidth, chartHeight)

// create a g for every chapter
// use the segment array for the start and end of the g
const chapter = d3.select(svg)
.selectAll('g')
.data(cleanData)
.enter()
.append('g')
// this is clearly wrong
.attr('transform', (d, i) => `translate(${d.segment[0]})`)

// then this code should space out each patch within its g
chapter.selectAll('path')
.data(d => d.shape)
.enter()
.append('path')
.attr('transform', (d, i) => `translate(${(i % 4) * svgSize + 30}, ${Math.floor(i / 4) * svgSize + 70 })`)
.attr('d', d => d.path)
.attr('fill', d => colorScale(d.type))
const axis = d3.select(svg)
.append("g")
.style("color", "black")
.call(xAxis)

return svg;

}
Insert cell
xAxis = g => g
.attr("transform", `translate(0, ${chartHeight - 50})`)
.style("font-size", "1.4em")
.call(d3.axisBottom(xScale)
.tickValues(xAxisTicks)
.tickFormat(d3.format('d')))
Insert cell
xScale = d3.scaleLinear()
.domain(d3.extent(data, d => d.chapter))
.range([20, chartWidth - 30])
Insert cell
xAxisTicks = xScale.ticks()
.filter(tick => Number.isInteger(tick));
Insert cell
colorScale = d3.scaleOrdinal()
.domain(d3.extent(data, d => d.type))
.range(["#00AED5", "#F29904", "#017101"]);
Insert cell
d3 = require('d3')
Insert cell
_ = require('lodash')
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