Public
Edited
Aug 13, 2023
Insert cell
Insert cell
// Import the function and arquero operations into your notebook
import {Wrangler, op} from "@observablehq/data-wrangler"


Insert cell
// Create an interface to wrangle your data
Wrangler(pizzaorders_names_size)
Insert cell
// To use copied code replace "data" with your own variable
aq.from(data)
.groupby('orderDate','pizza_name')
// .objects() // Uncomment to return an array of objects
Insert cell
Insert cell
Insert cell
pizzaorders_names_size
X
pizza_name
Y
Color
pizza_size
Size
Facet X
Facet Y
Mark
Auto
Type Chart, then Shift-Enter. Ctrl-space for more options.

Insert cell
Plot.auto(pizzaorders_names_size, {
x: "pizza_name",
color: "pizza_size"
}).plot({ color: { legend: true } })
Insert cell
Insert cell
pizzaorders_names_size
X
orderDate
Y
total
Color
category
Size
Facet X
Facet Y
pizza_size
Mark
rule
Type Chart, then Shift-Enter. Ctrl-space for more options.

Insert cell
Plot.auto(pizzaorders_names_size, {
x: "orderDate",
y: "total",
color: "category",
fy: "pizza_size",
mark: "rule"
}).plot({ color: { legend: true } })
Insert cell
Plot.plot({
marks: [
Plot.rectY(pizzaorders_names_size, Plot.binX({y: "count"}, {x: "orderDate"})),
Plot.ruleY([0])
],
color: "category",
width
})
Insert cell
Insert cell
Plot.plot({
marks: [
Plot.ruleY([0]),
Plot.lineY(pizzaorders_selectedState, Plot.groupX({y: "sum"}, {x: "orderDate", y: "total", z: "category", stroke: "category", title: "category"}))
],
color : {
legend: true
},
y: {domain: [0,50000]} // I would prefer this be a function like max of CA or NV so that it was dynamic
})
Insert cell
Plot.plot({
marks: [
Plot.barY(pizzaorders_names_size, Plot.groupX({y: "count"}, {x: "day_of_week", fill: "pizza_size", title: "sport",
sort: {x: "y", reverse: true, limit: 10}})),
],
color: {
legend: true
}
})
Insert cell
Plot.plot({
y: {
tickFormat: "s"
},
marks: [
Plot.areaY(pizzaorders_names_size, {x: "orderDate",
offset: "silhouette",
y: "total", fill: "category"}),
Plot.ruleY([0])
]
})
Insert cell
pizzaorders_names_size
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
Insert cell
Insert cell
pizzaorders_names_size
X
pizza_size
Y
Color
category
Size
total
Facet X
Facet Y
Mark
Auto
Type Chart, then Shift-Enter. Ctrl-space for more options.

Insert cell
Plot.auto(pizzaorders_names_size, {
x: "pizza_size",
color: { value: "category", reduce: null },
size: "total"
}).plot({ color: { legend: true } })
Insert cell
pizzaorders_names_size
X
orders
Y
Color
category
Size
Facet X
Facet Y
pizza_size
Mark
Auto
Type Chart, then Shift-Enter. Ctrl-space for more options.

