SandDance/packages/sanddance-embed
Dan Marshall 19feb40922
Refactor data-inference as package (#661)
* fix vega-typings pattern, use LF

* eslint, use LF

* add data-inference package

* eslint

* bundle with rollup

* use data-inference package

* bump vega-typings

* update package-locks

* minor bump

* add mocha to eslint

* eslint

* add umd declaration

* add data-inference

* add data-inference to docs

* add data-inference ui test

* remove uitest build step

* add vega datasets

* initial build

* minor build

* build

* eslint

* add data-inference and chart-types docs

* use const

* add readme

* add chart-types docs

* add data-inference docs

* regen docs
2023-06-22 16:44:44 -07:00
..
src Vega update (#658) 2023-05-30 11:16:06 -07:00
test
.gitignore
LICENSE
README.md
package-lock.json Refactor data-inference as package (#661) 2023-06-22 16:44:44 -07:00
package.json Vega update (#658) 2023-05-30 11:16:06 -07:00
tsconfig.json

README.md

@msrvida/sanddance-embed

SandDance Embed is the easiest way to integrate SandDance into your custom app, via an <iframe> tag. SandDance Embed is a wrapper around SandDance Explorer, plus postMessage handlers to load data and manage its display from outside the iframe.

image

Development considerations

SandDance-Embed is an alternative to creating your own app wrapper around SandDance Explorer. Here are reasons you might choose one over the other:

  • SandDance Explorer will require an npm install and your own build / deployment system. You will be bound to use only compatible React versions. You will have greater control over events and injectable React sub-componentry.

  • SandDance Embed does not require an install or build system. Launch time might be slower as loads its own copy of React and other libraries at runtime. It runs in a sandbox mode which allows little customization.

Deployment scenarios

There are two ways to create a SandDance Embed iframe instance:

  1. Cross-domain
  2. In-domain

Cross-domain iframe

This is the simplest approach. Add an <iframe> tag in your HTML page:

<iframe id="embedIframe" src="https://microsoft.github.io/SandDance/embed/v4/sanddance-embed.html" style="height:700px;width:100%"></iframe>

Get a code reference to this iframe:

const embedIframe = document.getElementById('embedIframe');
embedIframe.onload = () => {
    //ready to send commands to SandDance Embed
}

Note the version number in the address to specify by major version. You may style the iframe as you see fit.

Security: The URL is hosted by the secure SandDance GitHub Pages website.

Privacy: The page does not collect any data that you pass to SandDance Embed.

In-domain iframe

In your own website you can either download a copy of the sanddance-embed.html file and use it as above, or create an iframe dynamically.

Note the static html file approach will provide better performance, by utilizing the browser's built-in caching mechanisms to load scripts.

To dynamically create a SandDance Embed iframe in JavaScript:

    const embedPromise = new Promise((resolve, reject) => {
        const embedIframe = document.createElement('iframe');
        embedIframe.style.height = '700px';
        embedIframe.style.width = '1000px'
        embedIframe.onload = () => {
            const embedScript = embedIframe.contentDocument.createElement('script');
            embedScript.src = 'https://unpkg.com/@msrvida/sanddance-embed@4/dist/umd/sanddance-embed.js';
            embedIframe.contentDocument.head.appendChild(embedScript);
            embedScript.onload = () => resolve(embedIframe);
            embedScript.onerror = reject;
        };
        document.body.appendChild(embedIframe);
    });

This promise provides you embedIframe when it is available:

    embedPromise.then((embedIframe) => {
        //ready to send commands to SandDance Embed
    });

Send commands to SandDance Embed

Use postMessage to communicate with embedIframe.contentWindow. For all command requests, see https://github.com/microsoft/SandDance/blob/master/packages/sanddance-embed/src/types/message-request.d.ts

  • Use the load command to load data and display initial chart:

    const data = [
        { x: 0, y: 0, z: 0 },
        { x: 1, y: 1, z: 1 },
        { x: 2, y: 2, z: 2 },
    ];
    embedIframe.contentWindow.postMessage({ action: 'load', data }, '*');
    

    The data variable can be an array, or a DataFile object.

    Notable optional parameters:

    • The props member, of type Explorer Props, here is shown used to specify the dark color theme, initially close the sidebar, and use the advanced renderer:
    const props = { theme: 'dark-theme', initialSidebarClosed: true, initialRenderer: { advanced: true } };
    embedIframe.contentWindow.postMessage({ action: 'load', data, props }, '*');
    

    Note that the props member is for initializing the instance of SandDance Explorer. A new dataset can be loaded with a subsequent load command, but props will be not be used.

    • The insight member, of type Insight, to specify a chart view:
    const insight = {
        chart: 'barchartH',
        columns: {
            y: 'Age',
            z: 'TicketCost',
            color: 'Class'
        },
        scheme: 'category10',
        view: '3d',
    };
    embedIframe.contentWindow.postMessage({ action: 'load', data, insight }, '*');
    
  • The getInsight command will request the current insight:

    embedIframe.contentWindow.postMessage({ action: 'getInsight' }, '*');
    
  • The theme command will get or set the theme:

    embedIframe.contentWindow.postMessage({ action: 'theme', dark: true }, '*');
    

Receive commands from SandDance Embed

Attach a listener to your own window to observe message passing:

    window.onmessage = (e) => {
        console.log('messaged', e.data);
    };

The message will contain a property request which is a clone of the requesting message object which instigated the response. Other properties vary depending on the type of request. For all command responses, see https://github.com/microsoft/SandDance/blob/master/packages/sanddance-embed/src/types/message-response.d.ts

Here is an example of the response for getInsight:

{
    "request": {
        "action": "getInsight"
    },
    "insight": {
        "colorBin": null,
        "columns": {
            "x": "x",
            "y": "y"
        },
        "facetStyle": "wrap",
        "filter": null,
        "hideAxes": false,
        "hideLegend": false,
        "signalValues": {
            "RoleZ_ProportionSignal": 0.6,
            "Text_ScaleSignal": 1.2,
            "RoleColor_BinCountSignal": 7,
            "RoleColor_ReverseSignal": false,
            "Chart_PointScaleSignal": 5,
            "RoleZ_Grounded": false
        },
        "size": {
            "height": 663,
            "width": 700
        },
        "totalStyle": null,
        "transform": null,
        "chart": "scatterplot",
        "view": "2d"
    }
}

For more information

Please visit the SandDance website.