From 81457534035690b401401f7a8b66c5e5e0cc7ae0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Tue, 16 Jan 2024 16:16:47 -0800 Subject: [PATCH 01/23] adopt the new classes for plot's big numbers --- examples/plot/README.md | 2 +- examples/plot/docs/components/bigNumber.js | 36 --------------- examples/plot/docs/index.md | 51 +++++++++++++++------- 3 files changed, 36 insertions(+), 53 deletions(-) delete mode 100644 examples/plot/docs/components/bigNumber.js diff --git a/examples/plot/README.md b/examples/plot/README.md index 80f9697d5..a859a28f5 100644 --- a/examples/plot/README.md +++ b/examples/plot/README.md @@ -26,7 +26,7 @@ The [`npm-downloads.csv.ts`](./docs/data/npm-downloads.csv.ts) loader retrieves ## Big numbers -Key performance indicators are displayed as “big numbers” with, in some cases, a trend indicating growth over one week. See the components/bigNumber.js file. +Key performance indicators are displayed as “big numbers” with, in some cases, a trend indicating growth over one week. Their layout is using the convenience CSS classes _big_, _red_ etc. ## Charts diff --git a/examples/plot/docs/components/bigNumber.js b/examples/plot/docs/components/bigNumber.js deleted file mode 100644 index 621921838..000000000 --- a/examples/plot/docs/components/bigNumber.js +++ /dev/null @@ -1,36 +0,0 @@ -import * as d3 from "npm:d3"; -import {html} from "npm:htl"; - -export function BigNumber( - number, - { - href, - target = "_blank", - title, - format = ",.2~f", - trend, - trendFormat = "+.1~%", - trendColor = trend > 0 ? "green" : trend < 0 ? "red" : "orange", - trendArrow = trend > 0 ? "↗︎" : trend < 0 ? "↘︎" : "→", - trendTitle, - plot - } = {} -) { - if (typeof format !== "function") format = typeof number === "string" ? String : d3.format(format); - if (typeof trendFormat !== "function") trendFormat = d3.format(trendFormat); - const div = html`
-
${title}
-
-
${format(number)}
- ${ - trend == null - ? null - : html`
${trendFormat( - trend - )} ${trendArrow}
` - } -
- ${plot} -
`; - return href == null ? div : html`${div}`; -} diff --git a/examples/plot/docs/index.md b/examples/plot/docs/index.md index 693635137..4c8463e60 100644 --- a/examples/plot/docs/index.md +++ b/examples/plot/docs/index.md @@ -6,7 +6,6 @@ theme: dashboard # Plot ```js -import {BigNumber} from "./components/bigNumber.js"; import {DailyPlot, today, start} from "./components/dailyPlot.js"; ``` @@ -43,17 +42,25 @@ const burndown = issues ```
-
${BigNumber(versions.at(-1).version, { - title: "Current release", - href: `https://github.com/observablehq/plot/releases/tag/v${versions.at(-1).version}`, - trend: d3.utcDay.count(versions.at(-1).date, Date.now()), - trendFormat: d => `${d === 0 ? "today" : d===1 ? "yesterday" : `${d} days ago`}`, - trendColor: "#888", - trendArrow: null - })}
-
${BigNumber(stars.length, {title: "GitHub stars", trend: stars.filter((d) => d.starred_at >= lastWeek).length, trendFormat: "+", trendTitle: "Since last week"})}
-
${BigNumber(downloads[0].value, {title: "Daily npm downloads", trend: downloads[7].value ? (downloads[0].value - downloads[7].value) / downloads[7].value : undefined, trendTitle: "Compared to last week"})}
-
${BigNumber(d3.sum(downloads, (d) => d.value), {title: "Total npm downloads"})}
+ +
+

GitHub stars

+ ${html`${d3.format(",")(stars.length)}`} + ${html`${d3.format("+")(d3.sum(stars, (d) => d.starred_at >= lastWeek))} ↗︎`} +
+
+

Daily npm downloads

+ ${html`${d3.format(",")(downloads[0].value)}`} + ${((trend) => html` 0 ? "green" : trend < 0 ? "red" : "muted"}>${d3.format("+.1%")(trend)} ${trend > 0 ? "↗︎" : trend < 0 ? "↘︎" :""}`)(downloads[7].value ? (downloads[0].value - downloads[7].value) / downloads[7].value : undefined)} +
+
+

Total npm downloads

+ ${html`${d3.format(",")(d3.sum(downloads, (d) => d.value))}`}
@@ -100,10 +107,22 @@ const burndown = issues
From e611f92d610ceb857a1e785b0d02d7df0450c9a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Tue, 16 Jan 2024 16:24:55 -0800 Subject: [PATCH 02/23] fix padding and color, the hard way --- examples/plot/docs/index.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/plot/docs/index.md b/examples/plot/docs/index.md index 4c8463e60..619ec6088 100644 --- a/examples/plot/docs/index.md +++ b/examples/plot/docs/index.md @@ -106,6 +106,10 @@ const burndown = issues )}
+ + From a26fdd05cdb987105d1019fe119cd14dba41d8d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Wed, 17 Jan 2024 01:49:02 +0100 Subject: [PATCH 03/23] Update examples/plot/docs/index.md Co-authored-by: Mike Bostock --- examples/plot/docs/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/plot/docs/index.md b/examples/plot/docs/index.md index 619ec6088..8759616d5 100644 --- a/examples/plot/docs/index.md +++ b/examples/plot/docs/index.md @@ -44,7 +44,7 @@ const burndown = issues
From 54eb832fa67aa54d09c6912b7b17de9e25c4c3af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Wed, 17 Jan 2024 01:53:54 +0100 Subject: [PATCH 04/23] Update examples/plot/docs/index.md Co-authored-by: Mike Bostock --- examples/plot/docs/index.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/plot/docs/index.md b/examples/plot/docs/index.md index 8759616d5..5973c78cc 100644 --- a/examples/plot/docs/index.md +++ b/examples/plot/docs/index.md @@ -45,8 +45,9 @@ const burndown = issues