Insert cell
Plot.auto(pizzaorders_names_size, {
x: "orders",
color: "category",
fy: "pizza_size"
}).plot({ color: { legend: true } })
Insert cell
Insert cell
Plot.plot({
projection: "albers-usa",
width,
marks: [
Plot.geo(nation),
Plot.geo(states, { strokeOpacity: 0.25 })
],
})
Insert cell
nation = topojson.feature(us, us.objects.nation)
Insert cell
states = topojson.feature(us, us.objects.states)
Insert cell
airports = "https://cdn.jsdelivr.net/npm/vega-datasets@1.31.1/data/airports.csv"
Insert cell
usa = nation
Insert cell
flights = "https://cdn.jsdelivr.net/npm/vega-datasets@1.31.1/data/flights-airport.csv"
Insert cell
{
const map = vl.markGeoshape({fill: '#ddd', stroke: '#fff', strokeWidth: 1})
.data(vl.topojson(usa).feature('states'));

const points = vl.markCircle()
.data(flights)
.transform(
vl.groupby('origin').aggregate(vl.count().as('routes')),
vl.lookup('origin').from(
vl.data(airports).key('iata').fields('state', 'latitude', 'longitude')
),
vl.filter('datum.state !== "PR" && datum.state !== "VI"')
)
.encode(
vl.latitude().fieldQ('latitude'),
vl.longitude().fieldQ('longitude'),
vl.tooltip([vl.fieldN('origin'), vl.fieldQ('routes')]),
vl.size().fieldQ('routes').scale({range: [0, 1000]}).legend(null),
vl.order().fieldQ('routes').sort('descending'), // place smaller circles on top
);
return vl.layer(map, points)
.project(vl.projection('albersUsa'))
.width(900).height(500)
.config({view: {stroke: null}})
.render();
}
Insert cell
Insert cell
Insert cell
pizzaorders
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
pizzaorders.columns
Insert cell
Insert cell
viewof namez = Inputs.select(d3.group(pizzaorders, d => d.name), {label: "All names"})
Insert cell
viewof pizza_namez = Inputs.select(d3.group(pizzaorders, d => d.name.split('Pizza')[0]), {label: "All pizza_names"})
Insert cell
viewof pizza_sizez = Inputs.select(d3.group(pizzaorders, d => d.name.split('Pizza')[1]), {label: "All pizza_sizes"})
Insert cell
Insert cell
getSecondPart("sometext-20202") // simply testing function getSecondPart call
Insert cell
pizzaorders_names = addColumn(pizzaorders, 'pizza_name', d => d.name.split('Pizza')[0])
Insert cell
pizzaorders_names_size = addColumn(pizzaorders_names, 'pizza_size', d => d.name.split('Pizza')[1])
Insert cell
pizzaorders_names_size
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
function sum(values) {
let sum = 0;
for (let i = 0, n = values.length; i < n; ++i) {
const v = +values[i];
if (v) sum += v;
}
return sum;
}
Insert cell
{(sum(pizzaorders['orders'])).toFixed(0)}
Insert cell
data = pizzaorders_names_size
Insert cell
Insert cell
Insert cell
Plot.lineY(data, Plot.map({y: "cumsum"}, {y: data})).plot({height: 200})
Insert cell
Plot.lineY(data, Plot.mapY("cumsum", {y: data})).plot({height: 200})
Insert cell
// meant to show variance between highs and lows
// from https://observablehq.com/@observablehq/plot-map
Plot.plot({
y: {
grid: true,
label: "↑ Pizza Orders"
},
marks: [
Plot.areaY(data, {x: "orderDate", y: "orders", curve: "step", fill: "#ccc"})
//plot.areaY(data, {x: "orderDate", y:"orders", curve:"step", "fill: "#ccc"})
//Plot.areaY(data, {x: "orderDate", y1: min("orders"), y2: max("orders"), curve: "step", fill: "#ccc"}),
//Plot.line(data, Plot.windowY({x: "orderDate", y: "orders", k: 7, curve: "step", stroke: "blue"})),
// blue line along bottom, original high/low temperatures so cold/hot was colour code
//Plot.line(data, Plot.windowY({x: "orderDate", y: "total", k: 7, curve: "step", stroke: "red"}))
// red line along top
]
})
Insert cell
// Plot the total number of sales by brand
Plot.plot({
marks: [
// Draw vertical bars
Plot.barY(
data,
// Group data into categories along the x axis
Plot.groupX(
{ y: "count" }, // compute + display the count of observations in each group
{ x: "pizza_name" } // group observations by the `brand`
)
)
],
y: {
label: "↑ Count of sales by pizza name"
},
marginLeft: 60
})
Insert cell
// Plot the total number of sales by brand
Plot.plot({
marks: [
// Draw vertical bars
Plot.barY(
data,
// Group data into categories along the x axis
Plot.groupX(
{ y: "count" }, // compute + display the count of observations in each group
{ x: "pizza_size" }, // group observations by the `brand`
fill: "pizza_name"
)
)
],
y: {
label: "↑ Count of sales by pizza size"
},
marginLeft: 60
})
Insert cell
viewof limits = brushFilterX(
d3.extent(data, (d) => d.orderDate),
{ defaultExtent: [d3.isoParse("2022-01-01"), d3.isoParse("2022-03-31")] }
// why aren't these max and min functions instead of hard coding dates?
)
Insert cell
// Create a line plot showing the rolling average
// source: https://observablehq.com/@observablehq/discovering-date-patterns?collection=@observablehq/analyzing-time-series-data
Plot.line(
data,
// compute the rolling average, show values in the brush selection
Plot.windowY({
x: d => (!limits || d.date >= limits[0] && d.date <= limits[1]) ? d.date : NaN,
y: "value",
k: smooth
})
).plot({
marks: [Plot.ruleY([0])], // draw a line at x=0
marginLeft: 50,
x: { label: "date (utc)→", domain: limits || undefined },
y: {// Filtering down based on the brush
label: "↑ Electricity Demand (MWh)",
domain: [0, d3.max(data, (d) => d.value)]
},
width,
height: 400,
caption: md`<em>Note, this displays the x-axis in UTC time, not the local time for California.</em>`
})
Insert cell
Insert cell
Insert cell
Inputs.table(pizzaorders, {
format: {
orders: sparkbar(d3.max(pizzaorders, d => d.orders))
,total: sparkbar(d3.max(pizzaorders, d => d.total))
}
})
Insert cell
Insert cell
Plot.plot({
marks: [
// Plot.ruleY([0]),
Plot.lineY(pizzaorders,
Plot.windowX({x: "orderDate", y: pizzatotals, k: 1, reduce: "mean", stroke: "category"}))
],
color: {
domain: ["Specialty", "Classic","Vegetarian"],
legend: true
},
marginLeft: 50
})
Insert cell
// try stacked bar chart of pizza order values
// see https://observablehq.com/@d3/diverging-stacked-bar-chart
// or revenue by pizza category https://observablehq.com/@mbostock/revenue-by-music-format-1973-2018
Insert cell
chart = StackedBarChart(pizzaorders, {
x: d => d.orders,
y: d => d.cateogry,
z: d => d.total,
xFormat: "+%",
xLabel: "← more lies · Truthiness · more truths →",
yDomain: d3.groupSort(pizzaorders, D => d3.sum(D, d => -Math.min(0, d.proportion)), d => d.speaker),
zDomain: pizzaorders.rulings,
colors: d3.schemeSpectral[pizzaorders.rulings.length],
width,
marginLeft: 70
})
Insert cell
d3.sum(pizzaorders, d => d.total)
Insert cell
// filter array by sum
grpamounts.filter(d => d.sum > 50000)
Insert cell
pizzatotals = grpamounts.map(d => d.sum)
Insert cell
grpamounts = group(pizzaorders)
.by(d=>d.orderDate)
//.orderBy(d=>d.category)
.run() // This returns array
.map(grouped=>{
const total = grouped.values.map(d=>d.total);
const sum = total.reduce((a,b)=>a+b);
const avg = sum/grouped.values.length;
const max = Math.max(...total);
const min = Math.min(...total);
return Object.assign(
{min,max,sum,avg},
grouped,
)
})
Insert cell
viewof table = Inputs.table(pizzaorders)
Insert cell
Plot.plot({
marks: [
// Plot.ruleY([0]),
Plot.lineY(pizzaorders,
Plot.windowX({x: "orderDate", y: "total", k:100, reduce: "mean", stroke: "category"}))
],
color: {
domain: ["Classic", "Specialty","Vegetarian"],
legend: true
},
marginLeft: 50
})
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
Insert cell
Insert cell
import {Icicle} from "@d3/icicle"
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