Published
Edited
Feb 15, 2020
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
md`## Load libraries, look at data`
Insert cell
md`Load in libraries`
Insert cell
import {vl} from '@vega/vega-lite-api'
Insert cell
d3 = require('d3')
Insert cell
import {printTable} from '@uwdata/data-utilities'
Insert cell
Insert cell
stats = d3.csvParse(await FileAttachment("cityfixitdata@2.csv").text(), d3.autoType)
Insert cell
md`Take a look at the first five records, using a nice formatter`
Insert cell
printTable(stats.slice(0,5))
Insert cell
md`Look at the end of the table with negative indexing`
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
vl.markLine()
.data(stats)
.encode(
vl.x().fieldO('Year'),
vl.y().fieldQ('NumRequests'),
vl.color().fieldN('ProblemType')
)
.render()
Insert cell
Insert cell
html`<figure>
${await FileAttachment("linechart2.png").image()}

</figure>`
Insert cell
{
const line = vl.markLine({strokeWidth:3, opacity: 0.5, interpolate: 'monotone'})
.data(stats)
.encode(
vl.x().fieldO('Year'),
vl.y().fieldQ('NumRequests'),
vl.color().fieldN('ProblemType')
);
const points = vl.markCircle({size:100})
.data(stats)
.encode(
vl.x().fieldO('Year'),
vl.y().fieldQ('NumRequests'),
vl.color().fieldN('ProblemType')
);
return vl.layer(line, points).width(300).height(600).render();
}
Insert cell
Insert cell
html`<figure>
${await FileAttachment("linechart3.png").image()}

</figure>`
Insert cell
{
const line = vl.markLine({strokeWidth:3, opacity: 0.5, interpolate: 'monotone'})
.data(stats)
.encode(
vl.x().fieldO('Year')
.axis({labelAngle: 0}),
vl.y().fieldQ('NumRequests').title("Number of Requests"),
vl.color().fieldN('ProblemType')
);
const points = vl.markPoint({size:100, filled:true})
.data(stats)
.encode(
vl.x().fieldO('Year'),
vl.y().fieldQ('NumRequests').title("Number of Requests"),
vl.color().fieldN('ProblemType'),
vl.shape().fieldN('ProblemType')
);
return vl.layer(line, points).width(300).height(600).render();
}
Insert cell
Insert cell
html`<figure>
${await FileAttachment("linechart4.png").image()}

</figure>`
Insert cell
{
const colors = {
domain: ['IllegalDumping', 'BuildingMaintenance', 'Electrical', 'StreetSweeping', 'Graffiti',
'RoadRepair', 'Drainage', 'StreetLights', 'VegetationControl', 'Survey'],
range: ['#8B0000', '#006400', '#1E90FF', '#FFA500', '#800080', '#FFFF00', '#FF6347',
'#008000', '#FF69B4', '#808080']
}
const shapes = {
domain: ['IllegalDumping', 'BuildingMaintenance', 'Electrical', 'StreetSweeping', 'Graffiti',
'RoadRepair', 'Drainage', 'StreetLights', 'VegetationControl', 'Survey'],
range: ['circle', 'diamond', 'square', 'triangle', 'triangle', 'circle', 'diamond', 'square',
'triangle', 'triangle']
}
const line = vl.markLine({strokeWidth:3, opacity: 0.5, interpolate: 'monotone'})
.data(stats)
.encode(
vl.x().fieldO('Year')
.axis({labelAngle: 0}),
vl.y().fieldQ('NumRequests').title("Number of Requests"),
vl.color().fieldN('ProblemType')
);
const points = vl.markPoint({size:100, filled:true})
.data(stats)
.encode(
vl.x().fieldO('Year'),
vl.y().fieldQ('NumRequests').title("Number of Requests"),
vl.color().fieldN('ProblemType').scale(colors),
vl.shape().fieldN('ProblemType').scale(shapes)
);
return vl.layer(line, points).width(300).height(600).render();
}
Insert cell
Insert cell
html`<figure>
${await FileAttachment("linechart5.png").image()}

</figure>`
Insert cell
Insert cell
{
const colors = {
domain: ['IllegalDumping', 'BuildingMaintenance', 'Electrical', 'StreetSweeping', 'Graffiti',
'RoadRepair', 'Drainage', 'StreetLights', 'VegetationControl', 'Survey'],
range: ['#8B0000', '#006400', '#1E90FF', '#FFA500', '#800080', '#FFFF00', '#FF6347',
'#008000', '#FF69B4', '#808080']
}
const shapes = {
domain: ['IllegalDumping', 'BuildingMaintenance', 'Electrical', 'StreetSweeping', 'Graffiti',
'RoadRepair', 'Drainage', 'StreetLights', 'VegetationControl', 'Survey'],
range: ['circle', 'diamond', 'square', 'triangle', 'triangle', 'circle', 'diamond', 'square',
'triangle', 'triangle']
}
const line = vl.markLine({strokeWidth:3, opacity: 0.5, interpolate: 'monotone'})
.data(stats)
.encode(
vl.x().fieldO('Year')
.axis({labelAngle: 0}),
vl.y().fieldQ('NumRequests').title("Number of Requests"),
vl.color().fieldN('ProblemType'))
.title({
text: "By Year",
fontSize: 20,
font: "Tahoma"}
);
const points = vl.markPoint({size:100, filled:true})
.data(stats)
.encode(
vl.x().fieldO('Year'),
vl.y().fieldQ('NumRequests').title("Number of Requests"),
vl.color().fieldN('ProblemType').scale(colors),
vl.shape().fieldN('ProblemType').scale(shapes)
.legend({orient:'top-left'})
);
return vl.layer(line, points).width(300).height(600).render();
}
Insert cell
Insert cell
Insert cell
html`<figure>
${await FileAttachment("barchart3.png").image()}

</figure>`
Insert cell
vl.markBar()
.data(stats)
.encode(
vl.x().fieldQ('NumRequests'),
vl.y().fieldO('Year'),
vl.row().fieldO('ProblemType'),
vl.color().fieldQ('Year').scale({scheme:'greys'})
)
.render()

