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

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