From e13a9704ab6cf90b4da43834bf24ff9bd785b3e1 Mon Sep 17 00:00:00 2001 From: mhkeller Date: Fri, 7 Apr 2023 21:57:31 -0400 Subject: [PATCH] add plotVega function --- CHANGELOG.md | 6 ++++++ index.js | 1 + lib/showChart.js | 2 +- src/plot.js | 4 ++-- src/plotHistogram.js | 4 ++-- src/plotVega.js | 16 ++++++++++++++++ test/plotVega.test.js | 30 ++++++++++++++++++++++++++++++ test/plotVegaSpec.test.js | 29 +++++++++++++++++++++++++++++ test/vega-lite-api.test.js | 18 +++++++++--------- test/vega-lite.test.js | 18 +++++++++--------- 10 files changed, 105 insertions(+), 23 deletions(-) create mode 100644 src/plotVega.js create mode 100644 test/plotVega.test.js create mode 100644 test/plotVegaSpec.test.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 9811e0d..5a27278 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ CHANGELOG === +# 3.0.0 + +> 2023-04-07 + +Breaking change. Set `view` to `true` by default. Adds the `plotVega` export as a convenient and simpler API for plotting Vega-Lite specs and [Vega-Lite-API](https://github.com/vega/vega-lite-api) charts. + # 2.0.2 > 2023-03-25 diff --git a/index.js b/index.js index 9464774..9fb5dfb 100644 --- a/index.js +++ b/index.js @@ -1,2 +1,3 @@ export { default as plot } from './src/plot.js'; +export { default as plotVega } from './src/plotVega.js'; export { default as plotHistogram } from './src/plotHistogram.js'; diff --git a/lib/showChart.js b/lib/showChart.js index 15a0b28..2eb5cf5 100644 --- a/lib/showChart.js +++ b/lib/showChart.js @@ -6,7 +6,7 @@ import renderInBrowser from './renderInBrowser.js'; export default async function showChart( chart, - { args, library, libraryCode, now, bounds = {}, css = '', title = 'My chart', instance = 0 } = {} + { args, library, libraryCode, now, bounds = {}, css = '', title = 'Chart', instance = 0 } = {} ) { const page = await launchContextPage(bounds, instance, { title: `${title} - ${now}` }); /** diff --git a/src/plot.js b/src/plot.js index 26f95ed..d162c45 100644 --- a/src/plot.js +++ b/src/plot.js @@ -10,15 +10,15 @@ import getLibraryCode from '../utils/getLibraryCode.js'; * @param {Function|Object} [chart] An async function that returns a function that returns HTML. * @param {String} [options] Options * @param {String|String[]} [options.library] Specify what library to load to render the plot. Built-in options are `'observablehq/plot'`, `'vega-lite'` and `'plotly'`. Other strings will be interpreted as custom JavaScript to insert. This field can also be an array of strings, if you need to add multiple scripts. + * @param {Boolean} [options.view=true] If true, show the chart in a popup window. * @param {String} [options.outPath=''] A filepath to write the image. * @param {String} [options.css] Any CSS that you want injected into the page to tweak styles. - * @param {Boolean} [options.view=false] If true, show the chart in a popup window. * @param {Boolean} [options.debug] Whether to run the screenshot browser in headfull mode. */ export default async function plot( chart, args = [], - { library = 'observablehq/plot', outPath = '', view = false, css, title, debug = false } = {} + { library = 'observablehq/plot', outPath = '', view = true, css, title, debug = false } = {} ) { notify({ m: 'Generating plot...', v: outPath, d: ['magenta', 'bold'] }); diff --git a/src/plotHistogram.js b/src/plotHistogram.js index e50b834..264fe1d 100644 --- a/src/plotHistogram.js +++ b/src/plotHistogram.js @@ -16,7 +16,7 @@ import getLibraryCode from '../utils/getLibraryCode.js'; * @param {String} [options.outDir] The *directory* – not a specific file name – to write the various files out to. * @param {String} [options.fill='#000'] A hex code or field name. Defaults to `'#000'`. * @param {String} [options.css] Any CSS that you want injected into the page to tweak styles. - * @param {Boolean} [options.view=false] If true, show the chart in a popup window. + * @param {Boolean} [options.view=true] If true, show the chart in a popup window. * @param {String} [options.breakoutFields=true] For each field passed into `options.fields` write out a separate PNG. Set this to false to put everything on the same scale. * @param {String} [options.columns=true] Draw columns. If `false`, only draw lines. */ @@ -29,7 +29,7 @@ export default async function plotHistogram( outDir, fill = '#000', css, - view = false, + view = true, breakoutFields = true, columns = true, debug = false diff --git a/src/plotVega.js b/src/plotVega.js new file mode 100644 index 0000000..4752322 --- /dev/null +++ b/src/plotVega.js @@ -0,0 +1,16 @@ +import plot from './plot.js'; + +/** + * Plot Vega charts + * @param {Function|Object} [chart] A Vega-Lite-API chart or a Vega-Lite spec. + * @param {String} [options] Options + * @param {Boolean} [options.view=true] If true, show the chart in a popup window. + * @param {String} [options.outPath=''] A filepath to write the image. + * @param {String} [options.css] Any CSS that you want injected into the page to tweak styles. + * @param {Boolean} [options.debug] Whether to run the screenshot browser in headfull mode. + */ +export default async function plotVega(chart, options) { + const c = s => s; + const spec = typeof chart.toSpec === 'function' ? chart.toSpec() : chart; + await plot(c, [spec], { ...options, library: 'vega-lite', view: true }); +} diff --git a/test/plotVega.test.js b/test/plotVega.test.js new file mode 100644 index 0000000..0b3159a --- /dev/null +++ b/test/plotVega.test.js @@ -0,0 +1,30 @@ +/* eslint-disable no-undef */ +import * as vl from 'vega-lite-api'; +import plotVega from '../src/plotVega.js'; + +const data = { + values: [ + { a: 'A', b: 28 }, + { a: 'B', b: 55 }, + { a: 'C', b: 43 }, + { a: 'D', b: 91 }, + { a: 'E', b: 81 }, + { a: 'F', b: 53 }, + { a: 'G', b: 19 }, + { a: 'H', b: 87 }, + { a: 'I', b: 52 } + ] +}; + +const chart = vl + .markBar() + .description('A simple bar chart with embedded data.') + .data(data) + .encode( + vl.x().fieldO('a'), + vl.y().fieldQ('b') + ); + +await plotVega(chart, { + outPath: 'test/tmp/vega-lite-api_line-plot.png' +}); diff --git a/test/plotVegaSpec.test.js b/test/plotVegaSpec.test.js new file mode 100644 index 0000000..2ddfcb9 --- /dev/null +++ b/test/plotVegaSpec.test.js @@ -0,0 +1,29 @@ +/* eslint-disable no-undef */ +import plotVega from '../src/plotVega.js'; + +const data = { + values: [ + { a: 'A', b: 28 }, + { a: 'B', b: 55 }, + { a: 'C', b: 43 }, + { a: 'D', b: 91 }, + { a: 'E', b: 81 }, + { a: 'F', b: 53 }, + { a: 'G', b: 19 }, + { a: 'H', b: 87 }, + { a: 'I', b: 52 } + ] +}; + +const spec = { + $schema: 'https://vega.github.io/schema/vega-lite/v5.json', + description: 'A simple bar chart with embedded data.', + data, + mark: 'bar', + encoding: { + x: { field: 'a', type: 'ordinal' }, + y: { field: 'b', type: 'quantitative' } + } +}; + +await plotVega(spec); diff --git a/test/vega-lite-api.test.js b/test/vega-lite-api.test.js index bb6cb01..7c6e6fe 100644 --- a/test/vega-lite-api.test.js +++ b/test/vega-lite-api.test.js @@ -4,15 +4,15 @@ import plot from '../src/plot.js'; const dataset = { values: [ - {a: 'A', b: 28}, - {a: 'B', b: 55}, - {a: 'C', b: 43}, - {a: 'D', b: 91}, - {a: 'E', b: 81}, - {a: 'F', b: 53}, - {a: 'G', b: 19}, - {a: 'H', b: 87}, - {a: 'I', b: 52} + { a: 'A', b: 28 }, + { a: 'B', b: 55 }, + { a: 'C', b: 43 }, + { a: 'D', b: 91 }, + { a: 'E', b: 81 }, + { a: 'F', b: 53 }, + { a: 'G', b: 19 }, + { a: 'H', b: 87 }, + { a: 'I', b: 52 } ] }; diff --git a/test/vega-lite.test.js b/test/vega-lite.test.js index fdf0843..d6f321f 100644 --- a/test/vega-lite.test.js +++ b/test/vega-lite.test.js @@ -3,15 +3,15 @@ import plot from '../src/plot.js'; const dataset = { values: [ - {a: 'A', b: 28}, - {a: 'B', b: 55}, - {a: 'C', b: 43}, - {a: 'D', b: 91}, - {a: 'E', b: 81}, - {a: 'F', b: 53}, - {a: 'G', b: 19}, - {a: 'H', b: 87}, - {a: 'I', b: 52} + { a: 'A', b: 28 }, + { a: 'B', b: 55 }, + { a: 'C', b: 43 }, + { a: 'D', b: 91 }, + { a: 'E', b: 81 }, + { a: 'F', b: 53 }, + { a: 'G', b: 19 }, + { a: 'H', b: 87 }, + { a: 'I', b: 52 } ] };