Published
Edited
May 14, 2021
3 stars
Insert cell
Insert cell
Plot.plot({
marks: [
Plot.line(dataB_long, {x: 'month', y: 'value'})
],
facet: {
data: dataB_long,
y: 'term',
marginRight: 100
},
width: 900,
height: 2000
})
Insert cell
Plot.plot({
width: 900,
height: 400,
marks: [
Plot.line(dataB_long_forLines.filter(d => d.term == 'Mental illness'),
{x: 'month', y: 'value', z: 'year', curve: 'catmull-rom-open'})
],
})
Insert cell
beeswarm = {
const height = 300;
const width = 1000;
const data = dataA_long
const svg = d3.create("svg")
.attr("height", height)
.attr("width", width)
const max_val = d3.max(data, d => d.value)
const xScale = d3.scaleTime().domain(d3.extent(data, d => d.month)).range([0, width]).clamp(true)
const rScale = d3.scaleSqrt().domain([0, max_val]).range([0, 12])
const force = d3.forceSimulation(data)
.force('forceX', d3.forceX(d => xScale(d.month)).strength(1))
.force('forceY', d3.forceY(height/2).strength(0.1))
.force('collide', d3.forceCollide(d => rScale(d.value) + 0.75))
.stop();
const iterations = 100;
for (let i = 0; i < iterations; ++i) {
force.tick();
};
force.stop();
svg.selectAll("circle")
.data(data)
.join('circle')
.attr("cx", d => d.x)
.attr("cy", d => d.y)
.attr("r", d => rScale(d.value))
.style("fill", d => colorScale(d.category));
svg.selectAll('circle')
.on("mouseover", function(e,d) {
tooltip
.html(`<b>Term</b>: ${d.term}`);
let tooltipWidth = tooltip.node().offsetWidth;
let tooltipHeight = tooltip.node().offsetHeight;
tooltip
.style("left", e.pageX - tooltipWidth/2 +'px')
.style("top", e.pageY-tooltipHeight - 10+'px')
.style('visibility', 'visible');
})
.on("mousemove", function(e,d) {
let tooltipWidth = tooltip.node().offsetWidth;
let tooltipHeight = tooltip.node().offsetHeight;
tooltip
.style("left", e.pageX - tooltipWidth/2 +'px')
.style("top", e.pageY-tooltipHeight - 10+'px')
.style('visibility', 'visible');
})
.on("mouseout", function(e,d) {
tooltip
.style('visibility', 'hidden');
});
svg.append("g")
.call(d3.axisTop(xScale))
.style("transform", `translateY(${height*0.75}px`)
return svg.node();
}
Insert cell
radial = {
const svg = d3.create('svg')
.attr('viewBox', [-width/2, -height/2, width, height])
const filteredData = dataB_long_forLines.filter(d => d.term == 'Addiction').sort((a, b) => a.date - b.date)
console.log(filteredData)
const data = d3.groups(filteredData, d => d.term)
svg.append('path')
.attr('fill', 'none')
.attr('stroke', 'steelblue')
.attr('stroke-width', 1.5)
.attr('d', radialLine(filteredData));
// console.log(radialLine(filteredData));
svg.append("g")
.call(xAxis);
svg.append('g')
.call(yAxis);

return svg.node();
}
Insert cell
xAxis = g => g
.attr("font-family", "sans-serif")
.attr("font-size", 10)
.call(g => g.selectAll("g")
.data(xScale.ticks())
.join("g")
// .each((d, i) => { console.log(d); return d.id = new Date(d.month);} )
.call(g => g.append("path")
.attr("stroke", "#000")
.attr("stroke-opacity", 0.2)
.attr("d", d => `
M${d3.pointRadial(xScale(d), innerRadius)}
L${d3.pointRadial(xScale(d), outerRadius)}
`))
.call(g => g.append("path")
// .attr("id", d => d.id.id)
.datum(d => [d, d3.utcMonth.offset(d, 1)])
.attr("fill", "none")
.attr("d", ([a, b]) => `
M${d3.pointRadial(xScale(a), innerRadius)}
A${innerRadius},${innerRadius} 0,0,1 ${d3.pointRadial(xScale(b), innerRadius)}
`))
.call(g => g.append("text")
.append("textPath")
.attr("startOffset", 6)
// .attr("xlink:href", d => d.id.href)
.text(d3.utcFormat("%B"))))
Insert cell
yAxis = g => g
.attr("text-anchor", "middle")
.attr("font-family", "sans-serif")
.attr("font-size", 10)
.call(g => g.selectAll("g")
.data(yScale.ticks().reverse())
.join("g")
.attr("fill", "none")
.call(g => g.append("circle")
.attr("stroke", "#000")
.attr("stroke-opacity", 0.2)
.attr("r", yScale))
.call(g => g.append("text")
.attr("y", d => -yScale(d))
.attr("dy", "0.35em")
.attr("stroke", "#fff")
.attr("stroke-width", 5)
.text(x => `${x.toFixed(0)}`)
.clone(true)
.attr("y", d => yScale(d))
.selectAll(function() { return [this, this.previousSibling]; })
.clone(true)
.attr("fill", "currentColor")
.attr("stroke", "none")))
Insert cell
width = 900
Insert cell
height = 900
Insert cell
innerRadius = width / 5
Insert cell
outerRadius = width / 2 - margin
Insert cell
margin = 10
Insert cell
radialLine = d3.lineRadial()
// .defined(d => !isNaN(d))
.radius(d => radiusScale(d.value))
.angle(d => xScale(d.month))
.curve(d3.curveCatmullRom)
Insert cell
radiusScale = d3.scaleLinear()
.domain([0, d3.max(dataB_long_forLines, d => d.value)])
.range([innerRadius, outerRadius])
Insert cell
xScale = d3.scaleLinear()
.domain([0, d3.max(dataB_long_forLines, d => d.month + 1)])
.range([0, 2 * Math.PI])
Insert cell
xScale(dataB_long_forLines[0])
Insert cell
yScale = d3.scaleLinear()
.domain(d3.extent(dataB_long_forLines, d => d.value))
.range([innerRadius, outerRadius])
Insert cell
tooltip = d3.select('body')
.append('div')
.attr('id', 'barchart-tooltip')
.style('position', 'absolute')
.style('z-index', '1')
.style('visibility', 'hidden')
.style('padding', '10px')
.style('background', 'rgba(0,0,0,0.6)')
.style('border-radius', '4px')
.style('color', '#fff');
Insert cell
colorScale = d3.scaleOrdinal().domain(unique_cats).range(colors)
Insert cell
colors = ['#ec4977', '#ff9063', '#ffd577', '#baf29d', '#00dcd5', '#0cb4f5']
Insert cell
Insert cell
cats = terms.map(d => d.category)
Insert cell
unique_cats = [...new Set(cats)]
Insert cell
terms = FileAttachment("terms_categorization.csv").csv()
Insert cell
function catFinder(term) {
var category
terms.filter(d => {
if (term == d.term) {
category = d.category
}
})
return category
}
Insert cell
dataB_long_forLines = dataB_long.map(d => {
return {
month: d.month.getMonth(),
year: d.month.getFullYear(),
date: d.month,
term: d.term,
category: d.category,
value: d.value
}
})
Insert cell
dataA_long = {
dataA_long_raw.forEach(date => date.month = new Date(date.month))
dataA_long_raw.forEach(date => date.monthNum = Number(date.month))
dataA_long_raw.forEach(value => value.value = +value.value)
dataA_long_raw.forEach(item => item.category = catFinder(item.term))
return dataA_long_raw
}
Insert cell
dataB_long = {
dataB_long_raw.forEach(date => date.month = new Date(date.month))
dataB_long_raw.forEach(date => date.monthNum = Number(date.month))
dataB_long_raw.forEach(value => value.value = +value.value)
dataB_long_raw.forEach(item => item.category = catFinder(item.term))
return dataB_long_raw
}
Insert cell
dataA_long_raw = FileAttachment("indexA_long.csv").csv()
Insert cell
dataB_long_raw = FileAttachment("indexB_long.csv").csv()
Insert cell
dataA = {
indexA.forEach( date => date.month = new Date(date.month) )
return indexA
}
Insert cell
dataB = {
indexB.forEach( date => date.month = new Date(date.month) )
return indexB
}
Insert cell
indexA = FileAttachment("help_trends_indexA.csv").csv({typed:true})
Insert cell
indexB = FileAttachment("help_trends_indexB@2.csv").csv({typed:true})
Insert cell
Plot = require("@observablehq/plot@0.1")
Insert cell
d3 = require('d3@6')
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