Insert cell
Insert cell
html`<figure>
${await FileAttachment("barchart4.png").image()}

</figure>`
Insert cell
vl.markBar()
.data(stats)
.encode(
vl.x().fieldQ('NumRequests'),
vl.y().fieldO('Year').title(null),
vl.row({
field: "ProblemType",
type: "nominal",
header: {title:null, labelAngle:360, labelAlign: 'left', labelFont: 'Tahoma',
labelFontStyle: 'bold', labelFontSize: 12},
sort: ['IllegalDumping', 'BuildingMaintenance', 'Electrical', 'StreetSweeping', 'Graffiti',
'RoadRepair', 'Drainage', 'StreetLights', 'VegetationControl', 'Survey']}),
vl.color().fieldQ('Year').scale({scheme:'greys'}).legend(null)
)
.title({
text: "By Problem Type",
fontSize: 15,
font: "Tahoma",
anchor: "middle"})
.render()
Insert cell
Insert cell
html`<figure>
${await FileAttachment("barchart5.png").image()}

</figure>`
Insert cell
{
const bars = vl.markBar()
.encode(
vl.x().fieldQ('NumRequests'),
vl.y().fieldO('Year').title(null),
vl.color().fieldO('Year').scale({scheme:'greys'}).legend(null)
);
const text = vl.markText({type: 'text', align: 'left', baseline: 'middle', dx: 3})
.encode(
vl.text().fieldQ('NumRequests'),
vl.x().fieldQ('NumRequests'),
vl.y().fieldO('Year'));
return vl.layer(bars, text)
.facet({row: {field: 'ProblemType',
header: {title: null, labelAngle:360, labelAlign: 'left', labelFont: 'Tahoma',
labelFontStyle: 'bold', labelFontSize: 12},
sort: ['IllegalDumping', 'BuildingMaintenance', 'Electrical', 'StreetSweeping', 'Graffiti',
'RoadRepair', 'Drainage', 'StreetLights', 'VegetationControl', 'Survey']}})
.data(stats)
.title({
text: "By Problem Type",
fontSize: 15,
font: "Tahoma",
anchor: "middle"})
.render()
}
Insert cell
Insert cell
html`<figure>
${await FileAttachment("combined_chart1.png").image()}

</figure>`
Insert cell
{
const colors = {
domain: ['IllegalDumping', 'BuildingMaintenance', 'Electrical', 'StreetSweeping', 'Graffiti',
'RoadRepair', 'Drainage', 'StreetLights', 'VegetationControl', 'Survey'],
range: ['#8B0000', '#006400', '#1E90FF', '#FFA500', '#800080', '#FFFF00', '#FF6347',
'#008000', '#FF69B4', '#808080']}
const shapes = {
domain: ['IllegalDumping', 'BuildingMaintenance', 'Electrical', 'StreetSweeping', 'Graffiti',
'RoadRepair', 'Drainage', 'StreetLights', 'VegetationControl', 'Survey'],
range: ['circle', 'diamond', 'square', 'triangle', 'triangle', 'circle', 'diamond', 'square',
'triangle', 'triangle']}
const line = vl.markLine({strokeWidth:3, opacity: 0.5, interpolate: 'monotone'})
.data(stats)
.encode(
vl.x().fieldO('Year')
.axis({labelAngle: 0}),
vl.y().fieldQ('NumRequests')
.title("Number of Requests"),
vl.color().fieldN('ProblemType')
.scale(colors)
.legend({orient: 'top-left'}));
const points = vl.markPoint({size:100, filled:true})
.data(stats)
.encode(
vl.x().fieldO('Year'),
vl.y().fieldQ('NumRequests').title("Number of Requests"),
vl.color().fieldN('ProblemType').scale(colors),
vl.shape().fieldN('ProblemType').scale(shapes).legend(null));
const linegraph = vl.layer(line, points)
.width(500)
.height(1000)
.title({text: 'By Year', anchor: 'middle', font: 'Tahoma', fontSize: 15});;
const bars = vl.markBar()
.encode(
vl.x().fieldQ('NumRequests'),
vl.y().fieldO('Year').title(null),
vl.color().fieldQ('Year').scale({scheme:'greys'}).legend(null)
);
const text = vl.markText({type: 'text', align: 'left', baseline: 'middle', dx: 3})
.encode(
vl.text().fieldQ('NumRequests'),
vl.x().fieldQ('NumRequests'),
vl.y().fieldO('Year'));
const bartext = vl.layer(bars, text)
.facet({row: {field: 'ProblemType',
header: {title: null, labelAngle:360, labelAlign: 'left', labelFont: 'Tahoma',
labelFontStyle: 'bold', labelFontSize: 12},
sort: ['IllegalDumping', 'BuildingMaintenance', 'Electrical', 'StreetSweeping', 'Graffiti',
'RoadRepair', 'Drainage', 'StreetLights', 'VegetationControl', 'Survey']}})
.data(stats)
.title({
text: "By Problem Type",
fontSize: 15,
font: "Tahoma",
anchor: "middle"});
return vl.hconcat(linegraph, bartext).title({
text: 'City of Springfield Service Request Statistics (2009-2012)',
anchor: 'middle',
font: 'Tahoma',
fontSize: 20
}).render();
}
Insert cell
Insert cell
html`<figure>
${await FileAttachment("combined_withclickfix@1.png").image()}

</figure>`
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