Skip to content

Commit

Permalink
feat: add embed option exportDataSet
Browse files Browse the repository at this point in the history
If set, this is used to populate the data when opening in Vega editor or viewing Vega source
  • Loading branch information
Callum McIntyre committed Jul 21, 2021
1 parent 552c963 commit c5ebc12
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 2 deletions.
39 changes: 37 additions & 2 deletions src/embed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export interface EmbedOptions<S = string, R = Renderers> {
timeFormatLocale?: Record<string, unknown>;
ast?: boolean;
viewClass?: typeof View;
exportDataSet?: string;
}

const NAMES: {[key in Mode]: string} = {
Expand Down Expand Up @@ -263,6 +264,36 @@ function getRoot(el: Element) {
}
}

/**
* Set the data field on a spec to the current values of the given dataset
* @param spec Specification to update
* @param dataSet Dataset to use values from
* @param view View to get the data from
* @param mode Vega mode
* @returns A copy of the spec with the expected data values
*/
function updateSpecWithDataSet(
spec: VisualizationSpec,
dataSet: string,
view: vegaImport.View,
mode: Mode
): VisualizationSpec {
const exportSpec = {...spec};

const exportSpecData = {
name: dataSet,
// We convert from JSON and back to remove the un-serialisable Symbol from view.data
values: view.data(dataSet).map((d) => JSON.parse(JSON.stringify(d))),
};
if (mode == 'vega') {
exportSpec.data = [exportSpecData];
} else if (mode == 'vega-lite') {
exportSpec.data = exportSpecData;
}

return exportSpec;
}

async function _embed(
el: HTMLElement | string,
spec: VisualizationSpec,
Expand Down Expand Up @@ -468,7 +499,9 @@ async function _embed(
viewSourceLink.text = i18n.SOURCE_ACTION;
viewSourceLink.href = '#';
viewSourceLink.addEventListener('click', function (this, e) {
viewSource(stringify(spec), opts.sourceHeader ?? '', opts.sourceFooter ?? '', mode);
const exportSpec =
opts.exportDataSet !== undefined ? updateSpecWithDataSet(spec, opts.exportDataSet, view, mode) : spec;
viewSource(stringify(exportSpec), opts.sourceHeader ?? '', opts.sourceFooter ?? '', mode);
e.preventDefault();
});

Expand Down Expand Up @@ -497,11 +530,13 @@ async function _embed(
editorLink.text = i18n.EDITOR_ACTION;
editorLink.href = '#';
editorLink.addEventListener('click', function (this, e) {
const exportSpec =
opts.exportDataSet !== undefined ? updateSpecWithDataSet(spec, opts.exportDataSet, view, mode) : spec;
post(window, editorUrl, {
config: config as Config,
mode,
renderer,
spec: stringify(spec),
spec: stringify(exportSpec),
});
e.preventDefault();
});
Expand Down
71 changes: 71 additions & 0 deletions test-changeset.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Vega-Embed for Vega-Lite</title>

<script src="https://cdn.jsdelivr.net/npm/vega@5"></script>
<script src="https://cdn.jsdelivr.net/npm/vega-lite@4"></script>
<script src="build/vega-embed.js"></script>
</head>
<body>
<h1>Template for Embedding Vega-Lite Visualization</h1>
<div id="vis"></div>

<script>
const vlSpec = {
$schema: "https://vega.github.io/schema/vega-lite/v4.json",
data: { name: "table" },
width: 400,
mark: "line",
encoding: {
x: { field: "x", type: "quantitative", scale: { zero: false } },
y: { field: "y", type: "quantitative" },
color: { field: "category", type: "nominal" },
},
};
vegaEmbed("#vis", vlSpec, { exportDataSet: "table" }).then(function (res) {
/**
* Generates a new tuple with random walk.
*/
function newGenerator() {
let counter = -1;
let previousY = [5, 5, 5, 5];
return function () {
counter++;
const newVals = previousY.map(function (v, c) {
return {
x: counter,
y: v + Math.round(Math.random() * 10 - c * 3),
category: c,
};
});
previousY = newVals.map(function (v) {
return v.y;
});
return newVals;
};
}

const valueGenerator = newGenerator();
let minimumX = -100;
let counter = 0;
const looper = window.setInterval(function () {
minimumX++;
const changeSet = vega
.changeset()
.insert(valueGenerator())
.remove(function (t) {
return t.x < minimumX;
});
res.view.change("table", changeSet).run();

if (counter++ >= 5) {
window.clearInterval(looper);
}
}, 1000);
});
</script>
</body>
</html>

0 comments on commit c5ebc12

Please sign in to comment.