Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vega lite support #2131

Merged
merged 4 commits into from
Jan 27, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions _includes/scripts/vega.liquid
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{% if page.chart and page.chart.vega_lite %}
<script
src="https://cdn.jsdelivr.net/npm/vega@5.27/build/vega.min.js"
integrity="sha256-Yot/cfgMMMpFwkp/5azR20Tfkt24PFqQ6IQS+80HIZs="
crossorigin="anonymous"
></script>
<script
src="https://cdn.jsdelivr.net/npm/vega-lite@5.16/build/vega-lite.min.js"
integrity="sha256-TvBvIS5jUN4BSy009usRjNzjI1qRrHPYv7xVLJyjUyw="
crossorigin="anonymous"
></script>
<script
src="https://cdn.jsdelivr.net/npm/vega-embed@6.24/build/vega-embed.min.js"
integrity="sha256-FPCJ9JYCC9AZSpvC/t/wHBX7ybueZhIqOMjpWqfl3DU="
crossorigin="anonymous"
></script>

<script>
let theme = localStorage.getItem('theme');

/* Create vega lite chart as another node and hide the code block, appending the vega lite node after it
this is done to enable retrieving the code again when changing theme between light/dark */
document.querySelectorAll('pre>code.language-vega_lite').forEach((elem) => {
const jsonData = elem.textContent;
const backup = elem.parentElement;
backup.classList.add('unloaded');
/* create vega lite node */
let chartElement = document.createElement('div');
chartElement.classList.add('vega-lite');
backup.after(chartElement);

/* Embed the visualization in the container */
if (theme === 'dark') {
vegaEmbed(chartElement, JSON.parse(jsonData), { theme: 'dark' });
} else {
vegaEmbed(chartElement, JSON.parse(jsonData));
}
});
</script>
{% endif %}
1 change: 1 addition & 0 deletions _layouts/default.liquid
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
{% include scripts/masonry.liquid %}
{% include scripts/mermaid.liquid %}
{% include scripts/chart.liquid %}
{% include scripts/vega.liquid %}
{% include scripts/misc.liquid %}
{% include scripts/badges.liquid %}
{% include scripts/mathjax.liquid %}
Expand Down
104 changes: 104 additions & 0 deletions _posts/2024-01-27-vega-lite.md
Original file line number Diff line number Diff line change
@@ -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://github.com/raw/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://github.com/raw/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.
3 changes: 2 additions & 1 deletion assets/js/copy_code.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ codeBlocks.forEach(function (codeBlock) {
if (
(codeBlock.querySelector("pre:not(.lineno)") || codeBlock.querySelector("code")) &&
codeBlock.querySelector("code:not(.language-chart)") &&
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");
Expand Down
17 changes: 17 additions & 0 deletions assets/js/theme.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ let setTheme = (theme) => {
if (typeof mermaid !== "undefined") {
setMermaidTheme(theme);
}
// if vegaEmbed is not defined, do nothing
if (typeof vegaEmbed !== "undefined") {
setVegaLiteTheme(theme);
}

if (theme) {
document.documentElement.setAttribute("data-theme", theme);
Expand Down Expand Up @@ -120,6 +124,19 @@ let setMermaidTheme = (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(() => {
Expand Down