Public
Edited
Jun 11
Insert cell
Insert cell
import { vl } from "@vega/vega-lite-api-v5"
Insert cell
vegaSelected = require("vega-selected@0.0.3")
Insert cell
vega = await import("https://cdn.skypack.dev/vega@5")
Insert cell
url = "https://vega.github.io/vega-datasets/data/cars.json"
Insert cell
cars = await fetch("https://vega.github.io/vega-datasets/data/cars.json").then(
(res) => res.json()
)
Insert cell
colors3 = ["#ff8e2c", "#e10059", "#4e79a7"]
Insert cell
Inputs.table(filtered(view))
Insert cell
filtered = {
const signal = view.getState().signals;
const key = Object.keys(signal).find((k) => k.startsWith("brush"));
const brushStore = signal[key];

if (!brushStore || !brushStore.Horsepower || !brushStore.Miles_per_Gallon)
return [];

const [x0, x1] = brushStore.Horsepower;
const [y0, y1] = brushStore.Miles_per_Gallon;

return cars.filter(
(d) =>
d.Horsepower != null &&
d.Miles_per_Gallon != null &&
d.Horsepower >= x0 &&
d.Horsepower <= x1 &&
d.Miles_per_Gallon >= y0 &&
d.Miles_per_Gallon <= y1
);
}
Insert cell
{
const selectHover = vl
.selectPoint("hover")
.nearest(true)
.on("mouseover")
.clear("mouseout")
.fields(["Name"]);

const base = vl
.markCircle()
.data(cars)
.params(selectHover)
.encode(
vl
.x()
.fieldQ("Horsepower")
.scale({ domain: [0, 300] }),
vl
.y()
.fieldQ("Miles_per_Gallon")
.scale({ domain: [0, 50] }),
vl.color().fieldN("Origin"),
vl.opacity().value(0.7)
);

const highlight = vl
.markCircle({ stroke: "black", strokeWidth: 2 })
.data(cars)
.transform(vl.filter(selectHover))
.encode(
vl.x().fieldQ("Horsepower"),
vl.y().fieldQ("Miles_per_Gallon"),
vl.color().fieldN("Origin"),
vl.tooltip(["Name", "Horsepower", "Miles_per_Gallon"])
);

return vl.layer(base, highlight).render();
}
Insert cell
{
const selectHover = vl
.selectPoint("hover")
.nearest(true)
.on("mouseover")
.clear("mouseout");

return vl
.markCircle()
.data(cars)
.params(selectHover)
.encode(
vl
.x()
.fieldQ("Horsepower")
.scale({ domain: [0, 300] }),
vl
.y()
.fieldQ("Miles_per_Gallon")
.scale({ domain: [0, 50] }),
vl.color().fieldN("Origin"),
vl.stroke().if(selectHover, vl.value("black")).value(null),
vl.strokeWidth().if(selectHover, vl.value(2)).value(0),
vl
.tooltip()
.if(selectHover, [
vl.fieldN("Name"),
vl.fieldQ("Horsepower"),
vl.fieldQ("Miles_per_Gallon")
])
)
.render();
}
Insert cell
{
const selectHover = vl
.selectPoint("hover")
.on("mouseover")
.clear("mouseout")
.fields(["Name"])
//.fields(["Horsepower", "Miles_per_Gallon"])
.nearest(true);

const base = vl
.markCircle()
.data(cars)
.params(selectHover)
.encode(
vl
.x()
.fieldQ("Horsepower")
.scale({ domain: [0, 300] }),
vl
.y()
.fieldQ("Miles_per_Gallon")
.scale({ domain: [0, 50] }),
vl.color().fieldN("Origin"),
vl.opacity().value(0.7)
);

const highlight = vl
.markCircle({ stroke: "black", strokeWidth: 2 })
.data(cars)
.transform(
vl.filter(`hover["Name"] != null`) // 👈 vérifie que la sélection est active
)
//.transform(vl.filter(selectHover))
.encode(
vl.x().fieldQ("Horsepower"),
vl.y().fieldQ("Miles_per_Gallon"),
vl.color().fieldN("Origin"),
vl.tooltip(["Name", "Horsepower", "Miles_per_Gallon"])
);

return vl.layer(base, highlight).render();
}
Insert cell
{
const selectHover = vl
.selectPoint("hover")
.on("mouseover")
.clear("mouseout")
.fields(["Name"])
.nearest(true);

const base = vl
.markCircle()
.data(cars)
.params(selectHover)
.encode(
vl
.x()
.fieldQ("Horsepower")
.scale({ domain: [0, 300] }),
vl
.y()
.fieldQ("Miles_per_Gallon")
.scale({ domain: [0, 50] }),
vl.color().fieldN("Origin"),
vl.opacity().value(0.8),
vl.stroke().if(selectHover, vl.value("black")).value(null),
vl.strokeWidth().if(selectHover, vl.value(2)).value(0),
vl.tooltip().if(selectHover, ["Name", "Horsepower", "Miles_per_Gallon"])
);

return base.render();
}
Insert cell
{
const selectBrush = vl.selectInterval().encodings("x", "y");
const selectOrigin = vl.selectPoint().fields(["Origin"]);
const selectHover = vl
.selectPoint("hover")
.on("mouseover")
.nearest(true)
.clear("mouseout");
const selectAnd = vl.and(selectBrush, selectOrigin);

const baseEncoding = {
x: vl
.x()
.fieldQ("Horsepower")
.scale({ domain: [0, 300] }),
y: vl
.y()
.fieldQ("Miles_per_Gallon")
.scale({ domain: [0, 50] }),
color: vl.color().fieldN("Origin").scale({ range: colors3 }),
opacity: vl.opacity().if(selectAnd, vl.value(1.0)).value(0.2)
};

const layer1 = vl
.markCircle()
.data(cars)
.params(selectBrush, selectHover)
.encode(baseEncoding);

const layerHover = vl
.markCircle({ stroke: "black", strokeWidth: 1, fill: null })
.data(cars)
//.params(selectHover)
.transform(vl.filter(selectHover))
.encode({
x: baseEncoding.x,
y: baseEncoding.y,
tooltip: vl.tooltip(["Name", "Horsepower", "Miles_per_Gallon", "Origin"])
});

const plot1 = vl.layer(layer1, layerHover);

const plot2 = vl
.markBar()
.data(cars)
.params(selectOrigin)
//.transform(vl.filter(selectBrush))
.encode(
vl.y().fieldN("Origin"),
vl
.x()
.count()
.scale({ domain: [0, 300] }),
vl.color().fieldN("Origin").scale({ range: colors3 }),
vl.opacity().if(selectOrigin, vl.value(1.0)).value(0.2)
);

return vl.vconcat(plot1, plot2).render();
}
Insert cell
a = printTable(cars.slice(0, 10))
Insert cell
{
const brush = vl.selectInterval().encodings("x");

const scatter = vl
.markPoint()
.width(300)
.height(200)
.params(brush)
.encode(vl.x().fieldQ("Horsepower"), vl.y().fieldQ("Miles_per_Gallon"));

const bars = vl
.markBar()
.name("filtered")
.transform(vl.filter("brush"))
.encode(
vl.x().fieldN("Origin"),
vl.y().aggregate("count").type("quantitative")
);

const spec = vl
.vconcat(scatter, bars)
.data({ url: "https://vega.github.io/vega-datasets/data/cars.json" });

return spec.render();
}
Insert cell
import { printTable } from "@uwdata/data-utilities"
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