GitHub stars

From 55cf5ad776257690e436569d84a3b010893f7c1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Tue, 16 Jan 2024 16:56:12 -0800 Subject: [PATCH 05/23] quote attributes --- examples/plot/docs/index.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/examples/plot/docs/index.md b/examples/plot/docs/index.md index 5973c78cc..c069a314d 100644 --- a/examples/plot/docs/index.md +++ b/examples/plot/docs/index.md @@ -42,26 +42,26 @@ const burndown = issues ```
-
+ -
+

GitHub stars

- ${html`${d3.format(",")(stars.length)}`} - ${html`${d3.format("+")(d3.sum(stars, (d) => d.starred_at >= lastWeek))} ↗︎`} + ${html`${d3.format(",")(stars.length)}`} + ${html`${d3.format("+")(d3.sum(stars, (d) => d.starred_at >= lastWeek))} ↗︎`}
-
+

Daily npm downloads

- ${html`${d3.format(",")(downloads[0].value)}`} + ${html`${d3.format(",")(downloads[0].value)}`} ${((trend) => html` 0 ? "green" : trend < 0 ? "red" : "muted"}>${d3.format("+.1%")(trend)} ${trend > 0 ? "↗︎" : trend < 0 ? "↘︎" :""}`)(downloads[7].value ? (downloads[0].value - downloads[7].value) / downloads[7].value : undefined)}
-
+

Total npm downloads

- ${html`${d3.format(",")(d3.sum(downloads, (d) => d.value))}`} + ${html`${d3.format(",")(d3.sum(downloads, (d) => d.value))}`}
@@ -112,21 +112,21 @@ const burndown = issues
-
+

Open issues

- ${d3.format(",")(d3.sum(issues, (d) => !d.pull_request && d.state === "open"))} + ${d3.format(",")(d3.sum(issues, (d) => !d.pull_request && d.state === "open"))}
-
+

Opened issues, 28d

- ${d3.format(",")(d3.sum(issues, (d) => !d.pull_request && d.open >= lastMonth))} + ${d3.format(",")(d3.sum(issues, (d) => !d.pull_request && d.open >= lastMonth))}
-
+

Closed issues, 28d

- ${d3.format(",")(d3.sum(issues, (d) => !d.pull_request && d.close >= lastMonth))} + ${d3.format(",")(d3.sum(issues, (d) => !d.pull_request && d.close >= lastMonth))}
- From acd987c78b103b68ec65bf4328b519ccf2ceff0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Tue, 16 Jan 2024 17:06:42 -0800 Subject: [PATCH 06/23] link not muted, fix slag --- examples/plot/docs/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/plot/docs/index.md b/examples/plot/docs/index.md index c069a314d..64fd60b5e 100644 --- a/examples/plot/docs/index.md +++ b/examples/plot/docs/index.md @@ -45,8 +45,8 @@ const burndown = issues
From b30b82a34ff26645afd4d250cc7bbcf1f0e8fde9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Wed, 17 Jan 2024 02:09:23 +0100 Subject: [PATCH 07/23] Update examples/plot/docs/index.md Co-authored-by: Mike Bostock --- examples/plot/docs/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/plot/docs/index.md b/examples/plot/docs/index.md index 64fd60b5e..237dee5b1 100644 --- a/examples/plot/docs/index.md +++ b/examples/plot/docs/index.md @@ -126,7 +126,7 @@ const burndown = issues
From 8da625b138c995069f697f07360552cc5b18d2c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Tue, 16 Jan 2024 17:20:42 -0800 Subject: [PATCH 08/23] remove redundant client-side html generation --- examples/plot/docs/index.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/plot/docs/index.md b/examples/plot/docs/index.md index 237dee5b1..43ca8d0af 100644 --- a/examples/plot/docs/index.md +++ b/examples/plot/docs/index.md @@ -51,17 +51,17 @@ const burndown = issues

GitHub stars

- ${html`${d3.format(",")(stars.length)}`} - ${html`${d3.format("+")(d3.sum(stars, (d) => d.starred_at >= lastWeek))} ↗︎`} + ${d3.format(",")(stars.length)} + ${d3.format("+")(d3.sum(stars, (d) => d.starred_at >= lastWeek))} ↗︎

Daily npm downloads

- ${html`${d3.format(",")(downloads[0].value)}`} + ${d3.format(",")(downloads[0].value)} ${((trend) => html` 0 ? "green" : trend < 0 ? "red" : "muted"}>${d3.format("+.1%")(trend)} ${trend > 0 ? "↗︎" : trend < 0 ? "↘︎" :""}`)(downloads[7].value ? (downloads[0].value - downloads[7].value) / downloads[7].value : undefined)}

Total npm downloads

- ${html`${d3.format(",")(d3.sum(downloads, (d) => d.value))}`} + ${d3.format(",")(d3.sum(downloads, (d) => d.value))}
From 6537d9d3f72d6dfa85e89d5065061b25707ff162 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Tue, 16 Jan 2024 17:50:23 -0800 Subject: [PATCH 09/23] a bit of clean-up in the google-analytics example --- .../docs/components/bigNumber.js | 33 ------------ .../docs/components/dailyPlot.js | 4 +- examples/google-analytics/docs/index.md | 52 ++++++++++--------- 3 files changed, 30 insertions(+), 59 deletions(-) delete mode 100644 examples/google-analytics/docs/components/bigNumber.js diff --git a/examples/google-analytics/docs/components/bigNumber.js b/examples/google-analytics/docs/components/bigNumber.js deleted file mode 100644 index 95156515c..000000000 --- a/examples/google-analytics/docs/components/bigNumber.js +++ /dev/null @@ -1,33 +0,0 @@ -import * as d3 from "npm:d3"; -import {html} from "npm:htl"; - -export function BigNumber( - number, - { - href, - target = "_blank", - title, - format = ",.2~f", - trend, - trendFormat = "+.1~%", - trendColor = trend > 0 ? "green" : trend < 0 ? "red" : "orange", - trendArrow = trend > 0 ? "↗︎" : trend < 0 ? "↘︎" : "→", - plot - } = {} -) { - if (typeof format !== "function") format = typeof number === "string" ? String : d3.format(format); - if (typeof trendFormat !== "function") trendFormat = d3.format(trendFormat); - const div = html`
-
${title}
-
-
${format(number)}
- ${ - trend == null - ? null - : html`
${trendFormat(trend)} ${trendArrow}
` - } -
- ${plot} -
`; - return href == null ? div : html`${div}`; -} diff --git a/examples/google-analytics/docs/components/dailyPlot.js b/examples/google-analytics/docs/components/dailyPlot.js index 48d67abe5..293940c37 100644 --- a/examples/google-analytics/docs/components/dailyPlot.js +++ b/examples/google-analytics/docs/components/dailyPlot.js @@ -1,5 +1,5 @@ -import * as d3 from "npm:d3"; import * as Plot from "npm:@observablehq/plot"; +import * as d3 from "npm:d3"; export const today = d3.utcDay(d3.utcHour.offset(d3.utcHour(), -10)); export const start = d3.utcYear.offset(today, -2); @@ -16,7 +16,7 @@ export function DailyPlot(data, {title, label = title, domain, width, height = 2 y: { grid: true, domain, - label: label + label }, marks: [ Plot.axisY({ diff --git a/examples/google-analytics/docs/index.md b/examples/google-analytics/docs/index.md index a7471ba07..2e7412ad4 100644 --- a/examples/google-analytics/docs/index.md +++ b/examples/google-analytics/docs/index.md @@ -3,7 +3,6 @@ theme: dashboard --- ```js -// Data const summary = FileAttachment("data/google-analytics-summary.csv").csv({typed: true}); const hourly = FileAttachment("data/google-analytics-time-of-day.csv").csv({typed: true}); const channels = FileAttachment("data/google-analytics-channels.csv").csv({typed: true}); @@ -15,7 +14,6 @@ const world = FileAttachment("data/countries-110m.json").json(); ```js // Imports import {svg} from "npm:htl"; -import {BigNumber} from "./components/bigNumber.js"; import {Marimekko} from "./components/marimekko.js"; ``` @@ -59,7 +57,7 @@ function getCompareValue(data, metric) { function lineChart(data, {width, height, metric}) { return Plot.plot({ width, - height: 97, + height: 94, axis: null, insetTop: 10, insetLeft: -15, @@ -78,11 +76,11 @@ function lineChart(data, {width, height, metric}) { function areaChart(data, {width, height, metric}) { return Plot.plot({ width, - height: 97, + height: 94, axis: null, insetTop: 10, insetLeft: -15, - insetRight: -16.5, + insetRight: -17, marks: [ Plot.ruleY([0]), Plot.areaY(data, { @@ -276,42 +274,48 @@ function worldMap(data, {width, height, title, caption}) { } ``` - - # Google analytics _Summary of metrics from the [Google Analytics Data API](https://developers.google.com/analytics/devguides/reporting/data/v1/quickstart-client-libraries), pulled on ${date(d3.max(summary, d => d.date))}_
-
- ${resize((width) => BigNumber(`${summary[summary.length-1].active28d.toLocaleString("en-US")}`, {title: "Rolling 28-day Active users", plot: areaChart(summary, {width, metric: 'active28d'}), trend: getCompareValue(summary, 'active28d'), trendFormat: bigNumber}))} +
+

