diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 19dead2a01..0000000000 --- a/.eslintrc.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier"], - "plugins": ["@typescript-eslint"], - "parser": "@typescript-eslint/parser", - "env": { - "es2020": true, - "node": true, - "browser": true - }, - "rules": { - "no-cond-assign": 0, - "no-constant-condition": 0, - "no-sparse-arrays": 0, - "no-unexpected-multiline": 0, - "@typescript-eslint/no-empty-function": 0, - "@typescript-eslint/no-explicit-any": 0, - "@typescript-eslint/no-this-alias": 0, - "@typescript-eslint/no-unused-vars": ["error", {"ignoreRestSiblings": true}] - } -} diff --git a/.github/eslint.json b/.github/eslint.json deleted file mode 100644 index c280fdbd53..0000000000 --- a/.github/eslint.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "problemMatcher": [ - { - "owner": "eslint-compact", - "pattern": [ - { - "regexp": "^(.+):\\sline\\s(\\d+),\\scol\\s(\\d+),\\s(Error|Warning|Info)\\s-\\s(.+)\\s\\((.+)\\)$", - "file": 1, - "line": 2, - "column": 3, - "severity": 4, - "message": 5, - "code": 6 - } - ] - } - ] -} diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 608cfe8622..70d1136306 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 22 cache: yarn - run: yarn --frozen-lockfile - run: yarn prepublishOnly diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index a8ca29c08b..002d85321f 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -15,9 +15,9 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 22 + cache: yarn registry-url: 'https://registry.npmjs.org' - cache: 'yarn' - run: yarn --frozen-lockfile - run: yarn test - run: npm publish diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4eaaa5b855..d6ab52f70d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,14 +13,12 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 22 cache: yarn - run: yarn --frozen-lockfile - run: yarn test:mocha - run: yarn test:tsc - - run: | - echo ::add-matcher::.github/eslint.json - yarn run eslint src test --format=compact + - run: yarn test:lint - run: yarn test:prettier - run: yarn prepublishOnly - run: yarn docs:build diff --git a/CHANGELOG-2021.md b/CHANGELOG-2021.md index 3b57dc9101..f7c69507fe 100644 --- a/CHANGELOG-2021.md +++ b/CHANGELOG-2021.md @@ -1,6 +1,6 @@ # Observable Plot - Changelog [2021] -Year: [Current (2024)](./CHANGELOG.md) · [2023](./CHANGELOG-2023.md) · [2022](./CHANGELOG-2022.md) · **2021** +Year: [Current (2025)](./CHANGELOG.md) · [2024](./CHANGELOG-2024.md) · [2023](./CHANGELOG-2023.md) · [2022](./CHANGELOG-2022.md) · **2021** ## 0.3.2 diff --git a/CHANGELOG-2022.md b/CHANGELOG-2022.md index fcc2fc6e4f..c3094cd61c 100644 --- a/CHANGELOG-2022.md +++ b/CHANGELOG-2022.md @@ -1,6 +1,6 @@ # Observable Plot - Changelog [2022] -Year: [Current (2024)](./CHANGELOG.md) · [2023](./CHANGELOG-2023.md) · **2022** · [2021](./CHANGELOG-2021.md) +Year: [Current (2025)](./CHANGELOG.md) · [2024](./CHANGELOG-2024.md) · [2023](./CHANGELOG-2023.md) · **2022** · [2021](./CHANGELOG-2021.md) ## 0.6.1 diff --git a/CHANGELOG-2023.md b/CHANGELOG-2023.md index 7fc18fb69d..5ac25bfd45 100644 --- a/CHANGELOG-2023.md +++ b/CHANGELOG-2023.md @@ -1,6 +1,6 @@ # Observable Plot - Changelog [2023] -Year: [Current (2024)](./CHANGELOG.md) · **2023** · [2022](./CHANGELOG-2022.md) · [2021](./CHANGELOG-2021.md) +Year: [Current (2025)](./CHANGELOG.md) · [2024](./CHANGELOG-2024.md) · **2023** · [2022](./CHANGELOG-2022.md) · [2021](./CHANGELOG-2021.md) ## 0.6.13 @@ -233,7 +233,7 @@ Plot.bollingerY(aapl, {x: "Date", y: "Close", n: 20, k: 2}).plot() The [arrow mark](https://observablehq.com/plot/marks/arrow) supports a new **sweep** option to control the bend orientation. Below, we set this option to *-y* to draw arrows bulging right, independent of the relative vertical positions of its source and target. -[Detail of an arc diagram connecting characters in Les Misérables that appear in the same chapters.](https://observablehq.com/@observablehq/plot-arc-diagram?intent=fork) +[Detail of an arc diagram connecting characters in Les Misérables that appear in the same chapters.](https://observablehq.com/@observablehq/plot-arc-diagram) ```js Plot.plot({ diff --git a/CHANGELOG-2024.md b/CHANGELOG-2024.md new file mode 100644 index 0000000000..bb966eab27 --- /dev/null +++ b/CHANGELOG-2024.md @@ -0,0 +1,129 @@ +# Observable Plot - Changelog [2024] + +Year: [Current (2025)](./CHANGELOG.md) · **2024** · [2023](./CHANGELOG-2023.md) · [2022](./CHANGELOG-2022.md) · [2021](./CHANGELOG-2021.md) + +## 0.6.16 + +[Released August 6, 2024.](https://github.com/observablehq/plot/releases/tag/v0.6.16) + +The new [waffle mark](https://observablehq.com/plot/marks/waffle) 🧇 displays a quantity (or quantitative extent) for a given category; unlike a [bar](https://observablehq.com/plot/marks/bar), a waffle is subdivided into cells that allow easier counting, making waffles useful for reading and comparing exact quantities. Plot’s waffle mark is highly configurable: it supports stacking, positive and negative values, rounded corners, partial cells for fractional counts, automatic row or column size determination (with optional override), and more! + +[a waffle chart of Olympic athletes by weight](https://observablehq.com/plot/marks/waffle) + +```js +Plot.plot({ + fx: {interval: 10}, + color: {legend: true}, + marks: [Plot.waffleY(olympians, Plot.groupZ({y: "count"}, {fill: "sex", sort: "sex", fx: "weight", unit: 10}))] +}) +``` + +All marks now support GeoJSON data and GeoJSON property shorthand, making it easier to work with GeoJSON. For example, below the data `counties` is a GeoJSON FeatureCollection, and `unemployment` refers to a property on each feature; the **fill** option is thus shorthand for `(d) => d.properties.unemployment`. The [geo mark](https://observablehq.com/plot/marks/geo) now also supports the **tip** option (via an implicit [centroid transform](https://observablehq.com/plot/transforms/centroid)), making it easier to use Plot’s [interactive tooltips](https://observablehq.com/plot/interactions/pointer). + +[a choropleth map of unemployment by U.S. county](https://observablehq.com/plot/marks/geo) + +```js +Plot.plot({ + projection: "albers-usa", + color: { + type: "quantile", + n: 9, + scheme: "blues", + label: "Unemployment (%)", + legend: true + }, + marks: [ + Plot.geo(counties, { + fill: "unemployment", + title: (d) => `${d.properties.name} ${d.properties.unemployment}%`, + tip: true + }) + ] +}) +``` + +All marks now also support column name channel shorthand when using Apache Arrow tables as data, and we’ve added detection of Arrow date-type columns. (Arrow represents temporal data using BigInt rather than Date.) + +```js +Plot.dot(gistemp, {x: "Date", y: "Anomaly"}).plot() // gistemp is an Arrow Table! +``` + +The rect-like marks ([rect](https://observablehq.com/plot/marks/rect), [bar](https://observablehq.com/plot/marks/bar), [cell](https://observablehq.com/plot/marks/cell), and [frame](https://observablehq.com/plot/marks/frame)) now support individual rounding options for each side (**rx1**, **ry1**, *etc.*) and corner (**rx1y1**, **rx2y1**, *etc.*). This allows you to round just the top side of rects. You can even use a negative corner radius on the bottom side for seamless stacking, as in the histogram of Olympic athletes below. + +[a histogram of Olympic athletes by weight](https://observablehq.com/plot/marks/rect) + +```js +Plot.plot({ + color: {legend: true}, + marks: [ + Plot.rectY(olympians, Plot.binX({y: "count"}, {x: "weight", fill: "sex", ry2: 4, ry1: -4, clip: "frame"})), + Plot.ruleY([0]) + ] +}) +``` + +Plot now respects the projection **domain** when determining the default plot height. Previously, the map below would use a default square aspect ratio for the *conic-conformal* projection regardless of the specified **domain**, but now the map is perfectly sized to fit North Carolina. (Plot also now chooses a smarter default plot height when the ordinal *y* scale domain is empty.) + +an unlabeled map showing the outline and counties of North Carolina + +```js +Plot.plot({ + projection: {. + type: "conic-conformal", + parallels: [34 + 20 / 60, 36 + 10 / 60], + rotate: [79, 0], + domain: state + }, + marks: [ + Plot.geo(counties, {strokeOpacity: 0.2}), + Plot.geo(state) + ] +}) +``` + +The [marker options](https://observablehq.com/plot/features/markers) now render as intended on marks with varying aesthetics, such as the spiraling arrows of varying thickness and color below. + +several spiraling lines emanate from the center of the image, with rainbow color and increasing thickness, each capped with a pointed arrow at the end + +```js +Plot.plot({ + inset: 40, + axis: null, + marks: [ + Plot.line(d3.range(400), { + x: (i) => i * Math.sin(i / 100 + ((i % 5) * 2 * Math.PI) / 5), + y: (i) => i * Math.cos(i / 100 + ((i % 5) * 2 * Math.PI) / 5), + z: (i) => i % 5, + stroke: (i) => -i, + strokeWidth: (i) => i ** 1.1 / 100, + markerEnd: "arrow" + }) + ] +}) +``` + +This release includes a few more new features, bug fixes, and improvements: + +The new **className** [mark option](https://observablehq.com/plot/features/marks#mark-options) specifies an optional `class` attribute for rendered marks, allowing styling of marks via external stylesheets or easier selection via JavaScript; thanks, @RLesser! Plot now reuses `clipPath` elements, when possible, when the **clip** mark option is set to *frame* or *projection*. + +The [difference mark](https://observablehq.com/plot/marks/difference) now supports a horizontal orientation via [differenceX](https://observablehq.com/plot/marks/difference#differenceX), and the [shift transform](https://observablehq.com/plot/transforms/shift) now likewise supports [shiftY](https://observablehq.com/plot/transforms/shift#shiftY). The [Voronoi mark](https://observablehq.com/plot/marks/delaunay) is now compatible with the pointer transform: only the pointed Voronoi cell is rendered; the Voronoi mark now also renders as intended with non-exclusive facets (as when using the *exclude* facet mode). The [tip mark](https://observablehq.com/plot/marks/tip) no longer displays channels containing literal color values by default. + +## 0.6.15 + +[Released June 11, 2024.](https://github.com/observablehq/plot/releases/tag/v0.6.15) + +## 0.6.14 + +[Released March 12, 2024.](https://github.com/observablehq/plot/releases/tag/v0.6.14) + +Changes the default categorical color scheme to *Observable10*. + +The group transform now preserves the input order of groups by default, making it easier to sort groups by using the **sort** option. The group and bin transforms now support the *z* reducer. + +Improves the accessibility of axes by hidding tick marks and grid lines from the accessibility tree. + +Upgrades D3 to 7.9.0. + +--- + +For earlier changes, continue to the [2023 CHANGELOG](./CHANGELOG-2023.md). diff --git a/CHANGELOG.md b/CHANGELOG.md index 441795e696..a84f489039 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,130 +1,66 @@ # Observable Plot - Changelog -Year: **Current (2024)** · [2023](./CHANGELOG-2023.md) · [2022](./CHANGELOG-2022.md) · [2021](./CHANGELOG-2021.md) +Year: **Current (2025)** · [2024](./CHANGELOG-2024.md) · [2023](./CHANGELOG-2023.md) · [2022](./CHANGELOG-2022.md) · [2021](./CHANGELOG-2021.md) -## 0.6.16 +## 0.6.17 -[Released August 6, 2024.](https://github.com/observablehq/plot/releases/tag/v0.6.16) +[Released TDB, 2025.](https://github.com/observablehq/plot/releases/tag/v0.6.17) -The new [waffle mark](https://observablehq.com/plot/marks/waffle) 🧇 displays a quantity (or quantitative extent) for a given category; unlike a [bar](https://observablehq.com/plot/marks/bar), a waffle is subdivided into cells that allow easier counting, making waffles useful for reading and comparing exact quantities. Plot’s waffle mark is highly configurable: it supports stacking, positive and negative values, rounded corners, partial cells for fractional counts, automatic row or column size determination (with optional override), and more! +The [**clip** mark option](https://observablehq.com/plot/features/marks#clip) now supports GeoJSON objects 🌎 in addition to the named *frame* and *sphere* clipping methods, allowing the visual extent of marks to be limited to arbitrary polygons. For instance, this Voronoi mesh of world airports is clipped to land boundaries: -[a waffle chart of Olympic athletes by weight](https://observablehq.com/plot/marks/waffle) +[a map of world airports with a Voronoi mesh clipped to land](https://observablehq.com/@observablehq/plot-world-airports) ```js Plot.plot({ - fx: {interval: 10}, - color: {legend: true}, - marks: [Plot.waffleY(olympians, Plot.groupZ({y: "count"}, {fill: "sex", sort: "sex", fx: "weight", unit: 10}))] -}) -``` - - -All marks now support GeoJSON data and GeoJSON property shorthand, making it easier to work with GeoJSON. For example, below the data `counties` is a GeoJSON FeatureCollection, and `unemployment` refers to a property on each feature; the **fill** option is thus shorthand for `(d) => d.properties.unemployment`. The [geo mark](https://observablehq.com/plot/marks/geo) now also supports the **tip** option (via an implicit [centroid transform](https://observablehq.com/plot/transforms/centroid)), making it easier to use Plot’s [interactive tooltips](https://observablehq.com/plot/interactions/pointer). - -[a choropleth map of unemployment by U.S. county](https://observablehq.com/plot/marks/geo) - -```js -Plot.plot({ - projection: "albers-usa", - color: { - type: "quantile", - n: 9, - scheme: "blues", - label: "Unemployment (%)", - legend: true - }, + projection: {type: "orthographic", rotate: [110, -50]}, marks: [ - Plot.geo(counties, { - fill: "unemployment", - title: (d) => `${d.properties.name} ${d.properties.unemployment}%`, - tip: true - }) + Plot.dot(airports, {x: "longitude", y: "latitude", fill: "red", r: 1}), + Plot.voronoiMesh(airports, {x: "longitude", y: "latitude", clip: land}), + Plot.sphere(), + Plot.geo(land) ] }) ``` -All marks now also support column name channel shorthand when using Apache Arrow tables as data, and we’ve added detection of Arrow date-type columns. (Arrow represents temporal data using BigInt rather than Date.) +The GeoJSON object passed to the **clip** option is rendered as a [`clipPath` element](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/clipPath) using the same path data that a [geo mark](https://observablehq.com/plot/marks/geo) would produce, respecting the plot’s top-level **projection** option, if any. For performance, `clipPath` elements are shared by marks clipped with the same GeoJSON object. For example, the [raster mark](https://observablehq.com/plot/marks/raster) and [contour mark](https://observablehq.com/plot/marks/contour) below show atmospheric water vapor measurements across the United States from [NASA Earth Observations](https://neo.gsfc.nasa.gov/view.php?datasetId=MYDAL2_M_SKY_WV); both marks are clipped to the nation’s boundary, censoring the (absurd) values that would otherwise be interpolated between Alaska, Southern California, and Hawai’i. -```js -Plot.dot(gistemp, {x: "Date", y: "Anomaly"}).plot() // gistemp is an Arrow Table! -``` - -The rect-like marks ([rect](https://observablehq.com/plot/marks/rect), [bar](https://observablehq.com/plot/marks/bar), [cell](https://observablehq.com/plot/marks/cell), and [frame](https://observablehq.com/plot/marks/frame)) now support individual rounding options for each side (**rx1**, **ry1**, *etc.*) and corner (**rx1y1**, **rx2y1**, *etc.*). This allows you to round just the top side of rects. You can even use a negative corner radius on the bottom side for seamless stacking, as in the histogram of Olympic athletes below. - -[a histogram of Olympic athletes by weight](https://observablehq.com/plot/marks/rect) +[a map of water vapor measurements in the United States](https://observablehq.com/@observablehq/plot-us-water-vapor) ```js -Plot.plot({ - color: {legend: true}, - marks: [ - Plot.rectY(olympians, Plot.binX({y: "count"}, {x: "weight", fill: "sex", ry2: 4, ry1: -4, clip: "frame"})), - Plot.ruleY([0]) - ] -}) +Plot.raster(vapor, { + fill: Plot.identity, + width: 360, + height: 180, + x1: -180, y1: 90, x2: 180, y2: -90, + interpolate: "barycentric", + blur: 10, + clip: nation +}).plot() ``` -Plot now respects the projection **domain** when determining the default plot height. Previously, the map below would use a default square aspect ratio for the *conic-conformal* projection regardless of the specified **domain**, but now the map is perfectly sized to fit North Carolina. (Plot also now chooses a smarter default plot height when the ordinal *y* scale domain is empty.) +[The code for the map above is too long to reproduce here in its entirety; click the image above for the complete code.] -an unlabeled map showing the outline and counties of North Carolina +The **clip** mark option can also be used to clip against arbitrary polygons, not just geographic boundaries. For example, to show the value of [Math.atan2](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atan2) over the unit circle: -```js -Plot.plot({ - projection: {. - type: "conic-conformal", - parallels: [34 + 20 / 60, 36 + 10 / 60], - rotate: [79, 0], - domain: state - }, - marks: [ - Plot.geo(counties, {strokeOpacity: 0.2}), - Plot.geo(state) - ] -}) -``` - -The [marker options](https://observablehq.com/plot/features/markers) now render as intended on marks with varying aesthetics, such as the spiraling arrows of varying thickness and color below. - -several spiraling lines emanate from the center of the image, with rainbow color and increasing thickness, each capped with a pointed arrow at the end +[the value of atan2 across the unit disc, encoded as color](https://observablehq.com/@observablehq/plot-color-angle) ```js -Plot.plot({ - inset: 40, - axis: null, - marks: [ - Plot.line(d3.range(400), { - x: (i) => i * Math.sin(i / 100 + ((i % 5) * 2 * Math.PI) / 5), - y: (i) => i * Math.cos(i / 100 + ((i % 5) * 2 * Math.PI) / 5), - z: (i) => i % 5, - stroke: (i) => -i, - strokeWidth: (i) => i ** 1.1 / 100, - markerEnd: "arrow" - }) - ] -}) +Plot.raster({ + x1: -1, x2: 1, y1: -1, y2: 1, + fill: (x, y) => Math.atan2(y, x), + clip: { + type: "Polygon", + coordinates: [ + d3.range(0, 2 * Math.PI, 0.1).map((angle) => [Math.cos(angle), Math.sin(angle)]) + ] + } +}).plot({width: 300, aspectRatio: 1}) ``` -This release includes a few more new features, bug fixes, and improvements: - -The new **className** [mark option](https://observablehq.com/plot/features/marks#mark-options) specifies an optional `class` attribute for rendered marks, allowing styling of marks via external stylesheets or easier selection via JavaScript; thanks, @RLesser! Plot now reuses `clipPath` elements, when possible, when the **clip** mark option is set to *frame* or *projection*. - -The [difference mark](https://observablehq.com/plot/marks/difference) now supports a horizontal orientation via [differenceX](https://observablehq.com/plot/marks/difference#differenceX), and the [shift transform](https://observablehq.com/plot/transforms/shift) now likewise supports [shiftY](https://observablehq.com/plot/transforms/shift#shiftY). The [Voronoi mark](https://observablehq.com/plot/marks/delaunay) is now compatible with the pointer transform: only the pointed Voronoi cell is rendered; the Voronoi mark now also renders as intended with non-exclusive facets (as when using the *exclude* facet mode). The [tip mark](https://observablehq.com/plot/marks/tip) no longer displays channels containing literal color values by default. - -## 0.6.15 - -[Released June 11, 2024.](https://github.com/observablehq/plot/releases/tag/v0.6.15) - -## 0.6.14 - -[Released March 12, 2024.](https://github.com/observablehq/plot/releases/tag/v0.6.14) - -Changes the default categorical color scheme to *Observable10*. - -The group transform now preserves the input order of groups by default, making it easier to sort groups by using the **sort** option. The group and bin transforms now support the *z* reducer. - -Improves the accessibility of axes by hidding tick marks and grid lines from the accessibility tree. +The interactive **tip** associated with a [waffle mark](https://observablehq.com/plot/marks/waffle) is now anchored to the “center” of the visual representation of the associated datum. That center depends on the shape that is referenced. For fun, here’s a chart from out unit tests showing these anchoring points for various amounts of waffling. Baffling! -Upgrades D3 to 7.9.0. +waffle mark with the anchor position of each datum marked with its value --- -For earlier changes, continue to the [2023 CHANGELOG](./CHANGELOG-2023.md). +For earlier changes, continue to the [2024 CHANGELOG](./CHANGELOG-2024.md). diff --git a/LICENSE b/LICENSE index 7ad9b9653e..21be248f93 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright 2020-2023 Observable, Inc. +Copyright 2020-2025 Observable, Inc. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice diff --git a/README.md b/README.md index c9e7e78577..c23c18d037 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,18 @@ # Observable Plot -[The Observable Plot logo, spelling out the letters P-L-O-T in pastel shapes.](https://observablehq.com/plot/) +[The Observable Plot logo, spelling out the letters P-L-O-T in pastel shapes.](https://observablehq.com/plot/) [**Observable Plot**](https://observablehq.com/plot/) is a free, [open-source](./LICENSE), JavaScript library for visualizing tabular data, focused on accelerating exploratory data analysis. It has a concise, memorable, yet expressive API, featuring [scales](https://observablehq.com/plot/features/scales) and [layered marks](https://observablehq.com/plot/features/marks) in the *grammar of graphics* style. + + + + Daily downloads of Observable Plot + + + +Daily downloads of Observable Plot · [oss-analytics](https://observablehq.observablehq.cloud/oss-analytics/) + ## Documentation 📚 https://observablehq.com/plot/ diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index 2271044fca..f1a0381ac8 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -6,7 +6,7 @@ import plot from "./markdown-it-plot.js"; // https://vitepress.dev/reference/site-config // prettier-ignore export default defineConfig({ - title: "Observable Plot", + title: "Plot", description: "The JavaScript library for exploratory data visualization", appearance: "force-auto", base: "/plot/", @@ -17,6 +17,16 @@ export default defineConfig({ {find: "@observablehq/plot", replacement: path.resolve("./src/index.js")}, {find: /^.*\/VPFooter\.vue$/, replacement: fileURLToPath(new URL("./theme/CustomFooter.vue", import.meta.url))} ] + }, + define: { + __APP_VERSION__: JSON.stringify(process.env.npm_package_version) + } + }, + vue: { + template: { + compilerOptions: { + isCustomElement: (tag) => tag.startsWith("observable-") + } } }, markdown: { @@ -25,13 +35,17 @@ export default defineConfig({ } }, head: [ + ["link", {rel: "preconnect", href: "https://fonts.gstatic.com", crossorigin: ""}], + ["link", {rel: "preload", as: "style", href: "https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=Spline+Sans+Mono:ital,wght@0,300..700;1,300..700&display=swap"}], + ["link", {rel: "stylesheet", href: "https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=Spline+Sans+Mono:ital,wght@0,300..700;1,300..700&display=swap"}], ["link", {rel: "apple-touch-icon", href: "https://static.observablehq.com/favicon-512.0667824687f99c942a02e06e2db1a060911da0bf3606671676a255b1cf97b4fe.png"}], ["link", {rel: "icon", type: "image/png", href: "https://static.observablehq.com/favicon-512.0667824687f99c942a02e06e2db1a060911da0bf3606671676a255b1cf97b4fe.png", sizes: "512x512"}], ["script", {async: "", src: "https://www.googletagmanager.com/gtag/js?id=G-9B88TP6PKQ"}], - ["script", {}, "window.dataLayer=window.dataLayer||[];\nfunction gtag(){dataLayer.push(arguments);}\ngtag('js',new Date());\ngtag('config','G-9B88TP6PKQ');"] + ["script", {}, "window.dataLayer=window.dataLayer||[];\nfunction gtag(){dataLayer.push(arguments);}\ngtag('js',new Date());\ngtag('config','G-9B88TP6PKQ');"], + ["script", {async: "", defer: "", src: "https://static.observablehq.com/assets/components/observable-made-by.js"}], ], sitemap: { - hostname: 'https://observablehq.com/plot/' + hostname: "https://observablehq.com/plot/" }, themeConfig: { // https://vitepress.dev/reference/default-theme-config @@ -40,19 +54,14 @@ export default defineConfig({ light: "/observable-light.svg", dark: "/observable-dark.svg" }, - nav: [ - {text: "Home", link: "/"}, - {text: "Examples", link: "https://observablehq.com/@observablehq/plot-gallery"}, - {text: "Community", link: "/community"}, - {text: "D3", link: "https://d3js.org"} - ], sidebar: [ { text: "Introduction", items: [ {text: "What is Plot?", link: "/what-is-plot"}, {text: "Why Plot?", link: "/why-plot"}, - {text: "Getting started", link: "/getting-started"} + {text: "Getting started", link: "/getting-started"}, + {text: "Examples", link: "https://observablehq.com/@observablehq/plot-gallery"} ] }, { @@ -145,13 +154,6 @@ export default defineConfig({ search: { provider: "local" }, - socialLinks: [ - {icon: "github", link: "https://github.com/observablehq/plot"}, - {icon: "x", link: "https://twitter.com/observablehq"}, - {icon: "slack", link: "https://observablehq.com/slack/join"}, - {icon: "linkedin", link: "https://www.linkedin.com/company/observable"}, - {icon: "youtube", link: "https://www.youtube.com/c/Observablehq"} - ], footer: { message: "Library released under ISC License.", copyright: `Copyright 2020–${new Date().getUTCFullYear()} Observable, Inc.` diff --git a/docs/.vitepress/markdown-it-plot.ts b/docs/.vitepress/markdown-it-plot.ts index eb6253f421..c4f101fe89 100644 --- a/docs/.vitepress/markdown-it-plot.ts +++ b/docs/.vitepress/markdown-it-plot.ts @@ -26,7 +26,7 @@ export default function plot(md) { directives.includes("hidden") ? `
\n` : href - ? `Fork` + ? `Fork` : "" }`; if (/^Plot\.plot\(/.test(content)) { diff --git a/docs/.vitepress/theme/CustomFooter.vue b/docs/.vitepress/theme/CustomFooter.vue index 6bda2ef804..e026f21983 100644 --- a/docs/.vitepress/theme/CustomFooter.vue +++ b/docs/.vitepress/theme/CustomFooter.vue @@ -25,7 +25,6 @@
  • Plot
  • Integrations
  • Pricing
  • -
  • Enterprise
  • diff --git a/docs/.vitepress/theme/CustomLayout.vue b/docs/.vitepress/theme/CustomLayout.vue index 17511b6035..8cbd0f98d8 100644 --- a/docs/.vitepress/theme/CustomLayout.vue +++ b/docs/.vitepress/theme/CustomLayout.vue @@ -3,6 +3,7 @@ import DefaultTheme from "vitepress/theme-without-fonts"; import ExamplesGrid from "./ExamplesGrid.vue"; import ObservablePromo from "./ObservablePromo.vue"; +import VersionAndStars from "./VersionAndStars.vue"; const {Layout} = DefaultTheme; @@ -16,6 +17,12 @@ const {Layout} = DefaultTheme; + @@ -35,4 +42,19 @@ const {Layout} = DefaultTheme; background-color: rgba(37, 37, 41, 0.5); } +/* Remove unnecessary elements that are empty in our implementation */ +.VPNavBarExtra, +.VPNavBarHamburger { + display: none !important; +} + +/* rounded corners for search field */ +@media (min-width: 768px) { + .DocSearch-Button { + border-radius: 1000px; + padding-right: 0.75rem; + height: 2rem; + } +} + diff --git a/docs/.vitepress/theme/ExamplesGrid.vue b/docs/.vitepress/theme/ExamplesGrid.vue index 9b1d056cae..8074ac9d10 100644 --- a/docs/.vitepress/theme/ExamplesGrid.vue +++ b/docs/.vitepress/theme/ExamplesGrid.vue @@ -49,7 +49,7 @@ onUnmounted(() => {