Public
Edited
May 4, 2023
1 fork
34 stars
Insert cell
Insert cell
Insert cell
Sparks.bar([0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100])
Insert cell
Sparks.dotline([0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100])
Insert cell
Sparks.dot([0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100])
Insert cell
Insert cell
${Sparks.dot([0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100], { weight: 1 })}<br />
${Sparks.dot([0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100], { weight: 2 })}<br />
${Sparks.dot([0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100], { weight: 3 })}<br />
${Sparks.dot([0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100], { weight: 4 })}<br />
${Sparks.dot([0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100], { weight: 5 })}<br />
Insert cell
${Sparks.dotline([0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100], { weight: 1 })}<br />
${Sparks.dotline([0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100], { weight: 2 })}<br />
${Sparks.dotline([0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100], { weight: 3 })}<br />
${Sparks.dotline([0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100], { weight: 4 })}<br />
${Sparks.dotline([0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100], { weight: 5 })}<br />
Insert cell
${Sparks.bar([0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100], { weight: 1 })}<br />
${Sparks.bar([0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100], { weight: 2 })}<br />
${Sparks.bar([0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100], { weight: 3 })}<br />
${Sparks.bar([0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100], { weight: 4 })}<br />
${Sparks.bar([0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100], { weight: 5 })}<br />
Insert cell
Insert cell
Insert cell
Sparks.bar([4, 5, 6], { weight: 5 })
Insert cell
Insert cell
Sparks.bar([4, 5, 6], { weight: 5, domain: [0, 10] })
Insert cell
Insert cell
Sparks.bar([10, 11, 12], { weight: 5, domain: [0, 10] })
Insert cell
Sparks.bar([-3, -2, -1], { weight: 5, domain: [0, 10] })
Insert cell
Insert cell
fontFamily = Sparks.getFamily("bar", { weight: 3 })
Insert cell
Insert cell
Sparks.slug(laGuardiaTemperatures, { domain: [8, 13] })
Insert cell
Insert cell
Insert cell
airportTemperatures = Plot.plot({
caption: "Temperature at airports on 2021-12-31, 10am-11pm",
projection: {
type: "mercator",
domain: {
type: "MultiPoint",
coordinates: [
[-74.6, 40.6],
[-74.6, 41.1],
[-73.3, 40.6],
[-73.3, 41.1]
]
}
},
marks: [
Plot.geo(countiesMesh, { strokeOpacity: 0.15 }),
Plot.geo(statesMesh, { strokeOpacity: 0.5 }),
Plot.geo(nation, {
strokeWidth: 1.5
}),
Plot.text(airportWeather, {
x: "longitude",
y: "latitude",
fontSize: 14,
fontFamily: Sparks.getFamily("bar", { weight: 3 }),
text: (d) =>
d.name +
"\n" +
Sparks.slug(
d.observations.map((o) => o.air_temp),
{ domain: [6, 11] }
)
})
]
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
${Sparks.redlabel`GOOG`} ${Sparks.dotline(googMonth)}
Insert cell
${Sparks.blacklabel`AMZN`} ${Sparks.dotline(amznMonth)}
Insert cell
Insert cell
<span class="sparks bar-narrow">0{0,10,20,30,40,50,60,70,80,90,100}100</span><br />
<span class="sparks bar-medium">0{0,10,20,30,40,50,60,70,80,90,100}100</span><br />
<span class="sparks bar-wide">0{0,10,20,30,40,50,60,70,80,90,100}100</span><br />
<span class="sparks bar-extrawide">0{0,10,20,30,40,50,60,70,80,90,100}100</span><br />

<span class="sparks dot-extrasmall">0{0,10,20,30,40,50,60,70,80,90,100}100</span><br />
<span class="sparks dot-small">0{0,10,20,30,40,50,60,70,80,90,100}100</span><br />
<span class="sparks dot-medium">0{0,10,20,30,40,50,60,70,80,90,100}100</span><br />
<span class="sparks dot-large">0{0,10,20,30,40,50,60,70,80,90,100}100</span><br />
<span class="sparks dot-extralarge">0{0,10,20,30,40,50,60,70,80,90,100}100</span><br />

<span class="sparks dotline-extrathin">0{0,10,20,30,40,50,60,70,80,90,100}100</span><br />
<span class="sparks dotline-thin">0{0,10,20,30,40,50,60,70,80,90,100}100</span><br />
<span class="sparks dotline-medium">0{0,10,20,30,40,50,60,70,80,90,100}100</span><br />
<span class="sparks dotline-thick">0{0,10,20,30,40,50,60,70,80,90,100}100</span><br />
<span class="sparks dotline-extrathick">0{0,10,20,30,40,50,60,70,80,90,100}100</span><br />
Insert cell
Insert cell
thickDotline = Sparks.getClass("dotline", { weight: 4 })
Insert cell
<span class=${thickDotline}>0{0,10,20,30,40,50,60,70,80,90,100}100</span>
Insert cell
Insert cell
Insert cell
Insert cell
class Sparks {
static bar(data, { weight, domain } = {}) {
const c = Sparks.getClass("bar", { weight });
const s = Sparks.slug(data, { domain });
return htl.html`<span class="${c}">${s}</span>`;
}

static dot(data, { weight = 3, domain } = {}) {
const c = Sparks.getClass("dot", { weight });
const s = Sparks.slug(data, { domain });
return htl.html`<span class="${c}">${s}</span>`;
}

static dotline(data, { weight = 3, domain } = {}) {
const c = Sparks.getClass("dotline", { weight });
const s = Sparks.slug(data, { domain });
return htl.html`<span class="${c}">${s}</span>`;
}

static slug(data, { domain } = {}) {
const first = _.first(data);
const ns = translate(data, { domain }).join(",");
const last = _.last(data);

return `${first}{${ns}}${last}`;
}

static getFamily(variation, { weight = 3 } = {}) {
return FAMILY_BY_VARIATION_BY_WEIGHT[variation][weight];
}

static getClass(variation, { weight = 3 } = {}) {
return (
`sparks ${variation}-` + STYLE_BY_VARIATION_BY_WEIGHT[variation][weight]
);
}

static redlabel(string) {
return htl.html`<span class="sparks bar-medium" style="color: #F00">${string}</span>`;
}

static blacklabel(string) {
return htl.html`<span class="sparks bar-medium">${string}</span>`;
}
}
Insert cell
Insert cell
<link href="https://tools.aftertheflood.com/sparks/styles/font-faces.css" rel="stylesheet" />
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// should expand values around 50 to fill [0, 100]
translate([30, 40, 50, 60, 70])
Insert cell
// should halve all values
translate([30, 40, 50, 60, 70], { domain: [0, 200] })
Insert cell
// should clamp first and last values
translate([30, 40, 50, 60, 70], { domain: [40, 60] })
Insert cell
Insert cell
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