Rolling 28-day Active users

+ ${summary[summary.length-1].active28d.toLocaleString("en-US")} + ${((v) => html`${bigNumber(v)} ${v > 0 ? "↗︎" : v < 0 ? "↘︎" : ""}`)(getCompareValue(summary, 'active28d'))} + ${resize((width) => areaChart(summary, {width, metric: 'active28d'}))}
-
- ${resize((width) => BigNumber(`${bigPercent(summary[summary.length-1].engagementRate)}`, {title: "Engagement Rate", plot: lineChart(summary, {width, metric: 'engagementRate'}), trend: getCompareValue(summary, 'engagementRate'), trendFormat: percent}))} +
+

Engagement Rate

+ ${bigPercent(summary[summary.length-1].engagementRate)} + ${((v) => html`${percent(v)} ${v > 0 ? "↗︎" : v < 0 ? "↘︎" : ""}`)(getCompareValue(summary, 'engagementRate'))} + ${resize((width) => lineChart(summary, {width, metric: 'engagementRate'}))}
-
- ${resize((width) => BigNumber(`${bigPercent(summary[summary.length-1].wauPerMau)}`, {title: "WAU to MAU ratio", plot: lineChart(summary, {width, metric: 'wauPerMau'}), trend: getCompareValue(summary, 'wauPerMau'), trendFormat: percent}))} +
+

