Public
Edited
May 28, 2023
Insert cell
Insert cell
// imports
import {vegalite} from "@jonfroehlich/vega-lite-utilities"
Insert cell
import {printTableTypes} from '@jonfroehlich/data-utilities'
Insert cell
// load data
h4File = FileAttachment("H4.csv")
Insert cell
h5File = FileAttachment("H5.csv")
Insert cell
h6File = FileAttachment("H6.csv")
Insert cell
l5File = FileAttachment("L5.csv")
Insert cell
l6File = FileAttachment("L6.csv")
Insert cell
h4counts = h4File.csv()
Insert cell
h5counts = h5File.csv()
Insert cell
h6counts = h6File.csv()
Insert cell
l5counts = l5File.csv()
Insert cell
l6counts = l6File.csv()
Insert cell
{
const lineChartH4 = vl.markLine(
{clip: true, color: "black"})
.data(h4counts)
.encode(
vl.x().fieldQ('year').scale({domain: [860, 2100]}),
vl.y().fieldQ('H4_counts')
);

const lineChartH5 = vl.markLine(
{clip: true, color: "red"})
.data(h5counts)
.encode(
vl.x().fieldQ('year').scale({domain: [860, 2100]}),
vl.y().fieldQ('H5_counts')
);

const lineChartH6 = vl.markLine(
{clip: true, color: "blue"})
.data(h6counts)
.encode(
vl.x().fieldQ('year').scale({domain: [860, 2100]}),
vl.y().fieldQ('H6_counts')
);

const lineChartL5 = vl.markLine(
{clip: true, color: "green"})
.data(l5counts)
.encode(
vl.x().fieldQ('year').scale({domain: [860, 2100]}),
vl.y().fieldQ('L5_counts')
);
const lineChartL6 = vl.markLine(
{clip: true, color: "pink"})
.data(l6counts)
.encode(
vl.x().fieldQ('year').scale({domain: [860, 2100]}),
vl.y().fieldQ('L6_counts')
);

return vl.layer(lineChartH4, lineChartH5, lineChartH6, lineChartL5, lineChartL6)
.title("Distribution of Number of Landings")
.width(400)
.height(250)
.render();
}
Insert cell
mtrFile = FileAttachment("Meteorite_Landings.csv")
Insert cell
mtrLandings = mtrFile.csv()
Insert cell
plot = {
// select a point for which to provide details-on-demand
const hover = vl.selectPoint('hover')
.encodings('x') // limit selection to x-axis value
.on('mouseover') // select on mouseover events
.toggle(false) // disable toggle on shift-hover
.nearest(true); // select data point nearest the cursor

// predicate to test if a point is hover-selected
// return false if the selection is empty
const isHovered = hover.empty(false);
// define our base line chart of stock prices
const line = vl.markLine()
.transform([
{"calculate": "year(datum.year)", "as": "year"}, // calculate the year from the 'year' field
{"filter": "datum.recclass === 'L5'"},
{"aggregate": [{"op": "count", "as": "counts"}], "groupby": ["year"]} // aggregate counts by year and class
])
.encode(
vl.x().fieldT('year').scale({domain: [860, 2100]}),
vl.y().fieldQ('counts')
);
// shared base for new layers, filtered to hover selection
const base = line.transform(vl.filter(isHovered));

// mark properties for text label layers
const label = {align: 'left', dx: 5, dy: -5};
const white = {stroke: 'white', strokeWidth: 2};

return vl.data(mtrLandings)
.layer(
line,
// add a rule mark to serve as a guide line
vl.markRule({color: 'firebrick'})
.transform(vl.filter(isHovered))
.encode(vl.x().fieldT('year')),
// add circle marks for selected time points, hide unselected points
line.markCircle()
.params(hover) // use as anchor points for selection
.encode(vl.opacity().if(isHovered, vl.value(1)).value(0)),
// add white stroked text to provide a legible background for labels
base.markText(label, white).encode(vl.text().fieldQ('counts')),
// add text labels for stock prices
base.markText(label).encode(vl.text().fieldQ('counts'))
)
.width(700)
.height(400)
.render();
}
Insert cell
viewof toggleYAxisReverse = Inputs.toggle({label: "Reverse Y Axis", value: true})
Insert cell
{
const showH4= Inputs.toggle({label: "Reverse Y Axis", value: true})
const showGraph = vl.selectSingle()
.name('showGraph')
.fields('toggle')
.init({ toggle: true })
.bind({
input: 'checkbox',
label: 'Show Graph'
});
const lineChartH4 = vl.markLine(
{clip: true, color: "black"})
.data(h4counts)
.encode(
vl.x().fieldQ('year').scale({domain: [860, 2100]}),
vl.y().fieldQ('H4_counts').scale({reverse: showH4})
);

const lineChartH5 = vl.markLine(
{clip: true, color: "red"})
.data(h5counts)
.encode(
vl.x().fieldQ('year').scale({domain: [860, 2100]}),
vl.y().fieldQ('H5_counts')
);

const lineChartH6 = vl.markLine(
{clip: true, color: "blue"})
.data(h6counts)
.encode(
vl.x().fieldQ('year').scale({domain: [860, 2100]}),
vl.y().fieldQ('H6_counts')
);

const lineChartL5 = vl.markLine(
{clip: true, color: "green"})
.data(l5counts)
.encode(
vl.x().fieldQ('year').scale({domain: [860, 2100]}),
vl.y().fieldQ('L5_counts')
);
const lineChartL6 = vl.markLine(
{clip: true, color: "pink"})
.data(l6counts)
.encode(
vl.x().fieldQ('year').scale({domain: [860, 2100]}),
vl.y().fieldQ('L6_counts')
);

return vl.layer(lineChartH4, lineChartH5, lineChartH6, lineChartL5, lineChartL6)
.title("Distribution of Number of Landings")
.width(400)
.height(250)
.config({
selection: {
showGraph: showGraph
}
})
.render();
}
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