Published
Edited
Apr 30, 2021
3 forks
9 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
cars = (await require('vega-datasets@1'))['cars.json']()
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
vl.markPoint({filled:true, color:'teal'})
.data(cars)
.encode(
vl.x().fieldQ('Horsepower'),
vl.y().fieldQ('Miles_per_Gallon'),
vl.tooltip('Name') // New!
)
.render()
Insert cell
Insert cell
vl.markPoint({filled:true, color:'teal'})
.data(cars)
.encode(
vl.x().fieldQ('Horsepower'),
vl.y().fieldQ('Miles_per_Gallon'),
vl.tooltip(['Name', 'Origin']) // New!
)
.render()
Insert cell
Insert cell
Insert cell
{
// The selection instance stores our selected points, and we can use this to do conditional encodings later.
const selection = vl.selectPoint();
return vl.markPoint({filled:true})
.data(cars)
.encode(
vl.color().value('teal'), // same effect as putting color in the markPoint({...})
vl.x().fieldQ('Horsepower'),
vl.y().fieldQ('Miles_per_Gallon')
)
// Use params() method to say
// "the 'selection' should be invoked, please let me interact with the graph by the type in selection!"
.params(selection)
.render()
}
Insert cell
Insert cell
{
const selection = vl.selectPoint();
return vl.markPoint({filled:true})
.data(cars)
.encode(
vl.color().value('teal'),
vl.x().fieldQ('Horsepower'),
vl.y().fieldQ('Miles_per_Gallon'),
vl.opacity().if(selection).value(0.1) // New!
)
.params(selection)
.render()
}
Insert cell
Insert cell
{
const selection = vl.selectPoint();
return vl.markPoint({filled:true})
.data(cars)
.encode(
vl.color().if(selection, vl.value('teal')).value("gray"), // New!
vl.x().fieldQ('Horsepower'),
vl.y().fieldQ('Miles_per_Gallon'),
vl.opacity().if(selection).value(0.1)
)
.params(selection)
.render()
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
import {uniqueValid} from '@uwdata/data-utilities'
Insert cell
Insert cell
origin = uniqueValid(cars, d => d.Origin)
Insert cell
Insert cell
{
const selection = vl.selectPoint('Cars') // name the selection 'Cars' (what will happen if we delete 'Cars'?)
.fields('Origin') // limit selection to the Origin field
.init(origin[0]) // use first genre entry as initial value
.bind(vl.menu(origin)); // bind to a menu of unique genre values
// Nothing changed below
return vl.markPoint({filled:true})
.data(cars)
.params(selection)
.encode(
vl.color().if(selection, vl.value('teal')).value("gray"),
vl.x().fieldQ('Horsepower'),
vl.y().fieldQ('Miles_per_Gallon'),
vl.opacity().if(selection).value(0.1)
)
.render()
}
Insert cell
Insert cell
{
const selection = vl.selectPoint('Cars')
.fields('Origin')
.init(origin[0])
.bind(vl.radio(origin)); // New!

// Nothing changed below
return vl.markPoint({filled:true})
.data(cars)
.params(selection)
.encode(
vl.color().if(selection, vl.value('teal')).value("gray"),
vl.x().fieldQ('Horsepower'),
vl.y().fieldQ('Miles_per_Gallon'),
vl.opacity().if(selection).value(0.1)
)
.render()
}
Insert cell
Insert cell
Insert cell
Insert cell
cylinders = uniqueValid(cars, d => d.Cylinders)
Insert cell
{ const selection = vl.selectPoint('Cars')
.fields('Origin', 'Cylinders') // New!
.init({Origin: origin[2], Cylinders: cylinders[3]}) // New! Notice what we have for initial values.
.bind({Origin: vl.menu(origin).name("Origin"), Cylinders: vl.slider(3, 8, 1).name("Cylinders")}); // New!

return vl.markCircle()
.data(cars)
.params(selection)
.encode(
vl.x().fieldQ('Horsepower'),
vl.y().fieldQ('Miles_per_Gallon'),
vl.color().if(selection, vl.fieldN('Origin')).value('grey'),
vl.opacity().if(selection, vl.value(0.8)).value(0.1)
)
.render()
}
Insert cell
Insert cell
{
const isOrigin = vl.selectPoint('isOrigin')
.fields('Origin')
.bind('legend'); // bind to legend interactions
const numCylinders = vl.selectPoint('Cars')
.fields('Cylinders')
.init(cylinders[3])
.bind(vl.slider(3, 8, 1).name("Cylinders"));
const show = vl.and(isOrigin, numCylinders); // combine selections

return vl.markCircle()
.data(cars)
.params(isOrigin, numCylinders) // add selections to plot
.encode(
vl.x().fieldQ('Horsepower'),
vl.y().fieldQ('Miles_per_Gallon'),
vl.color().if(show, vl.color().fieldN('Origin')).value('grey'),
vl.opacity().if(show, vl.value(1.0)).value(0.2)
)
.render();
}
Insert cell
Insert cell
Insert cell
year_slider = Range([1970, 1980], { step: 1, value: 1970 })
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
const brush = vl.selectInterval() // Brush is a better (vivid?) name than selection in this case!
.encodings('x'); // limit selection to x-axis (year) values
// dynamic query histogram
const years = vl.markBar()
.data(cars)
.params(brush) // params(brush) assure that we are able to drag on the bar chart!
.encode(
vl.x().year('Year'),
vl.y().count().title(null)
)
.width(390)
.height(60)

const scatter = vl.markPoint({filled:true})
.data(cars)
.encode(
vl.color().fieldN('Origin')
.scale({scheme: 'tableau20'})
.legend({orient: 'bottom', titleOrient: 'left'}),
vl.x().fieldQ('Horsepower'),
vl.y().fieldQ('Miles_per_Gallon'),
vl.opacity().if(brush, vl.value(0.75)).value(0.05), // Use brush for conditional encodings
vl.tooltip('Name')
)
.width(390)
.height(300);

return vl.vconcat(years, scatter).spacing(5).render();
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
return vl.markCircle()
.data(cars)
.encode(
vl.x().fieldQ(vl.repeat('column')),
vl.y().fieldQ(vl.repeat('row')),
vl.color().fieldO('Cylinders'),
vl.opacity().value(0.8)
)
.width(140)
.height(140)
.repeat({
column: ['Acceleration', 'Horsepower', 'Miles_per_Gallon'],
row: ['Miles_per_Gallon', 'Horsepower', 'Acceleration']
})
.render();
}
Insert cell
Insert cell
{
const brush = vl.selectInterval() // create a constant brush
.resolve('global'); // resolve all selections to a single global instance
return vl.markCircle()
.data(cars)
.params(brush) // add selection
.encode(
vl.x().fieldQ(vl.repeat('column')),
vl.y().fieldQ(vl.repeat('row')),
vl.color().fieldO('Cylinders'),
vl.opacity().value(0.8)
)
.width(140)
.height(140)
.repeat({
column: ['Acceleration', 'Horsepower', 'Miles_per_Gallon'],
row: ['Miles_per_Gallon', 'Horsepower', 'Acceleration']
})
.render();
}
Insert cell
Insert cell
{
const brush = vl.selectInterval()
.resolve('global');
return vl.markCircle()
.data(cars)
.params(brush)
.encode(
vl.x().fieldQ(vl.repeat('column')),
vl.y().fieldQ(vl.repeat('row')),
vl.color().if(brush, vl.fieldO('Cylinders')).value('grey'), // New!
vl.opacity().if(brush, vl.value(0.8)).value(0.1) // New!
)
.width(140)
.height(140)
.repeat({
column: ['Acceleration', 'Horsepower', 'Miles_per_Gallon'],
row: ['Miles_per_Gallon', 'Horsepower', 'Acceleration']
})
.render();
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
vl.markPoint({filled:true, color:'teal'})
.data(cars)
.params(
vl.selectInterval().bind('scales') // Just adding a line of code, how amazing!
)
.encode(
vl.x().fieldQ('Horsepower'),
vl.y().fieldQ('Miles_per_Gallon')
)
.render()
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
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