selectedCities.length>2?svg`${selectedCityPlot}`:md`╳ Not enough cities selected`
selectedCities.length>2?// NOTE - i've actually just inlined the plot since// it's using different data Plot.plot({marks: [ Plot.barY(selectedCities, {x:"city",y:"pop",fill:"#222222ee",ariaLabel: d => d.city+": "+ d.pop+" million people" }), Plot.tip(transpose(aus_pops), Plot.pointerX({x:"city",y:"pop",fill:"#333333",ariaHidden:true })), ],style: {fontSize:16 },marginBottom:45 }) :md`╳ Not enough cities selected`
…or to make responsive graphics
Try resizing this window!
md`Window width is ${width} pixels`
horizBarPlot = Plot.plot({marks: [ Plot.barY(transpose(aus_pops), {x:"city",y:"pop",fill:"#222222ee",ariaLabel: d => d.city+": "+ d.pop+" million people" }), Plot.tip(transpose(aus_pops), Plot.pointerX({x:"city",y:"pop",fill:"#bbbbbb",ariaHidden:true })), ],style: {fontSize:16 },marginBottom:45,height:275,width:1200})
vertBarPlot = Plot.plot({marks: [ Plot.barX(transpose(aus_pops), {x:"pop",y:"city",fill:"#222222ee",ariaLabel: d => d.city+": "+ d.pop+" million people" }), Plot.tip(transpose(aus_pops), Plot.pointerY({x:"pop",y:"city",fill:"#bbbbbb",ariaHidden:true })), ],style: {fontSize:32 },marginLeft:160,marginBottom:80,height:1000})
… but this chart is Svelte!
(with just a smidge of D3.js)
import { aq, op } from"@uwdata/arquero"fullCity = aq.loadCSV("time-series/"+ selectedVariable +"."+ selectedCity +".daily.csv")tidiedCity = fullCity.rename(aq.names("date","value")).filter(d => d.date!==null).params({ selectedSeason: selectedSeason }).derive({year: d => op.year(d.date),month: d => op.month(d.date) +1 })// filter unless "Whole year" is selectedfilteredCity = selectedSeason ==0? tidiedCity : tidiedCity.filter(d => d.month== selectedSeason)// now group by year and calculate the metricsallMetrics = filteredCity.groupby("year").rollup({min: d => op.min(d.value),mean: d => op.mean(d.value),max: d => op.max(d.value), })// finally, select the year and whichever metric column is chosen by the userfinalData = allMetrics.select("year", selectedMetric).rename(aq.names("year","value"))
Remember D3.js? We’ve used it before! Remember the scale functions?
D3 has lots of handy utilities, but it’s best known for tools that turn data into graphics:
d3.select("svg")// make circles for each data row.selectAll("circle").data(mydata).join("circle")// style them using data columns.attr("cx", d => d.income).attr("cy", d => d.life_expec).attr("r", d => d.population).attr("fill","blue")
D3 is lower level (ggplot2 users, think grid)
I failed to learn it for years!
D3’s “select” code is very imperative
As Connor Rothschild explains, you can use D3.js tools when it’s useful, but Svelte is often a better way to create graphics from data
What about D3.js?
The differences between D3 and Svelte are equivalent to the differences between instructions and authoring. In D3, we write instructions to tell JavaScript what to render; in Svelte, we write our output directly.