clevermaps-js-sdk

2.3.7 • Public • Published

CM SDK: Embed your CleverMaps projects quickly and easily

CleverMaps SDK is a JavaScript library for embedding CleverMaps projects in a web iframe.
It lets you inject the iframe with CleverMaps project into your web page, authenticate a user on the CleverMaps platform and manage a two-way communication between web page and CleverMaps view in the iframe.

Index

  1. Quick start
  2. Installation
  3. API Reference
  4. Examples
  5. Releases and changelog

Quick start

Here is the simples way to start with sdk.
Run npm i clevermaps-js-sdk in your project folder.
Then inject the sdk js file from the node_modules folder into your static html file.

<script src="./node_modules/clevermaps-js-sdk/dist/index.js"><script>

And then instantiate the sdk:

<script>
    const sdk = cmSdk();
</script>

Installation

Run one of the command below according to the package manager you use.

npm i clevermaps-js-sdk
yarn add clevermaps-js-sdk

The SDK is written using UMD.
To import it into your ES2015 application import the default module:

import cmSdk from 'clevermaps-js-sdk';

Or require as CommonJS module:

const cmSdk = require('clevermaps-js-sdk');

API Reference

SDK Instance

cmSDK(hostUrl: string = 'https://secure.clevermaps.io/')
Returns an SDK instance.

import cmSdk from 'clevermaps-js-sdk';
// ...
const sdk = cmSdk();

Alternatively you can pass the host url:

const sdk = cmSdk('https://secure.clevermaps.io/');

Note that cmSdk() and cmSdk('https://secure.clevermaps.io/') will connect to exactly the same host, since https://secure.clevermaps.io/ is the function default host url.

SDK object contains methods for managing iframe and invoking authentication.

const {
    createIframe,
    renderIframe,
    removeIframe,
    authenticate
} = cmSdk();

sdk.createIframe(viewUrlPath: string, options: Options)
Returns an iframe instance.

const iframe = sdk.createIframe('h99r7aeqcsepjngk/map/points_overview_view', {});

Instead of h99r7aeqcsepjngk/map/points_overview_view use the right outermost part of your project view url, e.g. secure.clevermaps.io/#/h99r7aeqcsepjngk/map/points_overview_view.
SDK lets you change the behaviour, visibility or interactivity of the iframe or of its content. Here is a brief example:

const iframe = sdk.createIframe('h99r7aeqcsepjngk/map/points_overview_view', {
    componentSettings: {
        infoBox: {
            defaultExpanded: false,
        },
        tools: {
            search: false,
        }
    },
    theme: {
        colorPrimary: '#0055ff'
    },
    interactivity: {
        afterClick: false,
    },
    fullScreenButton: {
        enabled: false,
    },
});

Options

  • interactivity: { afterClick: boolean = true, text: string = 'Click to interact'}
    In default you interact with the frame only after you click into it. In a config object you can disable this behaviour, or you are able to change the description text.
  • fullScreenButton: { enabled: boolean = true, title: string = 'Display in full screen' }
    This option lets you disable a full screen button in the top right area of the iframe.
  • theme: { logoSrc: string, colorPrimary: string }
    CleverMaps platform lets you whitelabel it according to your brand.
    colorPrimary will affect all links and controls in the iframe.
    logoSrc will change the app loading logo. It requires a full url string of the svg, jpg or png image. Note that host of the image url must be secure.clevermaps.io. For more information please contact CleverMaps support.
  • componentSettings: Record<string, Record<string, boolean>>
    This option lets you hide/show some controls in the CleverMaps platform view or change its default behaviour.
    Here are all available options with default values:
{
    tools: {
        measure: true,
        search: true,
        compare: true
    },
    infoBox: {
        defaultExpanded: true,
        share: true,
        export: true
    }
}

sdk.renderIframe(containerId: string, iframeInstance: Iframe)
Injects iframe into the dom element with given id. You should pass iframeInstance returned by sdk.createIframe as a second parameter.
If dom element is not found, it will do nothing.

<main>
    <div id="frameRoot"></div>
