clevermaps-js-sdk
v2.4.1
Published
CleverMaps js integration sdk
Downloads
346
Readme
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
- Quick start
- Installation
- API Reference
- Examples
- 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,
},
studioLinkButton: {
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.studioLinkButton
: { enabled: boolean = true }
This option lets you disable a Studio link 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 thesvg
,jpg
orpng
image. Note that host of the image url must besecure.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:
{
controls: {
menu: false
},
tools: {
measure: true,
search: true,
compare: true,
filters: true
},
infoBox: {
viewSwitch: false,
defaultExpanded: true,
share: true,
bookmark: false,
export: true,
globalFilters: 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(listener);
iframe.message.removeSetFilterListener(listener);
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(listener);
iframe.message.removeRemoveFilterListener(listener);
Examples
Instantiate sdk and render iframe
const sdk = cmSdk();
const iframe = sdk.createIframe('lmpijr4jf9sjm6b9/map/catchment_area_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('lmpijr4jf9sjm6b9/map/catchment_area_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('lmpijr4jf9sjm6b9/map/catchment_area_view', options);
sdk.renderIframe('div_a', iframe);
Handle filter events
const iframe = sdk.createIframe('lmpijr4jf9sjm6b9/map/catchment_area_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('lmpijr4jf9sjm6b9/map/catchment_area_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.4.1
Adds Studio link button fallback font and sets font weight
2.4.0
Adds Studio link button
2.3.9
Adds missing documentation functions listener parameter
2.3.8
Adds new options for hidding and disabling filters
2.3.7
Deletes visibility tool related code
2.3.6
Checks 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