WAU to MAU ratio

+ ${bigPercent(summary[summary.length-1].wauPerMau)} + ${((v) => html`${percent(v)} ${v > 0 ? "↗︎" : v < 0 ? "↘︎" : ""}`)(getCompareValue(summary, 'wauPerMau'))} + ${resize((width) => lineChart(summary, {width, metric: 'wauPerMau'}))}
-
- ${resize((width) => BigNumber(`${summary[summary.length-1].engagedSessions.toLocaleString("en-US")}`, {title: "Engaged Sessions", plot: areaChart(summary, {width, metric: 'engagedSessions'}), trend: getCompareValue(summary, 'engagedSessions'), trendFormat: bigNumber}))} +
+

Engaged Sessions

+ ${summary[summary.length-1].engagedSessions.toLocaleString("en-US")} + ${((v) => html`${bigNumber(v)} ${v > 0 ? "↗︎" : v < 0 ? "↘︎" : ""}`)(getCompareValue(summary, 'engagedSessions'))} + ${resize((width) => areaChart(summary, {width, metric: 'engagedSessions'}))}
-
+
${resize((width, height) => horizonChart(channels, {width, height, metric:'active28d', title: 'Active users by channel', caption: 'Rolling 28-day active users', format: 's', z: 'channelGroup', color, order: color.domain.slice(1)}))}
-
+
${resize((width, height) => worldMap(countryData, {width, height, title: "Active users by country", caption: 'Current rolling 28-day active users by country', lookup: countryLookup}))}
-
- ${resize((width, height) => marrimekoChart(filteredChannelBreakdown, {width, height, metric:'active28d', title: 'New vs. returning users by channel', caption: 'Rolling 28-day active users by channel and split by new vs. returning', format: '%', yDim: 'channelGroup', xDim: 'type', color}))} +
+ ${resize((width, height) => marrimekoChart(filteredChannelBreakdown, {width, height: height - 12, metric:'active28d', title: 'New vs. returning users by channel', caption: 'Rolling 28-day active users by channel and split by new vs. returning', format: '%', yDim: 'channelGroup', xDim: 'type', color}))}
-
+
${resize((width, height) => Punchcard(hourly, {width, height, label: "active users"}))}
From d335c5ae5e951a156b13d85f08dab508fb839740 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Thu, 18 Jan 2024 16:16:07 -0800 Subject: [PATCH 10/23] add a gap class --- examples/plot/docs/index.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/plot/docs/index.md b/examples/plot/docs/index.md index 43ca8d0af..f29cd0565 100644 --- a/examples/plot/docs/index.md +++ b/examples/plot/docs/index.md @@ -41,23 +41,27 @@ const burndown = issues ); ``` + +

GitHub stars

${d3.format(",")(stars.length)} - ${d3.format("+")(d3.sum(stars, (d) => d.starred_at >= lastWeek))} ↗︎ + ${d3.format("+")(d3.sum(stars, (d) => d.starred_at >= lastWeek))} ↗︎

Daily npm downloads

${d3.format(",")(downloads[0].value)} - ${((trend) => html` 0 ? "green" : trend < 0 ? "red" : "muted"}>${d3.format("+.1%")(trend)} ${trend > 0 ? "↗︎" : trend < 0 ? "↘︎" :""}`)(downloads[7].value ? (downloads[0].value - downloads[7].value) / downloads[7].value : undefined)} + ${((trend) => html`${d3.format("+.1%")(trend)} ${trend > 0 ? "↗︎" : trend < 0 ? "↘︎" :""}`)(downloads[7].value ? (downloads[0].value - downloads[7].value) / downloads[7].value : undefined)}

Total npm downloads

@@ -107,10 +111,6 @@ const burndown = issues )}
- -

Open issues

From d15e6eb31487b0d3f3e28fc9a33041ceb64ca245 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Sun, 21 Jan 2024 22:57:03 -0800 Subject: [PATCH 11/23] fix links --- examples/plot/docs/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/plot/docs/index.md b/examples/plot/docs/index.md index f29cd0565..bf23025e5 100644 --- a/examples/plot/docs/index.md +++ b/examples/plot/docs/index.md @@ -49,7 +49,7 @@ const burndown = issues @@ -114,7 +114,7 @@ const burndown = issues

Open issues

- ${d3.format(",")(d3.sum(issues, (d) => !d.pull_request && d.state === "open"))} + ${d3.format(",")(d3.sum(issues, (d) => !d.pull_request && d.state === "open"))}

Opened issues, 28d

From 65fb83bc9666da1ab08921abd0327457a6098e8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Mon, 22 Jan 2024 09:33:28 -0800 Subject: [PATCH 12/23] remove .gap --- examples/plot/docs/index.md | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/examples/plot/docs/index.md b/examples/plot/docs/index.md index bf23025e5..f49e879b6 100644 --- a/examples/plot/docs/index.md +++ b/examples/plot/docs/index.md @@ -41,27 +41,23 @@ const burndown = issues ); ``` - -

