From f6bb6b5dcb4411c539905522f928e2551e523034 Mon Sep 17 00:00:00 2001 From: George <31376482+george-gca@users.noreply.github.com> Date: Sat, 27 Jan 2024 11:14:02 -0300 Subject: [PATCH] Vega lite support (#2131) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added support for [vega lite](https://vega.github.io/vega-lite/) charts. ![image](https://github.com/alshedivat/al-folio/assets/31376482/789c14d3-93b6-4d3f-94a6-7cec1f0f0b59) ![image](https://github.com/alshedivat/al-folio/assets/31376482/17f9021c-08c4-4922-9f97-1046b146a965) --------- Signed-off-by: George Araújo --- _includes/scripts/vega.liquid | 40 +++++++++++++ _layouts/default.liquid | 1 + _posts/2024-01-27-vega-lite.md | 104 +++++++++++++++++++++++++++++++++ assets/js/copy_code.js | 3 +- assets/js/theme.js | 20 +++++++ 5 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 _includes/scripts/vega.liquid create mode 100644 _posts/2024-01-27-vega-lite.md diff --git a/_includes/scripts/vega.liquid b/_includes/scripts/vega.liquid new file mode 100644 index 000000000000..1e8c397c8d79 --- /dev/null +++ b/_includes/scripts/vega.liquid @@ -0,0 +1,40 @@ +{% if page.chart and page.chart.vega_lite %} + + + + + +{% endif %} diff --git a/_layouts/default.liquid b/_layouts/default.liquid index e6c46a950bc0..f961f0ee4def 100644 --- a/_layouts/default.liquid +++ b/_layouts/default.liquid @@ -51,6 +51,7 @@ {% include scripts/leaflet.liquid %} {% include scripts/chartjs.liquid %} {% include scripts/echarts.liquid %} + {% include scripts/vega.liquid %} {% include scripts/misc.liquid %} {% include scripts/badges.liquid %} {% include scripts/mathjax.liquid %} diff --git a/_posts/2024-01-27-vega-lite.md b/_posts/2024-01-27-vega-lite.md new file mode 100644 index 000000000000..e94c3deeb87d --- /dev/null +++ b/_posts/2024-01-27-vega-lite.md @@ -0,0 +1,104 @@ +--- +layout: post +title: a post with vega lite +date: 2024-01-27 00:20:00 +description: this is what included vega lite code could look like +tags: formatting charts +categories: sample-posts +chart: + vega_lite: true +--- + +This is an example post with some [vega lite](https://vega.github.io/vega-lite/) code. + +````markdown +```vega_lite +{ + "$schema": "https://vega.github.io/schema/vega-lite/v5.json", + "description": "A dot plot showing each movie in the database, and the difference from the average movie rating. The display is sorted by year to visualize everything in sequential order. The graph is for all Movies before 2019.", + "data": { + "url": "https://raw.githubusercontent.com/vega/vega/main/docs/data/movies.json" + }, + "transform": [ + {"filter": "datum['IMDB Rating'] != null"}, + {"filter": {"timeUnit": "year", "field": "Release Date", "range": [null, 2019]}}, + { + "joinaggregate": [{ + "op": "mean", + "field": "IMDB Rating", + "as": "AverageRating" + }] + }, + { + "calculate": "datum['IMDB Rating'] - datum.AverageRating", + "as": "RatingDelta" + } + ], + "mark": "point", + "encoding": { + "x": { + "field": "Release Date", + "type": "temporal" + }, + "y": { + "field": "RatingDelta", + "type": "quantitative", + "title": "Rating Delta" + }, + "color": { + "field": "RatingDelta", + "type": "quantitative", + "scale": {"domainMid": 0}, + "title": "Rating Delta" + } + } +} +``` +```` + +Which generates: + +```vega_lite +{ + "$schema": "https://vega.github.io/schema/vega-lite/v5.json", + "description": "A dot plot showing each movie in the database, and the difference from the average movie rating. The display is sorted by year to visualize everything in sequential order. The graph is for all Movies before 2019.", + "data": { + "url": "https://raw.githubusercontent.com/vega/vega/main/docs/data/movies.json" + }, + "transform": [ + {"filter": "datum['IMDB Rating'] != null"}, + {"filter": {"timeUnit": "year", "field": "Release Date", "range": [null, 2019]}}, + { + "joinaggregate": [{ + "op": "mean", + "field": "IMDB Rating", + "as": "AverageRating" + }] + }, + { + "calculate": "datum['IMDB Rating'] - datum.AverageRating", + "as": "RatingDelta" + } + ], + "mark": "point", + "encoding": { + "x": { + "field": "Release Date", + "type": "temporal" + }, + "y": { + "field": "RatingDelta", + "type": "quantitative", + "title": "Rating Delta" + }, + "color": { + "field": "RatingDelta", + "type": "quantitative", + "scale": {"domainMid": 0}, + "title": "Rating Delta" + } + } +} +``` + +This plot supports both light and dark themes. diff --git a/assets/js/copy_code.js b/assets/js/copy_code.js index 0781d8c0c86d..35dbf7e15b9d 100644 --- a/assets/js/copy_code.js +++ b/assets/js/copy_code.js @@ -6,7 +6,8 @@ codeBlocks.forEach(function (codeBlock) { codeBlock.querySelector("code:not(.language-chartjs)") && codeBlock.querySelector("code:not(.language-echarts)") && codeBlock.querySelector("code:not(.language-geojson)") && - codeBlock.querySelector("code:not(.language-mermaid)") + codeBlock.querySelector("code:not(.language-mermaid)") && + codeBlock.querySelector("code:not(.language-vega_lite)") ) { // create copy button var copyButton = document.createElement("button"); diff --git a/assets/js/theme.js b/assets/js/theme.js index 1f526248da79..8436959ad3cc 100644 --- a/assets/js/theme.js +++ b/assets/js/theme.js @@ -12,15 +12,22 @@ let setTheme = (theme) => { transTheme(); setHighlight(theme); setGiscusTheme(theme); + // if mermaid is not defined, do nothing if (typeof mermaid !== "undefined") { setMermaidTheme(theme); } + // if echarts is not defined, do nothing if (typeof echarts !== "undefined") { setEchartsTheme(theme); } + // if vegaEmbed is not defined, do nothing + if (typeof vegaEmbed !== "undefined") { + setVegaLiteTheme(theme); + } + if (theme) { document.documentElement.setAttribute("data-theme", theme); @@ -140,6 +147,19 @@ let setEchartsTheme = (theme) => { }); }; +let setVegaLiteTheme = (theme) => { + document.querySelectorAll(".vega-lite").forEach((elem) => { + // Get the code block content from previous element, since it is the vega lite code itself as defined in Markdown, but it is hidden + let jsonData = elem.previousSibling.childNodes[0].innerHTML; + elem.innerHTML = ""; + if (theme === "dark") { + vegaEmbed(elem, JSON.parse(jsonData), { theme: "dark" }); + } else { + vegaEmbed(elem, JSON.parse(jsonData)); + } + }); +}; + let transTheme = () => { document.documentElement.classList.add("transition"); window.setTimeout(() => {