Published
Edited
Apr 7, 2021
5 stars
Insert cell
Insert cell
Insert cell
Insert cell
custom_scale = {
let sorted_activity_list = Array.from(new Set(data.map(a => a.activity))).sort()
return {
domain: sorted_activity_list,
range: {scheme:'category20'}
}
}
Insert cell
// Original problem was that custom_scale was incorrectly defined; specifically 'scheme' property:
corrected_custom_scale = {
let sorted_activity_list = Array.from(new Set(data.map(a => a.activity))).sort()
return {
domain: sorted_activity_list,
scheme:'category20' // incorrectly defined as range: {scheme:'category20'} in custom_scale
}
}
Insert cell
{
const brush = vl.selectInterval().encodings('x');
const x = vl.x().fieldT('date').title(null);
const y = vl.y().fieldQ('duration');
const selector = vl.markBar({color:'#999'})
.encode(
x,
y
)
.width(700);
const display = vl.markBar({scalePadding:0})
.transform(vl.filter(brush))
.encode(
x,
y,
//Solution:
// vl.color().fieldN('activity').scale(custom_scale), // <-- ONLY CHANGE IS ADDING THE SCALE *** Creates Error
// Proper use of scale: see: https://vega.github.io/vega-lite/docs/scale.html#1-set-a-custom-scheme
//vl.color().fieldN('activity').scale(custom_scale),
vl.color().fieldN('activity').scale(corrected_custom_scale),
vl.tooltip(['duration'])
)
.width(700);

const rule = vl.markRule({color: '#aaa'})
.encode(vl.y().value(30000))

return vl.data(data)
.vconcat(
display.encode( x.scale({domain: brush}) ),
selector.select(brush).height(60),
)
.render();
}
Insert cell
Insert cell
Insert cell
d3V4= require("d3@v4")
Insert cell
schemeCategory20 = d3V4.schemeCategory20
Insert cell
custom_scale_alternative_solution = {
const sorted_activity_list = Array.from(new Set(data.map(a => a.activity))).sort()
// Background: https://stackoverflow.com/questions/58933759/vega-lite-set-color-from-data-whilst-retaining-a-legend
// and https://github.com/d3/d3-scale/blob/master/README.md#schemeCategory20
// See discussion on limitations of category20 scheme: https://github.com/d3/d3/releases/tag/v5.0.0
// You can now use any category from here:
// https://github.com/d3/d3-scale-chromatic/blob/master/README.md#categorical
// For compatability with your example, using d3V4.schemeCategory20 to assign unique colors for all 39 activities.
// Ordinal scales: https://vega.github.io/vega-lite/docs/scale.html#ordinal
const colorRange = sorted_activity_list.map(d3V4.scaleOrdinal(schemeCategory20));

return {
domain: sorted_activity_list,
range: colorRange
}
}
Insert cell
viewof solution = {
const brush = vl.selectInterval().encodings('x');
const x = vl.x().fieldT('date').title(null);
const y = vl.y().fieldQ('duration');
const selector = vl.markBar({color:'#999'})
.encode(
x,
y
)
.width(700);
const display = vl.markBar({scalePadding:0})
.transform(vl.filter(brush))
.encode(
x,
y,
vl.color().fieldN('activity').scale(custom_scale_alternative_solution),
vl.tooltip(['duration'])
)
.width(700);

const rule = vl.markRule({color: '#aaa'})
.encode(vl.y().value(30000))

return vl.data(data)
.vconcat(
display.encode( x.scale({domain: brush}) ),
selector.select(brush).height(60),
)
.render();
}
Insert cell
Insert cell
data = FileAttachment("sharableData.json").json()
Insert cell
import { vl } from "@vega/vega-lite-api"
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more