Public
Edited
Nov 13, 2023
1 fork
Insert cell
Insert cell
render(App)
Insert cell
Visualization = bf.withBluefish((props) => {
return (
bf.Bluefish(
bf.StackH({ total: width },
ForEach(props.states, (state, i) =>
RiverAndShore({...state, next: props.states[i()+1]})
)
)
)
)
})
Insert cell
RiverAndShore = bf.withBluefish((props) => {
const id = solid.createUniqueId();
const nearShore = bluefish.createName("nearShore");
const farShore = bluefish.createName("farShore");
return bf.Group(
bf.Background({background: bf.Rect({ fill: "teal", stroke: "lightgray", "stroke-width": 5, rx: 5, }), padding: 10}, // river color
bf.StackH({ spacing: 100 },
// near shore
bf.Background({background: bf.Rect({ fill: "blanchedalmond" })}, // sandy beach
Shore({...props, side: "Near", name: nearShore}),
),
// far shore
bf.Background({background: bf.Rect({ fill: "blanchedalmond" })}, // sandy beach
Shore({...props, side: "Far", name: farShore}),
),
)
),
// arrows
ForEach(props.gwshore, (animal, i) => {
if (animal.Position === "Near" && props.next !== undefined && props.next.gwshore[i()].Position === "Far") {
return bf.Group(
// to draw the arrow we make an invisible rectangle offset by 50px from the corresponding element...
bf.StackH({spacing: 50},
bf.Ref({select: [nearShore, i()]}),
bf.Rect({ name: `${id}-${i()}-arrow`, width: 0, height: 0 })),
// then draw the arrow
bf.Arrow({ stroke: "white", "stroke-width": 10 }, bf.Ref({select: [nearShore, i()]}), bf.Ref({select: `${id}-${i()}-arrow`})),
)
} else if (animal.Position === "Far" && props.next !== undefined && props.next.gwshore[i()].Position === "Near") {
return bf.Group(
bf.StackH({spacing: 50},
bf.Rect({ name: `${id}-${i()}-arrow`, width: 0, height: 0 }),
bf.Ref({select: [farShore, i()]})),
bf.Arrow({ stroke: "white", "stroke-width": 10 }, bf.Ref({select: [farShore, i()]}), bf.Ref({select: `${id}-${i()}-arrow`})),
)
}
})
)
})
Insert cell
Shore = bf.withBluefish((props) => {
const animals = props.gwshore.map((_, i) => bluefish.createName(i));
return bf.StackV(ForEach(props.gwshore, (animal, i) => {
if (animal.Position === props.side) {
return Animal({...animal, name: animals[i()] });
} else {
return Blank({name: animals[i()]});
}
}))
})
Insert cell
states = [{
gwshore: [
{ GWAnimal: "Goat", Position: Near },
{ GWAnimal: "Goat", Position: Near },
{ GWAnimal: "Goat", Position: Far },
{ GWAnimal: "Wolf", Position: Near },
{ GWAnimal: "Wolf", Position: Far },
{ GWAnimal: "Wolf", Position: Far },
],
gwboat: { Position: Near },
gwnext: 1,
},
{
gwshore: [
{ GWAnimal: "Goat", Position: Near },
{ GWAnimal: "Goat", Position: Far },
{ GWAnimal: "Goat", Position: Far },
{ GWAnimal: "Wolf", Position: Near },
{ GWAnimal: "Wolf", Position: Far },
{ GWAnimal: "Wolf", Position: Far },
],
gwboat: { Position: Far },
gwnext: 2,
},
{
gwshore: [
{ GWAnimal: "Goat", Position: Near },
{ GWAnimal: "Goat", Position: Far },
{ GWAnimal: "Goat", Position: Far },
{ GWAnimal: "Wolf", Position: Near },
{ GWAnimal: "Wolf", Position: Far },
{ GWAnimal: "Wolf", Position: Near },
],
gwboat: { Position: Near },
},
]
Insert cell
ForEach = (list, callBack) => {
return h(For, { each: list }, callBack);
}
Insert cell
Animal = bf.withBluefish((props) => {
const goatUrl = "https://github.com/bluefishjs/bluefish/assets/21694516/c206f12c-6b9a-4e6f-b596-9b7e0729f6bc";
const wolfUrl = "https://github.com/bluefishjs/bluefish/assets/21694516/d6b1b9d2-e75c-48e5-bc72-63ca85bda956";
return bf.Image({ width: 100, height: 100, href: props.GWAnimal === "Goat" ? goatUrl : wolfUrl })
})
Insert cell
Blank = bf.withBluefish(() => {
return bf.Rect({ width: 100, height: 100, fill: "none", stroke: "none"});
});
Insert cell
function App() {
return Visualization({states});
}
Insert cell
Insert cell
Insert cell
h_pkg = import("https://cdn.jsdelivr.net/npm/solid-js/h/+esm");
Insert cell
h = h_pkg.default
Insert cell
solid = import("https://cdn.jsdelivr.net/npm/solid-js/+esm");
Insert cell
For = solid.For
Insert cell
Insert cell
Insert cell
Far = "Far"
Insert cell
Near = "Near"
Insert cell
Goat = "Goat"
Insert cell
Wolf = "Wolf"
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