Public
Edited
Jul 28, 2023
2 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
colorSpacesLocal
Insert cell
transitionFilter(
transitionGenerator(viewof spaceRef, {
states: luminanceDomain
}),
viewof transSpaceRef
)
Insert cell
viewof transSpaceRef = Inputs.input()
Insert cell
luminanceRefTens = tidy.tidy(
[],
tidy.expand({
space: Object.keys(colorSpacesLocal),
luminanceRef: math.range(0, 100, 10, true).toArray()
}),
tidy.mutate({
sRgbRef: (d) =>
transitionInterpolate(transSpaceRef, (spaceRef) =>
_.flow([
colorSpacesLocal[spaceRef].from100,
colorSpacesLocal[spaceRef].toSRgb,
colorUtils.clampRgbGamut
])([d.luminanceRef, 0, 0])
),
hexRef: (d) => colorUtils.hexFromSRgb(d.sRgbRef),
luminance: (d) =>
_.flow([
colorSpacesLocal[d.space].fromSRgb,
colorSpacesLocal[d.space].to100,
(x) => x[0]
])(d.sRgbRef)
})
)
Insert cell
luminanceRef = tidy.tidy(
[],
tidy.expand({
space: Object.keys(colorSpacesLocal),
luminanceRef: [
...math
.range(0, 1, 0.1)
.toArray()
.map((x) => math.pow(x, 3)),
...math.range(1, 100, 1, true).toArray()
]
}),
tidy.mutate({
luminance: (d) =>
transitionInterpolate(transSpaceRef, (spaceRef) =>
_.flow([
colorSpacesLocal[spaceRef].from100,
colorSpacesLocal[spaceRef].toSRgb,
colorUtils.clampRgbGamut,
colorSpacesLocal[d.space].fromSRgb,
colorSpacesLocal[d.space].to100,
(x) => x[0]
])([d.luminanceRef, 0, 0])
)
})
)
Insert cell
// uses each space's luminance scale to determine color
luminanceStatic = tidy.tidy(
[],
tidy.expand({
space: Object.keys(colorSpacesLocal),
luminance: math.range(0, 100, 10, true).toArray()
}),
tidy.mutate({
sRgb: (d) =>
_.flow([
colorSpacesLocal[d.space].from100,
colorSpacesLocal[d.space].toSRgb
])([d.luminance, 0, 0]),
hex: (d) => colorUtils.hexFromSRgb(d.sRgb)
})
)
Insert cell
colorSpacesLocal.sRgb.from100([100, 0, 0])
Insert cell
// names of colorspaces, ordered
luminanceDomain = tidy
.tidy(
luminanceStatic,
tidy.mutate({
lumSRgb: (d) => _.flow(math.mean)(d.sRgb)
}),
tidy.groupBy(["space"], [tidy.summarize({ total: tidy.sum("lumSRgb") })]),
tidy.arrange("total")
)
.map((x) => x.space)
Insert cell
// add a couple "fake" color spaces here, only to make luminance comparisons
colorSpacesLocal = {
const spaces = {
...colorSpaces,
sRgb: new ColorSpace({
label: "SRGB",
fromSRgb: _.identity,
toSRgb: _.identity
}),
linearRgb: new ColorSpace({
label: "Linear RGB",
fromSRgb: colorUtils.linearRgbFromSRgb,
toSRgb: colorUtils.linearRgbToSRgb
})
};

// overwrite from/to 100 methods
spaces.sRgb.from100 = rgbFrom100;
spaces.sRgb.to100 = rgbTo100;
spaces.linearRgb.from100 = rgbFrom100;
spaces.linearRgb.to100 = rgbTo100;

return spaces;
}
Insert cell
// sorted using luminanceDomain
mapColorSpacesLocal = new Map(
[
...colorUtils
.mapColorSpaces({
colorSpaces: colorSpacesLocal
})
.entries()
].sort(
(a, b) => luminanceDomain.indexOf(a[1]) - luminanceDomain.indexOf(b[1])
)
)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// return only luminance, mean of all components
rgbTo100 = function (x) {
const L = math.mean(x) * 100;

return [L, 0, 0];
}
Insert cell
// consider only luminance, put into each component
rgbFrom100 = function (x) {
const [L, a, b] = x;
const val = L / 100;

return [val, val, val];
}
Insert cell
Insert cell
tidy = import("https://unpkg.com/@tidyjs/tidy@2.5.2/dist/es/index.js?module")
Insert cell
math = import("https://cdn.skypack.dev/mathjs@11.8.2?")
Insert cell
import {
transitionGenerator,
transitionFilter,
transitionInterpolate,
Easing
} from "@ijlyttle/transition-helper"
Insert cell
import { colorSpaces, colorUtils, ColorSpace } from "@ijlyttle/color-utilities"
Insert cell
import { changeTable } from "@ijlyttle/change-log"
Insert cell
import { inputMode, invokeMode, styleDark } from "@ijlyttle/dark-mode-input"
Insert cell
invokeMode(dark)
Insert cell
styleDark({ light: { background: "#fafafa" } })
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