Files
brk/website/scripts/options/frameworks/cointime/age-range.js
T
2026-07-29 10:50:14 +02:00

163 lines
4.1 KiB
JavaScript

import { Unit } from "../../../utils/units.js";
import { line, ROLLING_WINDOWS } from "../../series.js";
import { satsBtcUsd } from "../../shared.js";
/**
* @typedef {{
* average: Record<"_24h" | "_1w" | "_1m" | "_1y", AnySeriesPattern>,
* sum: Record<"_24h" | "_1w" | "_1m" | "_1y", AnySeriesPattern>,
* cumulative: AnySeriesPattern,
* }} CointimeAgeRangeCoindays
*
* @typedef {Object} CointimeAgeRange
* @property {string} name
* @property {Color} color
* @property {{
* coindaysCreated: CointimeAgeRangeCoindays,
* coindaysConsumed: CointimeAgeRangeCoindays,
* coindaysStored: CointimeAgeRangeCoindays,
* liveliness: AnySeriesPattern,
* vaultedness: AnySeriesPattern,
* ratio: AnySeriesPattern,
* supply: { active: AnyValuePattern, vaulted: AnyValuePattern },
* }} tree
*/
/**
* @param {readonly CointimeAgeRange[]} ranges
* @param {"liveliness" | "vaultedness" | "ratio"} key
* @param {string} name
* @param {string} legend
* @returns {PartialChartOption}
*/
function activityChart(ranges, key, name, legend) {
return {
name,
title: `${legend} by UTXO Age`,
bottom: ranges.map((range) =>
line({
series: range.tree[key],
name: range.name,
color: range.color,
unit: Unit.ratio,
}),
),
};
}
/**
* @param {readonly CointimeAgeRange[]} ranges
* @param {"active" | "vaulted"} key
* @param {string} name
* @returns {PartialChartOption}
*/
function supplyChart(ranges, key, name) {
return {
name,
title: `${name} Supply by UTXO Age`,
bottom: ranges.flatMap((range) =>
satsBtcUsd({
pattern: range.tree.supply[key],
name: range.name,
color: range.color,
}),
),
};
}
/**
* @param {readonly CointimeAgeRange[]} ranges
* @param {"coindaysCreated" | "coindaysConsumed" | "coindaysStored"} key
* @param {string} name
* @returns {PartialOptionsGroup}
*/
function coindaysTree(ranges, key, name) {
return {
name,
tree: [
{
name: "Average",
tree: ROLLING_WINDOWS.map((window) => ({
name: window.name,
title: `${window.title} Average ${name} by UTXO Age`,
bottom: ranges.map((range) =>
line({
series: range.tree[key].average[window.key],
name: range.name,
color: range.color,
unit: Unit.coindays,
}),
),
})),
},
{
name: "Sum",
tree: ROLLING_WINDOWS.map((window) => ({
name: window.name,
title: `${window.title} ${name} by UTXO Age`,
bottom: ranges.map((range) =>
line({
series: range.tree[key].sum[window.key],
name: range.name,
color: range.color,
unit: Unit.coindays,
}),
),
})),
},
{
name: "Cumulative",
title: `Cumulative ${name} by UTXO Age`,
bottom: ranges.map((range) =>
line({
series: range.tree[key].cumulative,
name: range.name,
color: range.color,
unit: Unit.coindays,
}),
),
},
],
};
}
/**
* @param {readonly CointimeAgeRange[]} ranges
* @returns {PartialOptionsGroup}
*/
export function createCointimeAgeRangeSection(ranges) {
return {
name: "Age Range",
tree: [
{
name: "Supply",
tree: [
supplyChart(ranges, "active", "Active"),
supplyChart(ranges, "vaulted", "Vaulted"),
],
},
{
name: "Activity",
tree: [
activityChart(ranges, "liveliness", "Liveliness", "Liveliness"),
activityChart(ranges, "vaultedness", "Vaultedness", "Vaultedness"),
activityChart(
ranges,
"ratio",
"Activity Ratio",
"Liveliness / Vaultedness",
),
],
},
{
name: "Coindays",
tree: [
coindaysTree(ranges, "coindaysCreated", "Coindays Created"),
coindaysTree(ranges, "coindaysConsumed", "Coindays Consumed"),
coindaysTree(ranges, "coindaysStored", "Coindays Stored"),
],
},
],
};
}