<main>
const iframe = sdk.createIframe('h99r7aeqcsepjngk/map/points_overview_view'', {});
sdk.renderIframe('frameRoot', iframe);

will result into following dom injection:

<main>
    <div id="frameRoot">
        <iframe src="https://secure.clevermaps.io/#/h99r7aeqcsepjngk/map/points_overview_view">
            <!-- ... -->
        </iframe>
    </div>
<main>

sdk.removeIframe(containerId: string, iframeInstance: Iframe)
Remove iframe from the dom element with given id. In other words, it will do exactly vice versa as sdk.renderIframe.
You should pass iframeInstance returned by sdk.createIframe as a second parameter.
If iframe or dom element are not found, it will do nothing.

sdk.removeIframe('frameRoot', iframe);

sdk.authenticate()
Starts user authentication process

sdk.authenticate();

Iframe Instance

Iframe instance is returned by sdk.createIframe.

const {
    setState,
    message,
} = sdk.createIframe('h99r7aeqcsepjngk/map/points_overview_view', {});

The message object contains function for two-way communication between the host website and embedded iframe.

iframe.setState(viewUrlPath: string)
Immediately changes iframe view according to the url path. You should use the same url share as in sdk.createIframe

iframe.setState('h99r7aeqcsepjngk/map/points_overview_view');

iframe.message.addFilter(definitionId: string, values: Values, instanceId: string)
Adds a filter instance into the CleverMaps platform view.
definitionId is filtered dataset property or indicator link in case of indicator filter.
You can set arbitrary instanceId. The only prerequisite is uniqueness. Don't forget to store it into the variable since instanceId is a parameter of setFilter and removeFilter described below.

iframe.message.addFilter('clients.sex_name', {values: ['Male']}, 'myId0001');

You should input Values according the filter type:

type FilterValues = FilterValuesMultiSelect | FilterValuesSingleSelect | 
    FilterValuesFeature | FilterValuesHistogram | 
    FilterValuesDate | FilterValuesIndicator;


type FilterValuesMultiSelect = {
    values?: Array<string | number | null>;
}
type FilterValuesSingleSelect = {
    value?: string | number | null;
}
type FilterValuesFeature = {
    values?: Array<string | number>;
}
type FilterValuesHistogram = {
    values?: [number | null, number | null];
    nullFiltered?: boolean;
}
type FilterValuesDate = {
    startDate?: FilterDefinitionDateValue | FilterDefinitionDateFunction;
    endDate?: FilterDefinitionDateValue | FilterDefinitionDateFunction;
}
type FilterDateSimpleValues = {
    startDate: FilterDefinitionDateValue;
    endDate: FilterDefinitionDateValue;
}
type FilterDefinitionDateValue = {
    value: string;
}
type FilterValuesIndicator = {
    values?: [number | null, number | null];
    granularity?: string;
}

type FilterDefinitionDateFunction = {
    function: FilterDefinitionDateValueFunction;
}
type FilterDefinitionDateValueFunction = {
    type: FilterDefinitionDateValueFunctionType;
    value?: number;
    content?: Array<FilterDefinitionDateValueFunction>;
    options?: {
        interval?: FilterDefinitionDateUnit;
    };
}
enum FilterDefinitionDateValueFunctionType {
    Today = 'function_today',
    DateTrunc = 'function_date_trunc',
    Interval = 'function_interval',
    Minus = 'function_minus',
    Plus = 'function_plus',
    Number = 'number'
}
enum FilterDefinitionDateUnit {
    Day = 'day',
    Week = 'week',
    Month = 'month',
    Quarter = 'quarter',
    Year = 'year'
}

iframe.message.setFilter(instanceId: string, values: Values)
Sets values of already instanced filter.

const myUniqueInstanceId = 'myId0001';
iframe.message.addFilter('clients.sex_name', {values: ['Male']}, myUniqueInstanceId);
iframe.message.setFilter(myUniqueInstanceId, {values: ['Female']});

iframe.message.removeFilter(instanceId: string)
Removes filter instance from the view.

const myUniqueInstanceId = 'myId0001';
iframe.message.addFilter('clients.sex_name', {values: ['Male']}, myUniqueInstanceId);
iframe.message.removeFilter(myUniqueInstanceId);

iframe.message.resetFilter(instanceId: string)
Reset filter instance to the default state with default values.

const myUniqueInstanceId = 'myId0001';
iframe.message.addFilter('clients.sex_name', {values: ['Male']}, myUniqueInstanceId);
iframe.message.resetFilter(myUniqueInstanceId);

iframe.message.openBookmarkModal()
Opens a dialog in the frame with bookmark related options.

iframe.message.openBookmarkModal();

iframe.message.openExportModal()
Opens a dialog in the frame with list of exports.

iframe.message.openExportModal();

iframe.message.toggleFitAll()
Center the map in the view to show all filtered data.

iframe.message.toggleFitAll();

iframe.message.addAddFilterListener(listener: () => void)
iframe.message.removeAddFilterListener(listener: () => void)
Lets you add and remove a listener to a add filter event in the view.

const listener = (
    type: string, 
    params: 
        [
            instanceId: string, 
            values: Values, // see definition above
            filterDefinition: FilterDefinition
        ]
) => {
    console.log(`Filter event of type: ${type}`);
    console.log(`A filter with ${params.instanceId} instance id was added!`);
}

useEffect(() => {
    iframe.message.addAddFilterListener(listener);
    
    return () => {
        iframe.message.removeAddFilterListener(listener);
    };
});

FilterDefiniton can be of following types:

type FilterDefinition =
    FilterDefinitionMultiSelect |
    FilterDefinitionSingleSelect |
    FilterDefinitionFeature |
    FilterDefinitionHistogram |
    FilterDefinitionDate |
    FilterDefinitionGlobalDate |
    FilterDefinitionIndicator;

type FilterDefinitionMultiSelect = {
    type: FilterType.MultiSelect;
    property: string;
    orderBy?: Array<OrderBy>;
}

type FilterDefinitionSingleSelect = {
    type: FilterType.SingleSelect;
    property: string;
    orderBy?: Array<OrderBy>;
}

type FilterDefinitionFeature = {
    type: FilterType.Feature;
    dataset: string;
}

type FilterDefinitionHistogram = {
    type: FilterType.Histogram;
    property: string;
    format?: Format;
}

type FilterDefinitionDate = {
    type: FilterType.Date;
    property: string;
}

type FilterDefinitionGlobalDate = {
    type: FilterType.GlobalDate;
    property: string;
}

type FilterDefinitionIndicator = {
    type: FilterType.Indicator;
    indicator: string;
    filterSelection?: boolean;
}

iframe.message.addSetFilterListener(listener: () => void)
iframe.message.removeSetFilterListener(listener: () => void)
Lets you add and remove a listener to a set filter event in the view.

const listener = (    
    type: string, 
    params: 
        [
            instanceId: string, 
            values: Values, // see definition above
            filterDefinition: FilterDefinition
        ]
) => {
    // ...
}
iframe.message.addSetFilterListener();
iframe.message.removeSetFilterListener();

iframe.message.addRemoveFilterListener(listener: () => void)
iframe.message.removeRemoveFilterListener(listener: () => void)
Lets you add and remove a listener to a remove filter event in the view.

const listener = (    
    type: string, 
    params: 
        [
            instanceId: string, 
            filterDefinition: FilterDefinition
        ]
) => {
    // ...
}
iframe.message.addRemoveFilterListener();
iframe.message.removeRemoveFilterListener();

Examples

Instantiate sdk and render iframe

const sdk = cmSdk();
const iframe = sdk.createIframe('ra65qrdk8u9o8g69/map/ondashboard_view', {});
sdk.renderIframe('div_a', iframe);

Customize iframe interactivity

const options = {
    interactivity: {
        afterClick: true,
        text: 'Click to interact'
    },
    fullScreenButton: {
        enabled: true,
        title: 'Expand to full screen'
    },
};
const iframe = sdk.createIframe('ra65qrdk8u9o8g69/map/ondashboard_view', options);
sdk.renderIframe('div_a', iframe);

Customize view controls

const options = {
    componentSettings: {
        tools: {
            search: false,
            compare: false,
            measure: false,
        },
        infoBox: {
            defaultExpanded: false,
            share: false,
            export: false
        }
    }
};
const iframe = sdk.createIframe('ra65qrdk8u9o8g69/map/ondashboard_view', options);
sdk.renderIframe('div_a', iframe);

Handle filter events

const iframe = sdk.createIframe('ra65qrdk8u9o8g69/map/ondashboard_view', options);
sdk.renderIframe('div_a', iframe);
iframe.message.addFilter('clients.sex_name', ['Female'], 'filterId1')

const setFilter = () => iframe.message.setFilter('filterId1', ['Male']);
const resetFilter = () => iframe.message.resetFilter('filterId1');
const removeFilter = () => iframe.message.removeFilter('filterId1');

//...
<button onClick="resetFilter">Reset filter</button>
//...

Listen to filter events in useEffect hook

const iframe = sdk.createIframe('ra65qrdk8u9o8g69/map/ondashboard_view', options);
sdk.renderIframe('div_a', iframe);
const listener = (...params) => console.log(params);

useEffect(() => {
    iframe1.message.addSetFilterListener(listener);
    return () => {
        iframe1.message.removeSetFilterListener(listener);
    }
});

Releases and changelog

2.3.6

Check if iframe element and contentWindow is defined before calling postMessage

2.3.5

Adds better dom manipulation bug handling

2.3.4

Updates untrusted message warning

2.3.3

Fix callbacks firing on message from not connected frame

2.3.2

Updates readme docs

2.3.1

Bug fixes

2.3.0

Lets you whitelabel and customize the iframe and adds interactive controls to iframe

2.2.0

Adds ability to listen to view filter events

2.1.0

Adds new message functions to interact with fit all, bookmark and export modal dialog

2.0.2

Bug fixes

2.0.1

Bug fixes

2.0.0

Brings completely new api to interact with filters

1.3.1

Updates readme docs

1.3.0

Adds iframe message object with ability to interact with view filters

1.2.0

Adds ability to authenticate

1.1.0

Enhances url handling

1.0.2

Bug fixes

1.0.1

Bug fixes

1.0.0

Initial version lets to inject an iframe with CleverMaps platform view into host website

Versions

Current Tags

  • Version
    Downloads (Last 7 Days)
    • Tag
  • 2.3.7
    0
    • latest

Version History

Package Sidebar

Install

npm i clevermaps-js-sdk

Weekly Downloads

0

Version

2.3.7

License

MIT

Unpacked Size

2.76 MB

Total Files

5

Last publish

Collaborators

  • jiriclevermaps
  • ondrejvelisek
  • marekherda