GitHub stars

${d3.format(",")(stars.length)} - ${d3.format("+")(d3.sum(stars, (d) => d.starred_at >= lastWeek))} ↗︎ + ${d3.format("+")(d3.sum(stars, (d) => d.starred_at >= lastWeek))} ↗︎

Daily npm downloads

${d3.format(",")(downloads[0].value)} - ${((trend) => html`${d3.format("+.1%")(trend)} ${trend > 0 ? "↗︎" : trend < 0 ? "↘︎" :""}`)(downloads[7].value ? (downloads[0].value - downloads[7].value) / downloads[7].value : undefined)} + ${((trend) => html`${d3.format("+.1%")(trend)} ${trend > 0 ? "↗︎" : trend < 0 ? "↘︎" :""}`)(downloads[7].value ? (downloads[0].value - downloads[7].value) / downloads[7].value : undefined)}

Total npm downloads

From edfacf17ab854da6b59e6cabd708e3c0a691796a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Mon, 22 Jan 2024 09:36:35 -0800 Subject: [PATCH 13/23] fix indentation, close div --- examples/plot/docs/index.md | 39 +++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/examples/plot/docs/index.md b/examples/plot/docs/index.md index f49e879b6..ae7108c45 100644 --- a/examples/plot/docs/index.md +++ b/examples/plot/docs/index.md @@ -43,25 +43,26 @@ const burndown = issues
-
-

GitHub stars

- ${d3.format(",")(stars.length)} - ${d3.format("+")(d3.sum(stars, (d) => d.starred_at >= lastWeek))} ↗︎ -
-
-

Daily npm downloads

- ${d3.format(",")(downloads[0].value)} - ${((trend) => html`${d3.format("+.1%")(trend)} ${trend > 0 ? "↗︎" : trend < 0 ? "↘︎" :""}`)(downloads[7].value ? (downloads[0].value - downloads[7].value) / downloads[7].value : undefined)} -
-
-

Total npm downloads

- ${d3.format(",")(d3.sum(downloads, (d) => d.value))} +

Current release

+ ${versions.at(-1).version} + + ${((days) => days === 0 ? "today" : days === 1 ? "yesterday" : `${days} days ago`)(d3. utcDay.count(versions.at(-1).date, Date.now()))} + +
+
+

GitHub stars

+ ${d3.format(",")(stars.length)} + ${d3.format("+")(d3.sum(stars, (d) => d.starred_at >= lastWeek))} ↗︎ +
+
+

Daily npm downloads

+ ${d3.format(",")(downloads[0].value)} + ${((trend) => html`${d3. format("+.1%")(trend)} ${trend > 0 ? "↗︎" : trend < 0 ? "↘︎" :""}`)(downloads[7].value ? (downloads[0].value - downloads[7].value) / downloads[7].value : undefined)} +
+
+

Total npm downloads

+ ${d3.format(",")(d3.sum(downloads, (d) => d.value))} +
From 27e6c0178b904034c9ec18fd02b8369d3749f520 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Mon, 22 Jan 2024 09:40:10 -0800 Subject: [PATCH 14/23] trend function --- examples/plot/docs/index.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/examples/plot/docs/index.md b/examples/plot/docs/index.md index ae7108c45..36cbe0dd7 100644 --- a/examples/plot/docs/index.md +++ b/examples/plot/docs/index.md @@ -20,6 +20,9 @@ const stars = FileAttachment("data/plot-github-stars.csv").csv({typed: true}); const lastMonth = d3.utcDay.offset(today, -28); const lastWeek = d3.utcDay.offset(today, -7); const x = {domain: [start, today]}; +function trend(value, format) { + return html`${d3.format(format)(value)} ${value > 0 ? "↗︎" : value < 0 ? "↘︎" : ""}`; +} ``` ```js @@ -57,7 +60,9 @@ const burndown = issues

Daily npm downloads

${d3.format(",")(downloads[0].value)} - ${((trend) => html`${d3. format("+.1%")(trend)} ${trend > 0 ? "↗︎" : trend < 0 ? "↘︎" :""}`)(downloads[7].value ? (downloads[0].value - downloads[7].value) / downloads[7].value : undefined)} + ${trend(downloads[7].value + ? (downloads[0].value - downloads[7].value) / downloads[7].value + : undefined, d3.format("+.1%"))}

Total npm downloads

