Public
Edited
Feb 2
Importers
17 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
trajectory_manipulate = manipulate({
this: this,
viewofData: viewof x_trajectory,
viewofPlot: viewof plot_trajectory,
invalidation,
onInteraction: ({
event,
pixelStart,
pixelCurrent,
dataStart,
dataCurrent,
viewofPlot
}) => {
// Adjust control surface
const scaleX = viewofPlot.scale("x");
const scaleY = viewofPlot.scale("y");
dataCurrent.i = Math.max(
invert(
scaleX,
scaleX.apply(dataStart.i) + pixelCurrent[0] - pixelStart[0]
),
0.1
);
dataCurrent.j = Math.max(
invert(
scaleY,
scaleY.apply(dataStart.j) + pixelCurrent[1] - pixelStart[1]
),
0.1
);

// fix velocity
const magnitude = Math.sqrt(
dataCurrent.i * dataCurrent.i + dataCurrent.j * dataCurrent.j
);
if (magnitude > 50) {
const scale = 50 / magnitude;
dataCurrent.i *= scale;
dataCurrent.j *= scale;
}
event.preventDefault(); // prevents scrolling on mobile
}
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
manipulate({
this: this,
viewofData: viewof x_simple,
viewofPlot: viewof plot_simple,
invalidation,
onInteraction: ({
event,
pixelStart,
pixelCurrent,
dataStart,
dataCurrent,
viewofPlot
}) => {
const scaleX = viewofPlot.scale("x");
const scaleY = viewofPlot.scale("y");
dataCurrent.x = invert(
scaleX,
scaleX.apply(dataStart.x) + pixelCurrent[0] - pixelStart[0]
);
dataCurrent.y = invert(
scaleY,
scaleY.apply(dataStart.y) + pixelCurrent[1] - pixelStart[1]
);
event.preventDefault(); // prevents scrolling on mobile
}
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
manipulate({
this: this,
viewofData: viewof x_ordcat,
viewofPlot: viewof plot_ordcat,
invalidation,
onInteraction: ({
event,
pixelStart,
pixelCurrent,
dataStart,
dataCurrent,
viewofPlot
}) => {
const scaleX = viewofPlot.scale("x");
const scaleY = viewofPlot.scale("y");
dataCurrent.ordinal = invert(
scaleX,
scaleX.apply(dataStart.ordinal) + pixelCurrent[0] - pixelStart[0]
);
dataCurrent.categorical = invert(
scaleY,
scaleY.apply(dataStart.categorical) + pixelCurrent[1] - pixelStart[1]
);
event.preventDefault(); // prevents scrolling on mobile
}
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
manipulate({
this: this,
viewofData: viewof x_sliders,
viewofPlot: viewof plot_sliders,
invalidation,
onInteraction: ({
event,
pixelStart,
pixelCurrent,
dataStart,
dataCurrent,
viewofPlot
}) => {
const y_scale = viewofPlot.scale("y");
dataCurrent.value = invert(
y_scale,
y_scale.apply(dataStart.value) + pixelCurrent[1] - pixelStart[1]
);
event.preventDefault(); // prevents scrolling on mobile
}
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
manipulate({
this: this,
viewofData: viewof x_nodes,
viewofPlot: viewof plot_graph,
invalidation,
onInteraction: ({
event,
pixelStart,
pixelCurrent,
dataStart,
dataCurrent,
viewofPlot
}) => {
const x_scale = viewofPlot.scale("x");
const y_scale = viewofPlot.scale("y");
dataCurrent.x = invert(
x_scale,
x_scale.apply(dataStart.x) + pixelCurrent[0] - pixelStart[0]
);
dataCurrent.y = invert(
y_scale,
y_scale.apply(dataStart.y) + pixelCurrent[1] - pixelStart[1]
);
event.preventDefault(); // prevents scrolling on mobile
}
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
manipulate({
this: this,
viewofData: viewof x_edges_domain,
viewofPlot: viewof plot_edges,
invalidation,
onInteraction: ({
event,
pixelStart,
pixelCurrent,
dataStart,
dataCurrent,
viewofPlot
}) => {
if (!_.isEqual(pixelStart, pixelCurrent)) return; // only trigger for click
const edgeIndex = viewof x_edges.value.findIndex((x) =>
_.isEqual(x, dataCurrent)
);
if (edgeIndex != -1) {
viewof x_edges.value.splice(edgeIndex, 1);
} else {
viewof x_edges.value.push({ ...dataCurrent });
}
viewof x_edges.dispatchEvent(new Event("input"));
event.preventDefault(); // prevents scrolling on mobile
}
})
Insert cell
Insert cell
// import { land } from "@observablehq/plot-world-map"
Insert cell
Insert cell
Insert cell
Insert cell
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