a set of shared methods that can be used throughout Datawrapper
Import single functions:
import purifyHtml from '@datawrapper/shared/purifyHtml';Import entire package:
import shared from '@datawrapper/shared';
shared.purifyHtml();
shared.httpReq();- __(key, scope) ⇒
string - area(vertices) ⇒
number - arrayToObject(o) ⇒
object - autoTickFormat(column) ⇒
string - autoTickFormatDate(range, precision) ⇒
string - autoTickFormatNumber(range) ⇒
string - clone(object) ⇒
* - colorLightness(hexColor) ⇒
number - columnFormatter(column, metadata, axis) ⇒
function - columnNameToVariable(name) ⇒
string - combinations(input) ⇒
Array.<array> - dateColumnFormatter(column) ⇒
function - defaultColors(theme) ⇒
* deleteJSON(url, callback) ⇒Promise- drawPattern(parameters)
- equalish(a, b) ⇒
boolean - escapeHtml(unsafe) ⇒
string - estimateTextWidth(text, fontSize) ⇒
number fetchJSON(url, method, credentials, body, callback) ⇒Promise- findConfigPath() ⇒
String - formatNumber(value, options) ⇒
string - get(object, key, _default) ⇒
getJSON(url, credentials, callback) ⇒Promise- highlightTimer(action, delay) ⇒
object - httpReq(path, options) ⇒
Promise - initNumeralLocale(locale)
- isValidUrl(input) ⇒
boolean - kMeans(values, numCluster) ⇒
array.<Array.<number>> - loadScript(src, callback)
- loadStylesheet(src, callback)
- numberColumnFormatter(config) ⇒
function - observeFonts(fontsJSON, typographyJSON) ⇒
Promise - opts :
object patchJSON(url, body, callback) ⇒Promise- postEvent(chartId) ⇒
function postJSON(url, body, callback) ⇒Promise- purifyHTML(input, allowed) ⇒
string putJSON(url, body, callback) ⇒Promise- requireConfig() ⇒
Object - round(value, decimals) ⇒
number - set(object, key, value) ⇒
- significantDimension(values, tolerance) ⇒
number - smartRound(values, addPrecision, tolerance) ⇒
- tailLength(value) ⇒
number - toFixed(value) ⇒
string - trackEvent(category, category, category, category)
- trackPageView(loadTime)
- truncate(str, start, end) ⇒
string
translates a message key. translations are originally stored in a
Google spreadsheet that we're pulling into Datawrapper using the
scripts/update-translations script, which stores them as :locale.json
files in the /locale folders (both in core as well as inside plugin folders)
for the client-side translation to work we are also storing the translations
in the global window.dw.backend.__messages object. plugins that need
client-side translations must set "svelte": true in their plugin.json
Returns: string - -- the translated text
| Param | Type | Default | Description |
|---|---|---|---|
| key | string |
- the key to be translated, e.g. "signup / hed" | |
| scope | string |
"core" |
- the translation scope, e.g. "core" or a plugin name |
Computes the area of a polygon
Returns: number - -- polygon area, might be negative
| Param | Type | Description |
|---|---|---|
| vertices | Array.<array> |
- polygon vertices as [[x,y], [x,y], ...] array |
This function fixes an uglyness when working with PHP backends.
in PHP, there is no distiction between arrays and objects, so
PHP converts an empty object {} to a empty array [].
When this empty array then ends up in client-side JS functions which
might start to assign values to the array using arr.foo = "bar"
which results in a data structure like this:
| Param | Type | Description |
|---|---|---|
| o | array |
the input |
Example
console.log(arr);
[]
foo: "bar"
length: 0
<prototype>: Array []
console.log(arrayToObject(arr));
Object { foo: "bar" }Convenient wrapper around autoTickFormatNumber and autoTickFormatDate. Returns either a numeral.js or day.js format, depending on the column type.
Returns: string - -- a numeral|dayjs format string
| Param | Type | Description |
|---|---|---|
| column | object |
- dw.column instance that is displayed on the axis |
auto-detects a nice default axis tick format for date columns based on the input range and precision
Returns: string - - day.js compatible format string
| Param | Type | Description |
|---|---|---|
| range | array |
[min, max] of the data |
| precision | string |
the input data precision (year |
Example
import {autoTickFormatDate} from '@datawrapper/shared/autoTickFormat';
autoTickFormatDate([new Date(2000,0,1), new Date(2002,0,1)], 'quarter'); // 'YYYY|[Q]Q'auto-detects a nice default axis tick format for numeric columns based on the input range
Returns: string - - numeral.js compatible format string
| Param | Type | Description |
|---|---|---|
| range | array |
[min, max] of the data |
Example
import {autoTickFormatNumber} from '@datawrapper/shared/autoTickFormat';
autoTickFormatNumber([0,100]); // '0,0.[00]'
autoTickFormatNumber([0.2,0.7]); // '0,0.00[00]'Clones an object
Returns: * - - the cloned thing
| Param | Type | Description |
|---|---|---|
| object | * |
the thing that should be cloned |
Returns the Lab lightness value of a given hexidecimal RGB color. Uses chroma-js to convert from Hex to Lab, but only adds a few hundreds bytes to your build.
To use this function, you have to manually install chroma-js using
npm install chroma-js.
Returns: number - - the Lab lightness, between 0 (black) and 100 (white)
| Param | Type | Description |
|---|---|---|
| hexColor | string |
the RGB color as hexadecimal string, e.g. "#330066" |
Example
import colorLightness from '@datawrapper/shared/colorLightness';
colorLightness('#ff3399') // 57.9This function returns a formatting function based, given a column object, a metadata object and the axis column name.
| Param | Type | Description |
|---|---|---|
| column | object |
the date column object |
| metadata | object |
the full metadata object |
| axis | string |
the column name of the axis |
converts a column name to a variable name that can be used in the custom column editor. variable names can't contain spaces and special characters and are also converted to lowercase.
Returns: string - -- variable name
| Param | Type | Description |
|---|---|---|
| name | string |
- name of the column |
Example
import columnNameToVariable from '@datawrapper/shared/columnNameToVariable';
columnNameToVariable('GDP (per cap.)') // gdp_per_capcomputes all combinations of input elements
Returns: Array.<array> - -- array of combinations
| Param | Type | Description |
|---|---|---|
| input | Array.<array> |
- array of input objects, could be numbers, strings, etc |
Example
// returns [['a','b'], ['a'], ['b']]
combinations(['a', 'b']);Example
// returns [[1,2,3], [1,2], [1,3], [1], [2,3], [2], [3]]
combinations([1,2,3])This function returns a date formatting function based on a dw column object. The implementation is backwards-compatible with our old Globalize-based date formatting, but uses dayjs under the hood.
| Param | Type | Description |
|---|---|---|
| column | object |
the date column object |
defines colors for the various chart elements like axis text, gridlines, bar background etc. based on the theme background color, and some other optional theme parameters
Returns: * - -- object with color definitions
| Param | Type | Description |
|---|---|---|
| theme | * |
- theme data for a chart |
Example
// returns {"tickText":{"secondary":"#9d9d9d","primary":"#d9d9d9"},"series":"#f1f1f1","value":"#d9d9d9","axis":"#f1f1f1","gridline":"#707070","fallbackBaseColor":"#f1f1f1"}
defaultColors({"colors": {"background": "#333333"}});Example
// returns {"tickText":{"secondary":"#ffffff","primary":"#ffffff"},"series":"#ffffff","value":"#fef2e4","axis":"#ffffff","gridline":"#fedeb5","fallbackBaseColor":"#ffffff"}
defaultColors({"colors": {"bgBlendRatios": {"gridline": 0.5,"tickText": {"primary": 0,"secondary": 0}},"chartContentBaseColor": "#ffffff","background": "#FCB716"}});Deprecated
Download and parse a remote JSON endpoint via DELETE. credentials are included automatically Use httpReq or delete instead.
| Param | Type |
|---|---|
| url | string |
| callback | function |
Example
import { deleteJSON } from '@datawrapper/shared/fetch';
deleteJSON('http://api.example.org/chart/123').then(() => {
console.log('deleted!')
});draws a configurable pattern into an svg pattern def, so that it can be used as a fill
| Param | Type | Description |
|---|---|---|
| parameters | * |
- style parameters for the pattern |
returns true if two numeric values are close enough
| Param | Type |
|---|---|
| a | number |
| b | number |
Example
// returns true
equalish(0.333333, 1/3)Example
// returns false
equalish(0.333, 1/3)returns escaped HTML that can be used to display untrusted content
| Param | Type |
|---|---|
| unsafe | string |
returns the estimated width of a given text in Roboto. this method has proven to be a good compromise between pixel-perfect but expensive text measuring methods using canvas or getClientBoundingRect and just multiplying the number of characters with a fixed width.
be warned that this is just a rough estimate of the text width. the character widths will vary from typeface to typeface and may be off quite a bit for some fonts (like monospace fonts).
| Param | Type | Description |
|---|---|---|
| text | string |
the text to measure |
| fontSize | number |
the output font size (optional, default is 14) |
Example
import estimateTextWidth from '@datawrapper/shared/estimateTextWidth';
// or import {estimateTextWidth} from '@datawrapper/shared';
const width = estimateTextWidth('my text', 12);Deprecated
Download and parse a remote JSON document. Use httpReq instead
| Param | Type | Description |
|---|---|---|
| url | string |
|
| method | string |
HTTP method, either GET, POST or PUT |
| credentials | string | undefined |
set to "include" if cookies should be passed along CORS requests |
| body | string |
|
| callback | function |
Example
import { fetchJSON } from '@datawrapper/shared/fetch';
fetchJSON('http://api.example.org', 'GET', 'include');Function to find a Datawrapper config file (config.js).
It looks in the current working directory and in /etc/datawrapper/.
If no config is found, the process will exit with a non zero exit code.
It is possible to overwrite the config path with the env variable DW_CONFIG_PATH.
Useful for tests!
This is a Node module, that will probably not work in a browser environment.
Example
const { findConfigPath } = require('@datawrapper/shared/node/findConfig')
const path = findConfigPath()
// -> /etc/datawrapper/config.jsspecial number formatting that can deal with microtypography and "prepend currencies" (e.g., −$1234.57)
Use initNumeralLocale to set a custom locale.
Returns: string - - the formatted number
| Param | Type | Description |
|---|---|---|
| value | number |
the number to format |
| options | object |
options, see below |
| options.format | string |
numeral.js compatible number format |
| options.prepend | string |
string to prepend to number |
| options.append | string |
string to append to number |
| options.minusChar | string |
custom character to use for minus |
| options.multiply | number |
multiply number before applying format |
Example
// returns '1234.57'
formatNumber(1234.567)Example
// returns '−$1234.57'
formatNumber(-1234.567, { prepend: '$' })Safely access object properties without throwing nasty
cannot access X of undefined errors if a property along the
way doesn't exist.
Returns: the value
| Param | Type | Description |
|---|---|---|
| object | the object which properties you want to acccess | |
| key | String | Array.<String> |
path to the property as a dot-separated string or array of strings |
| _default | * |
the fallback value to be returned if key doesn't exist |
Example
import get from '@datawrapper/shared/get';
const someObject = { key: { list: ['a', 'b', 'c']}};
get(someObject, 'key.list[2]') // returns 'c'
get(someObject, 'missing.key') // returns undefined
get(someObject, 'missing.key', false) // returns falseDeprecated
Download and parse a JSON document via GET. Use httpReq or get instead.
| Param | Type | Description |
|---|---|---|
| url | string |
|
| credentials | string | undefined |
optional, set to undefined to disable credentials |
| callback | function |
Example
import { getJSON } from '@datawrapper/shared/fetch';
// use it callback style
getJSON('http://api.example.org', 'include', function(data) {
console.log(data);
});
// or promise-style
getJSON('http://api.example.org')
.then(data => {
console.log(data);
});A delayed highlight setter
| Param | Type | Description |
|---|---|---|
| action | function |
the highlight action callback |
| delay | int |
how long something needs to be highlighted before the highlight triggers (in milliseconds) |
Example
import {highlightTimer} from '@datawrapper/shared';
const myTimer = highlightTimer(value => {
if (value) {
selection.style('opacity', d => d === value ? 1 : 0.3);
} else {
selection.style('opacity', 1);
}
});
lines.on('mouseenter', d => myTimer.set(d));
chart.on('mouseleave', myTimer.clear);The response body is automatically parsed according to the response content type.
Returns: Promise - promise of parsed response body or raw response
| Param | Type | Description |
|---|---|---|
| path | string |
the url path that gets appended to baseUrl |
| options.body | object |
raw body to be send with req |
| options.payload | object |
raw JSON payload to be send with req (will overwrite options.body) |
| options.raw | boolean |
disable parsing of response body, returns raw response |
| options.baseUrl | string |
base for url, defaults to dw api domain |
| options | * |
see documentation for window.fetch for additional options |
Example
import httpReq from '@datawrapper/shared/httpReq';
let res = await httpReq('/v3/charts', {
method: 'post',
payload: {
title: 'My new chart'
}
});
import { post } from '@datawrapper/shared/httpReq';
res = await post('/v3/charts', {
payload: {
title: 'My new chart'
}
});
// send raw csv
await httpReq.put(`/v3/charts/${chartId}/data`, {
body: csvData,
headers: {
'Content-Type': 'text/csv'
}
});Like httpReq but with fixed http method DELETE
See: httpReq
Like httpReq but with fixed http method GET
See: httpReq
Like httpReq but with fixed http method HEAD
See: httpReq
Like httpReq but with fixed http method PATCH
See: httpReq
Like httpReq but with fixed http method POST
See: httpReq
Like httpReq but with fixed http method PUT
See: httpReq
in order to use formatValue with custom locales
and to avoid version conflicts with numeral, this method
allows setting a locale.
| Param | Type |
|---|---|
| locale | object |
checks if a given string is a valid URL
| Param | Type |
|---|---|
| input | string |
Performs one-dimensional k-means clustering on an array of numbers. Useful for finding n groups of "similar values".
Returns: array.<Array.<number>> - - array of clusters
| Param | Type | Description |
|---|---|---|
| values | Array.<number> |
sorted array of numbers |
| numCluster | number |
the desired cluster count |
Example
import kMeans from '@datawrapper/shared/kMeans';
const values = [1, 1.1, 1.2, 2.1, 3, 3.1, 3.2, 3.3, 7, 7.1, 10];
// returns [[1, 1.1, 1.2, 2.1], [3, 3.1, 3.2, 3.3], [7, 7.1, 10]]
kMeans(values, 3)injects a <script> element to the page to load a new JS script
| Param | Type |
|---|---|
| src | string |
| callback | function |
Example
import { loadScript } from '@datawrapper/shared/fetch';
loadScript('/static/js/library.js', () => {
console.log('library is loaded');
})injects a <link> element to the page to load a new stylesheet
| Param | Type |
|---|---|
| src | string | opts |
| callback | function |
Example
import { loadStylesheet } from '@datawrapper/shared/fetch';
loadStylesheet('/static/css/library.css', () => {
console.log('library styles are loaded');
})This function returns a number formatting function based on a column configuration object stored in metadata.data.column-format. The implementation is backwards-compatible with our old Globalize-based number formatting, but uses numeral under the hood.
| Param | Type | Description |
|---|---|---|
| config | object |
the column configuration from metadata |
Function that returns a promise, that resolves when all fonts, specified in fontsJSON and typographyJSON have been loaded.
| Param | Type |
|---|---|
| fontsJSON | Object | Array |
| typographyJSON | Object |
Properties
| Name | Type | Description |
|---|---|---|
| src | string |
stylesheet URL to load |
| parentElement | DOMElement |
DOM element to append style tag to |
Deprecated
| Param | Type |
|---|---|
| url | string |
| body | string |
| callback | function |
Example
import { patchJSON } from '@datawrapper/shared/fetch';
patchJSON('http://api.example.org', JSON.stringify({
query: 'foo',
page: 12
}));Use this function to post event messages out of Datawrapper iframe embeds to the parent website.
| Param | Type | Description |
|---|---|---|
| chartId | string |
the chart id each message should be signed with |
Example
import genPostEvent from '@datawrapper/shared/postEvent';
const postEvent = genPostEvent(chart.get('id'));
postEvent('bar:hover', {value: 123});Deprecated
Download and parse a remote JSON endpoint via POST. credentials are included automatically. Use httpReq or post instead.
| Param | Type |
|---|---|
| url | string |
| body | string |
| callback | function |
Example
import { postJSON } from '@datawrapper/shared/fetch';
postJSON('http://api.example.org', JSON.stringify({
query: 'foo',
page: 12
}));Remove all non-whitelisted html tags from the given string
Returns: string - - the cleaned html output
| Param | Type | Description |
|---|---|---|
| input | string |
dirty html input |
| allowed | string |
list of allowed tags, defaults to <a><b><br><br/><i><strong><sup><sub><strike><u><em><tt> |
Deprecated
Download and parse a remote JSON endpoint via PUT. credentials are included automatically Use httpReq or put instead.
| Param | Type |
|---|---|
| url | string |
| body | string |
| callback | function |
Example
import { putJSON } from '@datawrapper/shared/fetch';
putJSON('http://api.example.org', JSON.stringify({
query: 'foo',
page: 12
}));Tiny wrapper around findConfigPath that directly requires the found config.
Example
const { requireConfig } = require('@datawrapper/shared/node/findConfig')
const config = requireConfig()rounds a value to a certain number of decimals
Returns: number - - rounded value
| Param | Type | Description |
|---|---|---|
| value | number |
the value to be rounded |
| decimals | number |
the number of decimals |
Example
import round from '@datawrapper/shared/round';
round(1.2345); // 1
round(1.2345, 2); // 1.23
round(12345, -2); // 12300safely set object properties without throwing nasty
cannot access X of undefined errors if a property along the
way doesn't exist.
Returns: the value
| Param | Type | Description |
|---|---|---|
| object | the object which properties you want to acccess | |
| key | String | Array.<String> |
path to the property as a dot-separated string or array of strings |
| value | * |
the value to be set |
computes the significant dimension for a list of numbers That's the number of decimals to which we can round the numbers without loosing information
Returns: number - - number of significant dimensions (= the number of decimals)
| Param | Type | Description |
|---|---|---|
| values | Array.<number> |
list of input numbers |
| tolerance | number |
percent of input values that we allow to "collide" |
Example
import {significantDimension} from '@datawrapper/shared/significantDimension';
significantDimension([0,10,20,30]); // -1rounds an array of numbers to the least number of decimals without loosing any information due to the rounding
Returns: the rounded values
| Param | Type | Description |
|---|---|---|
| values | array |
the numbers to be rounded |
| addPrecision | number |
force more precision (=numbers of decimals) to the rounding |
| tolerance | number |
the percent of uniq input values that we can tolerate to lose after rounding |
Example
import {smartRound} from '@datawrapper/shared/smartRound';
smartRound([9, 10.5714, 12.1428, 13.7142]); // [9, 11, 12, 14]
smartRound([9, 10.5714, 12.1428, 12.4142]); // [9, 10.6, 12.1, 12.4]returns the length of the "tail" of a number, meaning the number of meaningful decimal places
| Param | Type |
|---|---|
| value | number |
Example
// returns 3
tailLength(3.123)Example
// returns 2
tailLength(3.12999999)Automatically converts a numeric value to a string. this is better than the default number to string conversion in JS which sometimes produces ugly strings like "3.999999998"
| Param | Type |
|---|---|
| value | number |
Example
import toFixed from '@datawrapper/shared/toFixed';
// returns '3.1'
toFixed(3.100001)tracks a custom event in Matomo
| Param | Type | Description |
|---|---|---|
| category | string |
the event category |
| category | string |
the event action |
| category | string |
the event name |
| category | string | number |
the event value, optional |
tracks a custom page view in Matomo. Useful for single page apps in Datawrapper, such as the locator maps UI. The page title and URL are automatically detected using the window object.
| Param | Type | Description |
|---|---|---|
| loadTime | number |
optional page load time, has to be measured manually |
Shorten a string by removing characters from the middle
| Param | Type | Description |
|---|---|---|
| str | string |
|
| start | number |
characters to keep at start of string |
| end | number |
characters to keep at end off string |
Example
import truncate from '@datawrapper/shared/truncate';
// returns 'This is a…tring'
truncate('This is a very very long string')