From 03920a609879bf564b0d66944c1a37399e0b7c0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Tue, 23 Jan 2024 04:26:34 +0100 Subject: [PATCH 15/23] Update examples/google-analytics/docs/index.md Co-authored-by: Mike Bostock --- examples/google-analytics/docs/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/google-analytics/docs/index.md b/examples/google-analytics/docs/index.md index 2e7412ad4..bb0a64317 100644 --- a/examples/google-analytics/docs/index.md +++ b/examples/google-analytics/docs/index.md @@ -289,7 +289,7 @@ _Summary of metrics from the [Google Analytics Data API](https://developers.goog

Engagement Rate

${bigPercent(summary[summary.length-1].engagementRate)} ${((v) => html`${percent(v)} ${v > 0 ? "↗︎" : v < 0 ? "↘︎" : ""}`)(getCompareValue(summary, 'engagementRate'))} - ${resize((width) => lineChart(summary, {width, metric: 'engagementRate'}))} + ${resize((width) => lineChart(summary, {width, metric: "engagementRate"}))}

WAU to MAU ratio

From ad9164f0e386631a65693de3b906fd150b053c7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Tue, 23 Jan 2024 04:26:44 +0100 Subject: [PATCH 16/23] Update examples/google-analytics/docs/index.md Co-authored-by: Mike Bostock --- examples/google-analytics/docs/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/google-analytics/docs/index.md b/examples/google-analytics/docs/index.md index bb0a64317..13a5f02c7 100644 --- a/examples/google-analytics/docs/index.md +++ b/examples/google-analytics/docs/index.md @@ -288,7 +288,7 @@ _Summary of metrics from the [Google Analytics Data API](https://developers.goog

Engagement Rate

${bigPercent(summary[summary.length-1].engagementRate)} - ${((v) => html`${percent(v)} ${v > 0 ? "↗︎" : v < 0 ? "↘︎" : ""}`)(getCompareValue(summary, 'engagementRate'))} + ${((v) => html`${percent(v)} ${v > 0 ? "↗︎" : v < 0 ? "↘︎" : ""}`)(getCompareValue(summary, "engagementRate"))} ${resize((width) => lineChart(summary, {width, metric: "engagementRate"}))}
From 0d9c5bc305840f37ec32ed67992285ce46ea9097 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Tue, 23 Jan 2024 04:26:54 +0100 Subject: [PATCH 17/23] Update examples/google-analytics/docs/index.md Co-authored-by: Mike Bostock --- examples/google-analytics/docs/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/google-analytics/docs/index.md b/examples/google-analytics/docs/index.md index 13a5f02c7..b82b48570 100644 --- a/examples/google-analytics/docs/index.md +++ b/examples/google-analytics/docs/index.md @@ -294,7 +294,7 @@ _Summary of metrics from the [Google Analytics Data API](https://developers.goog

WAU to MAU ratio

${bigPercent(summary[summary.length-1].wauPerMau)} - ${((v) => html`${percent(v)} ${v > 0 ? "↗︎" : v < 0 ? "↘︎" : ""}`)(getCompareValue(summary, 'wauPerMau'))} + ${((v) => html`${percent(v)} ${v > 0 ? "↗︎" : v < 0 ? "↘︎" : ""}`)(getCompareValue(summary, "wauPerMau"))} ${resize((width) => lineChart(summary, {width, metric: 'wauPerMau'}))}
From 09d3c8943cc3117b4eebfad8644df8949d4e783d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Tue, 23 Jan 2024 04:27:37 +0100 Subject: [PATCH 18/23] Update examples/google-analytics/docs/index.md Co-authored-by: Mike Bostock --- examples/google-analytics/docs/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/google-analytics/docs/index.md b/examples/google-analytics/docs/index.md index b82b48570..8cd3d5c7a 100644 --- a/examples/google-analytics/docs/index.md +++ b/examples/google-analytics/docs/index.md @@ -300,7 +300,7 @@ _Summary of metrics from the [Google Analytics Data API](https://developers.goog

Engaged Sessions

${summary[summary.length-1].engagedSessions.toLocaleString("en-US")} - ${((v) => html`${bigNumber(v)} ${v > 0 ? "↗︎" : v < 0 ? "↘︎" : ""}`)(getCompareValue(summary, 'engagedSessions'))} + ${((v) => html`${bigNumber(v)} ${v > 0 ? "↗︎" : v < 0 ? "↘︎" : ""}`)(getCompareValue(summary, "engagedSessions"))} ${resize((width) => areaChart(summary, {width, metric: 'engagedSessions'}))}
From 5f4f6c75f9b27b6ed98df5dd4e480b0239b8d0ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Tue, 23 Jan 2024 04:27:58 +0100 Subject: [PATCH 19/23] Update examples/plot/docs/index.md Co-authored-by: Mike Bostock --- examples/plot/docs/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/plot/docs/index.md b/examples/plot/docs/index.md index 36cbe0dd7..626cb4fcf 100644 --- a/examples/plot/docs/index.md +++ b/examples/plot/docs/index.md @@ -49,7 +49,7 @@ const burndown = issues

Current release

${versions.at(-1).version} - ${((days) => days === 0 ? "today" : days === 1 ? "yesterday" : `${days} days ago`)(d3. utcDay.count(versions.at(-1).date, Date.now()))} + ${((days) => days === 0 ? "today" : days === 1 ? "yesterday" : `${days} days ago`)(d3. utcDay.count(versions.at(-1).date, new Date()))}
From da252408fd9ad84ed505b5f47f37410e13d758d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Tue, 23 Jan 2024 04:28:09 +0100 Subject: [PATCH 20/23] Update examples/plot/docs/index.md Co-authored-by: Mike Bostock --- examples/plot/docs/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/plot/docs/index.md b/examples/plot/docs/index.md index 626cb4fcf..3d92b354e 100644 --- a/examples/plot/docs/index.md +++ b/examples/plot/docs/index.md @@ -55,7 +55,7 @@ const burndown = issues

GitHub stars

${d3.format(",")(stars.length)} - ${d3.format("+")(d3.sum(stars, (d) => d.starred_at >= lastWeek))} ↗︎ + ${d3.format("+")(d3.sum(stars, (d) => d.starred_at >= lastWeek))} ↗︎

Daily npm downloads

From 7860c6b983a29fc3080f1edc8eacb9f6c9912e2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Tue, 23 Jan 2024 04:28:19 +0100 Subject: [PATCH 21/23] Update examples/plot/docs/index.md Co-authored-by: Mike Bostock --- examples/plot/docs/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/plot/docs/index.md b/examples/plot/docs/index.md index 3d92b354e..7f8031020 100644 --- a/examples/plot/docs/index.md +++ b/examples/plot/docs/index.md @@ -66,7 +66,7 @@ const burndown = issues

Total npm downloads

- ${d3.format(",")(d3.sum(downloads, (d) => d.value))} + ${d3.format(",")(d3.sum(downloads, (d) => d.value))}
From 1706dc41c93e69ab2c4502b8d264dc91d34a37a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Thu, 25 Jan 2024 17:26:23 +0100 Subject: [PATCH 22/23] - trend as a (local) component - adopt toLocaleString --- .../google-analytics/docs/components/trend.js | 31 +++++++++++++++++++ examples/google-analytics/docs/index.md | 13 +++----- examples/plot/docs/components/dailyPlot.js | 2 +- examples/plot/docs/components/trend.js | 31 +++++++++++++++++++ examples/plot/docs/index.md | 22 ++++++------- 5 files changed, 78 insertions(+), 21 deletions(-) create mode 100644 examples/google-analytics/docs/components/trend.js create mode 100644 examples/plot/docs/components/trend.js diff --git a/examples/google-analytics/docs/components/trend.js b/examples/google-analytics/docs/components/trend.js new file mode 100644 index 000000000..13a0f781c --- /dev/null +++ b/examples/google-analytics/docs/components/trend.js @@ -0,0 +1,31 @@ +import * as d3 from "npm:d3"; +import {html} from "npm:htl"; + +export function trend( + value /*: number */, + { + format = "+d", + positive = "green", + negative = "red", + base = "muted", + positiveSuffix = " ↗︎", + negativeSuffix = " ↘︎", + baseSuffix = "" + } = {} /* + as { + format: string | ((x: number) => string); + positive: string; + negative: string; + base: string; + positiveSuffix: string; + negativeSuffix: string; + baseSuffix: string; + } + */ +) /*: Node */ { + if (typeof format === "string") format = d3.format(format); + if (typeof format !== "function") throw new Error(`unsupported format ${format}`); + return html`${format(value)}${ + value > 0 ? positiveSuffix : value < 0 ? negativeSuffix : baseSuffix + }`; +} diff --git a/examples/google-analytics/docs/index.md b/examples/google-analytics/docs/index.md index 8cd3d5c7a..f4450e9a5 100644 --- a/examples/google-analytics/docs/index.md +++ b/examples/google-analytics/docs/index.md @@ -12,15 +12,13 @@ const world = FileAttachment("data/countries-110m.json").json(); ``` ```js -// Imports import {svg} from "npm:htl"; import {Marimekko} from "./components/marimekko.js"; +import {trend} from "./components/trend.js"; ``` ```js -// Helpers const bigPercent = d3.format(".0%"); -const percent = d3.format(".2%"); const bigNumber = d3.format(".3s"); const date = d3.utcFormat("%m/%d/%Y"); const color = Plot.scale({ @@ -53,7 +51,6 @@ function getCompareValue(data, metric) { ``` ```js -// Charts function lineChart(data, {width, height, metric}) { return Plot.plot({ width, @@ -282,25 +279,25 @@ _Summary of metrics from the [Google Analytics Data API](https://developers.goog

Rolling 28-day Active users

${summary[summary.length-1].active28d.toLocaleString("en-US")} - ${((v) => html`${bigNumber(v)} ${v > 0 ? "↗︎" : v < 0 ? "↘︎" : ""}`)(getCompareValue(summary, 'active28d'))} + ${trend(getCompareValue(summary, 'active28d'))} ${resize((width) => areaChart(summary, {width, metric: 'active28d'}))}

Engagement Rate

${bigPercent(summary[summary.length-1].engagementRate)} - ${((v) => html`${percent(v)} ${v > 0 ? "↗︎" : v < 0 ? "↘︎" : ""}`)(getCompareValue(summary, "engagementRate"))} + ${trend(getCompareValue(summary, "engagementRate"), {format: "+.2%"})} ${resize((width) => lineChart(summary, {width, metric: "engagementRate"}))}

WAU to MAU ratio

${bigPercent(summary[summary.length-1].wauPerMau)} - ${((v) => html`${percent(v)} ${v > 0 ? "↗︎" : v < 0 ? "↘︎" : ""}`)(getCompareValue(summary, "wauPerMau"))} + ${trend(getCompareValue(summary, "wauPerMau"), {format: "+.2%"})} ${resize((width) => lineChart(summary, {width, metric: 'wauPerMau'}))}

Engaged Sessions

${summary[summary.length-1].engagedSessions.toLocaleString("en-US")} - ${((v) => html`${bigNumber(v)} ${v > 0 ? "↗︎" : v < 0 ? "↘︎" : ""}`)(getCompareValue(summary, "engagedSessions"))} + ${trend(getCompareValue(summary, 'engagedSessions'))} ${resize((width) => areaChart(summary, {width, metric: 'engagedSessions'}))}
diff --git a/examples/plot/docs/components/dailyPlot.js b/examples/plot/docs/components/dailyPlot.js index 012bd7214..0229b2059 100644 --- a/examples/plot/docs/components/dailyPlot.js +++ b/examples/plot/docs/components/dailyPlot.js @@ -1,5 +1,5 @@ -import * as d3 from "npm:d3"; import * as Plot from "npm:@observablehq/plot"; +import * as d3 from "npm:d3"; export const today = d3.utcDay(d3.utcHour.offset(d3.utcHour(), -10)); export const start = d3.utcYear.offset(today, -2); diff --git a/examples/plot/docs/components/trend.js b/examples/plot/docs/components/trend.js new file mode 100644 index 000000000..13a0f781c --- /dev/null +++ b/examples/plot/docs/components/trend.js @@ -0,0 +1,31 @@ +import * as d3 from "npm:d3"; +import {html} from "npm:htl"; + +export function trend( + value /*: number */, + { + format = "+d", + positive = "green", + negative = "red", + base = "muted", + positiveSuffix = " ↗︎", + negativeSuffix = " ↘︎", + baseSuffix = "" + } = {} /* + as { + format: string | ((x: number) => string); + positive: string; + negative: string; + base: string; + positiveSuffix: string; + negativeSuffix: string; + baseSuffix: string; + } + */ +) /*: Node */ { + if (typeof format === "string") format = d3.format(format); + if (typeof format !== "function") throw new Error(`unsupported format ${format}`); + return html`${format(value)}${ + value > 0 ? positiveSuffix : value < 0 ? negativeSuffix : baseSuffix + }`; +} diff --git a/examples/plot/docs/index.md b/examples/plot/docs/index.md index 7f8031020..0098e8092 100644 --- a/examples/plot/docs/index.md +++ b/examples/plot/docs/index.md @@ -6,6 +6,7 @@ theme: dashboard # Plot ```js +import {trend} from "./components/trend.js"; import {DailyPlot, today, start} from "./components/dailyPlot.js"; ``` @@ -20,9 +21,6 @@ const stars = FileAttachment("data/plot-github-stars.csv").csv({typed: true}); const lastMonth = d3.utcDay.offset(today, -28); const lastWeek = d3.utcDay.offset(today, -7); const x = {domain: [start, today]}; -function trend(value, format) { - return html`${d3.format(format)(value)} ${value > 0 ? "↗︎" : value < 0 ? "↘︎" : ""}`; -} ``` ```js @@ -54,19 +52,19 @@ const burndown = issues

GitHub stars

- ${d3.format(",")(stars.length)} - ${d3.format("+")(d3.sum(stars, (d) => d.starred_at >= lastWeek))} ↗︎ + ${stars.length.toLocaleString("en-US")} + ${trend(d3.sum(stars, (d) => d.starred_at >= lastWeek))}

Daily npm downloads

- ${d3.format(",")(downloads[0].value)} + ${downloads[0].value.toLocaleString("en-US")} ${trend(downloads[7].value ? (downloads[0].value - downloads[7].value) / downloads[7].value - : undefined, d3.format("+.1%"))} + : undefined, {format: "+.1%"})}

Total npm downloads

- ${d3.format(",")(d3.sum(downloads, (d) => d.value))} + ${d3.sum(downloads, (d) => d.value).toLocaleString("en-US")}
@@ -116,19 +114,19 @@ const burndown = issues

Opened issues, 28d

- ${d3.format(",")(d3.sum(issues, (d) => !d.pull_request && d.open >= lastMonth))} + ${d3.sum(issues, (d) => !d.pull_request && d.open >= lastMonth).toLocaleString("en-US")}

Closed issues, 28d

- ${d3.format(",")(d3.sum(issues, (d) => !d.pull_request && d.close >= lastMonth))} + ${d3.sum(issues, (d) => !d.pull_request && d.close >= lastMonth).toLocaleString("en-US")}
From 20ef431daf3306bf99fe72e8a1c303c32b897364 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Thu, 25 Jan 2024 18:34:56 +0100 Subject: [PATCH 23/23] small --- examples/google-analytics/docs/components/trend.js | 2 +- examples/plot/docs/components/trend.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/google-analytics/docs/components/trend.js b/examples/google-analytics/docs/components/trend.js index 13a0f781c..53ba00142 100644 --- a/examples/google-analytics/docs/components/trend.js +++ b/examples/google-analytics/docs/components/trend.js @@ -25,7 +25,7 @@ export function trend( ) /*: Node */ { if (typeof format === "string") format = d3.format(format); if (typeof format !== "function") throw new Error(`unsupported format ${format}`); - return html`${format(value)}${ + return html`${format(value)}${ value > 0 ? positiveSuffix : value < 0 ? negativeSuffix : baseSuffix }`; } diff --git a/examples/plot/docs/components/trend.js b/examples/plot/docs/components/trend.js index 13a0f781c..53ba00142 100644 --- a/examples/plot/docs/components/trend.js +++ b/examples/plot/docs/components/trend.js @@ -25,7 +25,7 @@ export function trend( ) /*: Node */ { if (typeof format === "string") format = d3.format(format); if (typeof format !== "function") throw new Error(`unsupported format ${format}`); - return html`${format(value)}${ + return html`${format(value)}${ value > 0 ? positiveSuffix : value < 0 ? negativeSuffix : baseSuffix }`; }