-
Notifications
You must be signed in to change notification settings - Fork 25
Workspace Configuration
The workspace is a JSON document which defines locales, layers, and locations available to the MAPP library through the XYZ host.
This page provides an overview of the different configuration blocks contained within the workspace.
A default workspace.dbs
is the fallback database connection for any query which does not have an implicit dbs
parameter. The dbs key-value must have a corresponding DBS_* environment variable.
The JSON workspace.templates{}
holds template objects which can be referenced by their unique key.
A template can be a view, layer, or query [module].
Templates are only available to the XYZ API and are used to assemble a JSON locale and layers for the MAPP client.
The .template
key-value is a string representation of a SQL [query] or html [view] template. If not implicit in the template definition a template string can be loaded from an external source.
The workspace is assembled and cached upon initialisation of an XYZ process. The template src
is a reference for XYZ API to load the template from an external source. The source formats are supported:
-
https:
The template is loaded from a public URL. -
file:
The template is loaded from the local file system. The root being the application root, only files from the/public/*
directory can be loaded as templates when deployed. On the localhost it is possible to prefix the file path with a double dot to step out of the XYZ repository and load templates from other folders like so:file:../resources_repository/templates/etc
-
cloudflront:
The template will be loaded from the Cloudfront CDN. A KEY_CLOUDFRONT environment variable is required to provide signed access to secured Cloudfront ressources.
The Workspace API which assembles and caches the workspace will interpolate src strings prior to loading templates. A variable defined within a interpolation expression (${variable}
) will be substituted with the corresponding SRC_* environment variable.
A query template is referenced in parameterised request to prevent SQL injection. The XYZ API will never directly accept SQL as a paramater. A SQL query template must be referenced in a query request with parameters for the query template string interpolation being validated by the XYZ API or substituted in the database.
"table_parameter_query": {
"template": "SELECT * from ${table}",
},
"nnearest_locations": {
"src": "file:/public/js/queries/nnearest_locations.sql",
"dbs": "DEV"
},
"module_query": {
"src": "file:/public/js/queries/infotip.js",
"module": true,
"dbs": "DEV"
},
A template flagged as a module (.module = true
) must be loaded from an external source. The Workspace API will compile a JS module directly from the [file] source.
A template render method cannot be assigned as a string value in the JSON workspace. The Workspace API will the Module.exports
as the template .render() method when compiling a module from its source.
Application views are html templates available to the View API
e.g. https://geolytix.dev/latest/view/embedded
"embedded": {
"src": "file:public/views/embedded.html"
}
Layer templates allow for the same layer to be used in multiple locales without the need to duplicate the layer JSON. The XYZ host will assign the layer JSON template to the layer JSON if referenced as layer.template key-value. Partials can be defined in the layer.templates[] array. Partials will be merged with the layer JSON instead of using Object.assign().
The workspace.locale{}
is the master template for all locales in a workspace.
Each object referenced by its key in the workspace.locales{}
object represents a locale available to the XYZ API. An array of available locales dependending on user role restrictions can be requested from the Workspace API. It is recommended to use simple [locale] keys for ease of programmatic use.
A template matching the locale key will be assigned to the locale JSON.
Available locales are listed for access in a dropdown in the default MAPP view. Without specifying a locale
URL parameter.
A locale defines the functional and geographical extent of a mapview. A locale JSON object can be retrieved from the Workspace API and must be passed to the MAPP.Mapview decorator with the params argument. The default script will check whether any of the locale keys match MAPP.plugins and provide the mapview as well as the key argument to the plugin method.
A locale is referenced by it's key
. A name
can be defined for display in the locales dropdown. The locale key is assigned as name if undefined.
The locale extent
defines the geopgraphic limits of the mapview. It is not possible to pan the viewport outside the defined extent. The extent will also limit the min zoom. It is not possible to zoom out to a level where the viewport would exceeed the extent. The mapview beyond the extent will covered with a shade if the mask
flag is set in the extent configuration.
"extent": {
"north": 91,
"east": 91,
"south": 91,
"west": 91,
"mask": true
}
The centre of the mapview view[port] will be set to the fit the locale extent. The view
can be set to an implicit lat
, lng
, and z
.
"view": {
"lat": 91,
"lng": 91,
"z": 15
}
The .minZoom
integer value will limit the mapview's minimum zoom level. The relevant mapview zoom control will be disabled if the MinZoom level is matched by the current viewport.
The .maxZoom
integer value will limit the mapview's maximum zoom level. The relevant mapview zoom control will be disabled if the MinZoom level is matched by the current viewport.
The .ScaleLine
property in the mapview configuration allows you to specify the unit for the scale bar, enhancing the localization of the scale representation on the map.
-
ScaleLine
(string, optional): Specifies the unit for the scale bar. Acceptable values are 'metric' or 'imperial'. If not specified, the default value is 'metric'.
A gazetteer can be configured for a locale to provide a query tool for locations referenced by a location property matching a search term. The mapp.ui library provides an input interface to display the gazetteer query response in a dropdown for selection.
A layer
must be referenced by its mapview.layers
key in order to query and get a location from the layer. Any current [layer] filter as well as role restrictions will apply.
The qterm
defines the field which will be queried for the search term.
"gazetteer": {
"layer": "retailpoints",
"qterm": "store_name"
}
Optional configuration keys are:
Query this table
instead of the layer table.
Set the gazetteer input placeholder. Can not be set within .datasets[]
.
The field which will be returned in the results. By default this is the qterm
, however it is possible to query one field but display a different field as label in the gazetteer results.
The title is shown next to the records in the gazetteer results. The title tag will default to layer.name
, or provider
is not implicit.
Whether the SQL search term should be prefixed with a wildcard [%].
Limits the maximum number of results per search/dataset. Defaults to 10.
The result string to be shown for a gazetteer/dataset query which doesn't return any results. No result entry will be shown for no_result:null
.
Limits the zoom level when setting the mapview viewport for a location from a gazetteer search.
It is possible to enable external gazetteer services through plugins. These services may require API keys and are documented in their respective plugin documentation.
Plugins for access to Google [Places] and Mapbox [Forward-Geocoding] are available in the MAPP repository.
A new location is being created from the external gazetteer response. The gazetteer.layer
and qterm
will be ignored for provider queries.
Additional queries are made for each dataset defined in the datasets array. A placeholder
or provider
can not be defined in a dataset. The layer
and limit
parameter will be taken from the gazetteer configuration if not implicit in the dataset configuration.
"gazetteer": {
"layer": "retailpoints",
"qterm": "store_name",
"leading_wildcard": true,
"limit": 5,
"datasets": [{
"title": "Postcode"
"qterm": "postcode"
}]
}
The locale.roles{}
defines which user roles have access to a locale. A role is referenced by its key in the roles{} object. A role key prefixed with an exlamation mark indicates a negated role. The role expression applies to all users which do not have the negated role.
The locale.queryparams{}
will be assigned to the layer.queryparams{}
and location entry.queryparams{}
.
The .locator:true
flag can be set to add a locator button to the MAPP default view button column.
Plugins are javascript modules which are loaded and executed from src strings in the locale.plugins[]
array.
"plugins": ["path/script.js"]
An array of plugin method keys can be defined to be executed synchronously prior to any other plugins being executed asynchronously. By default the array of plugin methods defines the order of the buttons for the default view as zoomBtn, admin, and login.
syncPlugins: ['zoomBtn', 'admin', 'login']
The MAPP default view script checks any locale keys against the mapp.plugins{}
after a locale is used to initialise the mapview, but before layers are added to the mapview. The [custom] locale key-value is provided as first argument to the plugin method, and the mapview itself is provided as second argument.
SVG templates defined in the locale.svg_templates{}
are cached as string values available for parameter substitution through the svgSymbols utility.
"svg_templates": {
"template_pin": "https://geolytix.github.io/MapIcons/pins/pink_master_pin.svg"
}
An array for the symbol and colour being assigned to mapview.locations{}
when the location [view] is added to a locations.listview
. This defaults to a list A to J with a non repetitive rainbow spectrum for the colours.
"listview_records": [
{
"symbol": "1",
"colour": "#000000"
},
{
"symbol": "2",
"colour": "#DD0000"
},
{
"symbol": "3",
"colour": "#FFCE00"
}
],
The layer JSON will be merged with the locale.layer{}
when a layer is added to a mapview. The locale.layer{}
acts as a master template for all layers in a locale. This allows to assign the same filter or draw defaults to every layer in a locale.
"layer": {
"filter": {
"current": {
"country_code": {
"match": "GBR"
}
}
},
"draw": {
"defaults": {
"country_code": "GBR"
}
}
}
Only layers within the locale.layers{}
object are available within the context of a locale being used to initialise a mapview.
A layer is referenced by its key in locale.layers{}. A JSON locale requested from the Workspace API will contain an array of layer [keys] available to the user requesting the locale for a mapview.
A [layer] template whose key is matching a key in the .layers{}
object will be assigned to the layer object when the JSON layer is requested from the Workspace API.
A JSON layer is a configuration object which can be added to a mapview. The MAPP library will decorate the JSON layer when it is added to the mapview to create a functional layer object which can be accessed through the mapview.layers list object.
The layer object will be merged into a template which matches the layer key. Alternatively a template can be referenced by the template property.
Multiple templates can be assigned to the JSON layer. The Workspace API will merge these templates in order into the layer object.
Please note the reversed order: The layer is merged into a template. But templates are merged into the layer.
If not set the JSON layer key will be assigned as the layer's name. The name is assigned to the header of a layer view.
The meta property value will be parsed as innerHTML for an element in the layer.view
node.
Layer views will be grouped in a layer listview group drawer. The key-value of the layer.group
property will be assigned as the group element header.
The layer.groupmeta
property value will be parsed as innerHTML for an element in the layer.group
node which contains the layer.view
node.
The layer.display
will determine whether the layer is displayed as default when added to a mapview without a layers URL parameter overriding which set of layers should be displayed.
The layer.hidden
flag controls whether a layer view is created and shown in the layers listview. A layer without a view element is still accessible programatically through the mapview.layers{}
object.
By default all location [infoj] entries with an edit key are editable. Setting the layer.toggleLocationViewEdits
will prefix all edit entries with an underscore character. A spanner icon will be added to the location.view
header to toggle the edit entries.
Role objects within the layer.roles{}
define which user roles have access to a layer. Any role object referenced by its key in the mapp.user.roles[]
array will be merged with the JSON layer when the layer is decorated by the MAPP library. Likewise any negated role object will be merged if the user does not have the referenced role.
A .filter{}
object can be defined within a role. This filter will always be applied by any query which references the layer.
The asterisk role (*) is a reserved role which will not be returned from the roles.get() method to the admin panel. Setting "*": true
as a layer role simply makes the layer available to every user, even user without any roles. This does not have an effect merging, or filter associated with other roles on the layer.
"roles": {
"*": true,
"foo": true,
"!point": {
"draw": {
"polygon": true
}
},
"draw_role": {
"draw": {
"point": true
}
},
"fascia_filter": {
"filter": {
"fascia": {
"in": ["Budgens", "Waitrose"]
}
}
}
}
The layer.filter{}
object will be created if undefined when a layer is decorated.
layer.filter.current{}
stores the currently applied filter to a layer. Current filter can be modified or removed through the layer.view
filter panel.
The XYZ sqlFilter.js module will turn JSON filter into SQL [Postgres] filter expression.
The layer.filter.default will always be applied in addition to any role or current filter. The default filter is looked up directly from the layer JSON and can not be modified by a client request. The default filter can be defined as string or object.
// default filter as string
"default": "(NOT retailer = ANY (ARRAY['Booths','Co-op']))"
// default filter as object
"default": {
"retailer": {
"ni": [
"Booths",
"Co-op"
]
}
}
A gte filter will pass records where the filter field has a numeric value which is equal or greater than filter value. In a gt
filter the value must be greater than.
"field": {
"gte": 10000
}
WHERE "field" >= 1000
A lte filter will pass records where the filter field has a numeric value which is equal or lesser than filter value. In a lt
filter the value must be lesser than.
"field": {
"lte": 10000
}
WHERE "field" <= 1000
Table records will be passed if the field value is in the filter array.
"field": {
"in": ["A", "B", "C"]
}
WHERE "field" = ANY(['A', 'B', 'C'])
Table records will be passed if the field value is not in the filter array.
"field": {
"ni": ["A", "B", "C"]
}
WHERE NOT "field" = ANY(['A', 'B', 'C'])
The match filter will pass if a string matches an ILIKE expression.
"field": {
"match": "st pauls"
}
WHERE "field" ILIKE 'st pauls'
Similar to the match filter, the like filter will add a wildcard character to the filter expression.
"field": {
"like": "st"
}
WHERE "field" ILIKE 'st%'
A record will pass the filter expression if the boolean field value matches the filter.
"field": {
"boolean": true
}
WHERE "field" IS true
A record will pass the filter expression if the field value is (or is not [false]) null.
"field": {
"null": true
}
WHERE "field" IS NULL
Requests to the Location API require the field name for a unique location identifier.
The table name for the layer data at rest.
Instead of the layer.table
a layer.tables{}
configuration object can be assigned to the JSON layer. The keys in the tables object representing an integer zoom level. The key-value is the table name for the keyed zoom level. A null
value as the smallest or largest zoom key-value will make the layer unavailable at or beyond that zoom level. Without a null value the last defined table name in the tables object will be used.
{
7: null,
8: "schema.table_1",
9: "schema.table_2",
10: "schema.table_3",
11: null
}
The field name which stores the feature geometries in the layer table.
Instead of the layer.geom
a layer.geoms{}
configuration object can be assigned to the JSON layer. The keys in the geoms object representing an integer zoom level. The key-value being is the feature geometry field name for the keyed zoom level. The smallest or largest zoom level key-value will be assigned as geometry field in requests which are outside the specified zoom level range.
{
8: "geom_50m",
9: "geom_10m",
10: "geom"
}
Features will be filtered if the .z_field
integer value is below the current zoom level.
"z_field": "field"
The SRID/EPSG projection code for the layer geometry field.
Any layer keys are checked against the mapp.plugins{}
and mapp.layer{}
methods when a layer is decorated. The decorated layer object which must have a mapview property is provided as only argument to the plugin/layer method.
The deleteLocation: true
flag indicates whether a location can be deleted from the layer's dataset.
Entries in the .draw{}
configuration define which types of geometry are created by the mapview draw interaction.
A .label
value can be assigned to each drawing method. The label will be displayed as button text which toggles the drawing interaction.
"draw": {
"polygon": {
"label":"Add New Polygon"
}
}
The field values defined as .defaults{}
will set for the fields for a newly created location.
The .defaults{}
can be set directly in the .draw{}
config or within the individual drawing method configurations.
"edit": {
"point": true,
"delete": true,
"defaults": {
"field": "default_value"
}
}
Creates a single point geometry. There are no additional configuration keys for the point geometry draw interaction.
Creates a single linestring geometry.
Creates a single polygon geometry.
Creates a single rectangular polygon by defining two opposing corner points.
Creates a single circular polygon by defining the centre and a point on the circle edge.
- Creates a single circular polygon from a centre point and parameters that describe the extent of the circle.
- Default params for the circle configuration panel can be overwritten.
- Providing
hidePanel:true
will hide the radius and units panel from the user, instead allowing them only to draw a circle using the defined defaults, or specified configuration. e.g.
"circle": {
"hidePanel": true,
"label": "1km Catchment",
"radius": 1000,
"units": "meter"
}
Creates a single point geometry on the current locator position. There are no additional configuration keys for the rectangle geometry draw interaction.
If defined within the drawing type, the snap:true
flag will configure the drawing interaction snapping to geometries from the draw layer. A layer key for another layer added to the same mapview can be provided instead.
"draw": {
"polygon": {
"snap": {
"layer": "layer_key"
}
}
}
A custom draw method can be created by assigning the method to mapp.ui.elements.drawing{}
.
The layer.format
defines the nature of a layer when being added to a mapview and decorated.
The layer data is provided as tiles in the Mapbox Vector Tile format. Requests to the XYZ Layer API must reference the tile using /zoom/x/y slippy tile name. Tiles maybe cached in the .mvt_cache
table. Cached tiles may not be used with layer filter and dynamic feature properties.
MVT features can have any geometry type.
MVT feature geometry must be SRID:3857
.
"format": "mvt",
"mvt_cache": "table_name",
The Vector format should be used for wkt
, geojson
and cluster
formats.
As of v4.7.2 the methods have been combined into vector.mjs
for ease of maintainability.
"type": "vector",
"cluster":{
"resolution":0.2,
"distance": 10,
"label": "field",
"hexgrid": true
},
"fade": true
Parameters:
layer.cluster
- Object containing:
-
resolution
(optional) - Required for cluster format layers. This is a fraction of the average tile length at a given zoom level [z param].
-
distance
(optional) - Required for WKT format layers.
NOTE -resolution
anddistance
are mutually exclusive, you CANNOT use them together.
-
label
(optional) - The label field to use when clicking on a cluster, defaults to thelayer.qID
.
-
layer.hexgrid
- A flag that if set totrue
, A hex grid aggregation will be applied.
-
layer.fade
- A flag that if set totrue
, will fade the layer while requesting new data.
The maplibre library will be dynamically loaded if not found as global. An .accessToken
must be provided to access private datasets and styles hosted by mapbox.
"mapbox_light": {
"format": "maplibre",
"accessToken": "XXXXX",
"preserveDrawingBuffer": true,
"style": {
"zIndex": 98,
"URL": "mapbox://styles/XXX/XXX"
}
}
The layer.queryparams
will be used assigned to layer queries and to location entry.queryparams{}
. The locale.queryparams{}
will be assigned to the layer.queryparams{}
.
The order of layer panel in the layer view can be controlled with the .panelOrder[]
array.
The default order is:
.panelOrder: [
'draw-drawer',
'dataviews-drawer',
'filter-drawer',
'style-drawer',
'meta'
]
The style object defines how layer features are styled.
The default style will be applied to every feature in a dataset. Other style objects will be assigned to this default style before sending the style object to the feature render.
"default": {
"fillColor": "#d9d9d9",
"fillOpacity": 0.5,
"strokeWidth": 0.01,
"strokeColor":"#d9d9d9"
}
A highlight styling can be provided which is used when you hover over a geometry. This is useful to let the client know which geometry they are selecting.
"highlight": {
"fillColor": "#DBD56E",
"strokeColor": "#000",
"strokeWidth":1,
"fillOpacity": 0.7,
"scale": 1.3
}
The cluster style is applied to features which account for multiple locations in close proximity which form a location cluster.
If the default styling is an SVG and the cluster as a non-SVG, make sure to add svg: null
to the cluster object to allow this. You can provide clusterScale: null
if you wish for the cluster to be a single size, and not resize based on how many points are within it.
"cluster": {
"clusterScale": 0.8
}
Label can be used to display feature properties as text elements in the mapview.
The label.title
will be displayed in the dropdown to switch the label or as title for the display toggle with a single label.
Whether the label is displayed by default.
The feature property to be displayed as label.
Whether the location count should be displayed on cluster features which do not have a single property value.
The size and font family to use. Defaults to "12px sans-serif"
.
The font colour.
The colour and width of a halo for the text.
Limits the zoom level range at which the label can be displayed.
The offset of the text from the feature geometry [centre].
"label": {
"field": "name",
"title": "Toggle Label Display",
"display": true,
"overflow": true,
"count": true,
"font": "12px sans-serif",
"fillColor": "#ee4b2b",
"strokeColor": "#fff",
"strokeWidth": 3,
"minZoom": 9,
"maxZoom": 15,
"offsetX": -10,
"offsetY": 10
}
A label{}
config with the key matching a style.label
string will be assigned as default, otherwise the first of multiple style.labels{}
will be assigned as style.label{}
when the layer is decorated.
The style.hover{}
config object defines a feature hover method. mapp.layer.featureHover()
will be defined as style.hover.method()
if not already defined.
The hover method receives the feature, and layer as arguments from the mapview.highlight
interaction.
The display flag controls whether the query in the default featureHover()
method will be executed.
The field will be provided as parameter for the default infotip query template.
The query template for the featureHover()
method. Defaults to the 'infotip' template.
The title for the hover interface in the layer style panel.
The .layout
and alignment of the content for a theme legend can be configured in the theme.legend{}
JSON.
"legend": {
"layout": "flex",
"alignContents": "centered"
}
A hover{}
config with the key matching a style.hover
string will be assigned as default, otherwise the first of multiple style.hovers{}
will be assigned as style.hover{}
when the layer is decorated.
A layer can be styled according to its features' property values. The theme.type
defines the lookup method for a style to be assigned to the layers default style for a feature.
A theme will be assigned from style.themes{}
if the theme key matches a style.theme
string value.
The theme title will displayed in theme legend or themes dropdown. The style.themes{}
key will be assigned as name if not implicit. It is recommended to use simple keys for all themes in favour of assigning a theme name for display.
The meta value will be rendered as innerHTML in legend element below the title.
The field which must be assigned as a feature property in the layer data. Depending on the theme type the feature style will be assigned from a lookup in the theme.cat{}
or theme.cat_array[]
. A query template will be used in the dataset query if the field matches a workspace.templates{}
key.
A label with the setLabel
key value will be set as the style.label{}
from the style.labels{}
object.
A label with the setHover
key value will be set as the style.hover{}
from the style.hovers{}
object.
A categorized theme can be used to assign a style object from a cat{}
where the cat key matches a feature's [field] property value. The cat .label
can be set for display in the theme legend.
"type": "categorized",
"field": "colour",
"cat": {
"red": {
"label": "Red"
"style": {
"fillColor": "#f00"
}
},
"green": {
"label": "Green"
"style": {
"fillColor": "#0f0"
}
},
"blue": {
"label": "Blue"
"style": {
"fillColor": "#00f"
}
}
}
A distribution: count
key-value pair added to a categorized thematic will use the simple-statistics library to only show options in the legend that are present in the viewport. This will show the number of that option in the thematic too:
Red [10]
Green [8]
The configuration developer will just provide the style for each category in the data, and then the count is generated using the data within the viewport.
NOTE - to use this on an mvt
format layer, you will need to pass layer.wkt_properties:true
.
NOTE - to use this on an wkt
or geojson
format layer, you will need to pass layer.params.viewport:true
.
If you do not pass this, you will get the counts for the whole dataset and it will not update as you zoom in and zoom out.
"type": "categorized",
"field": "colour",
"distribution": "count",
"cat": {
"red": {
"label": "Red"
"style": {
"fillColor": "#f00"
}
},
"green": {
"label": "Green"
"style": {
"fillColor": "#0f0"
}
},
"blue": {
"label": "Blue"
"style": {
"fillColor": "#00f"
}
}
}
A graduated theme can be used to assign a style object from a cat_array[]
entry where feature's [field] property value is below the entry .value
.
- The
legend
object allows the legend to be styled differently.layout:flex
will turn the legend into a flexbox instead of grid.alignContents
will allow the contents to be aligned.horizontal: true
will turn the legend from vertical to horizontal.nowrap: true
will force all legend entries onto one line, rather than wrapping.
"type": "graduated",
"legend": {
"layout": "flex",
"alignContents": "centered",
"horizontal": true,
"nowrap": true
},
"field": "rank",
"cat_arr": [
{
"value": 0,
"label": "Nought",
"style": {
"fillOpacity": 0.1
}
},
{
"value": 10,
"label": "below 10",
"style": {
"fillOpacity": 0.3
}
},
{
"value": 100,
"label": "10 to 100",
"style": {
"fillOpacity": 0.6
}
},
{
"value": 999999999,
"label": "above 100",
"style": {
"fillOpacity": 1
}
}
]
A distribution: jenks
key-value pair added to a graduated thematic will use the simple-statistics library to generate the breaks using a jenks classification.
The configuration developer will just provide the style for each break required in the data, and then the jenks breaks are generated using the data within the viewport.
NOTE - to use this on an mvt format layer, you will need to pass layer.wkt_properties:true.
NOTE - to use this on an wkt or geojson format layer, you will need to pass layer.params.viewport:true.
"jenks": {
"label": "Thematic",
"type": "graduated",
"distribution": "jenks",
"field": "field_name",
"cat_arr": [
{
"style": {
"fillColor": "#f7fcfd"
}
},
{
"style": {
"fillColor": "#e5f5f9"
}
},
{
"style": {
"fillColor": "#ccece6"
}
},
{
"style": {
"fillColor": "#99d8c9"
}
},
{
"style": {
"fillColor": "#66c2a4"
}
},
{
"style": {
"fillColor": "#41ae76"
}
},
{
"style": {
"fillColor": "#238b45"
}
},
{
"style": {
"fillColor": "#005824"
}
}
]
}
A distributed theme will assign style objects from the .cat_array[]
array in a manner the reduces the likelihood of the same style being applied to neighbouring features. The theme method will distribute each style equally among the layer features. A field can be assigned to distribute cat values. The same field value will be assigned the same cat style. This is optional by default the feature property id
will be used to distribute cat styles.
"type": "distributed",
"field": "id",
"cat_arr": [
{
"fillColor": "#f00"
},
{
"fillColor": "#0f0"
},
{
"fillColor": "#00f"
}
]
Multiple theme{}
configurations can be provided as layer.style.themes{}
. With layer.style.theme
defined as a string value a theme with matching key will be assigned as default when the layer is decorated. Otherwise the first entry will be assigned as the default theme. The theme can be changed with a dropdown input in the layer style panel.
It is possible to skip themes by using the skip:true
flag. This is useful when you wish to remove a theme from a template.
The example below would skip the Fascia
theme.
"style": {
"themes": {
"Fascia": {
"skip": true
}
}
The icon can be defined as an array where the first item in the array will be rendered first and subsequent items will be rendered on top. Default legend icons are rendered 24 by 24px. A legendScale must be applied to scale down the icons to fit into the default sized canvas.
"icon": [
{
"svg": "https://geolytix.github.io/MapIcons/pins/mint.svg",
"scale": 2,
"legendScale": 0.35,
"anchor": [0.5, 1]
},
{
"svg": "https://geolytix.github.io/mapp/icons/emblem.svg",
"scale": 0.03,
"anchor": [0.5, 1.6]
}
]
type: "target"
type: "diamond"
type: "dot"
type: "svg"
type: "template"
A location is associated with the features that make up a layer. It is possible to get a location from the XYZ Location API by sending a request providing the locale
, layer
, and a location's unique ID.
The infoj_skip array allows you to define a list of keys, fields, or queries to be skipped from the infoj of that layer.
"infoj_skip": [
"field_to_skip",
"key_to_skip",
"query_to_skip"
]
The infoj_order array can be defined as a list of lookup keys and entry objects.
"infoj_order": [
{
"type": "dataview",
"dataview": "tabulator",
"target": "tabview",
"query": "query_template",
"table": {
"layout": "fitColumns",
"columns": [],
"autoColumns": true
}
},
"entry_key",
"char_field",
"textarea"
]
Key strings will be used to lookup entries in the location layer infoj array for matching key, field, or query key values. This allows for the sorting and filtering of infoj entries.
Entry objects in the infoj_order will be spliced and decorated with the location object in place.
The infoj is the term used to describe the information we provide in the left-hand panel of the map window when you click on a geometry. This is an array of objects that make up what the user wishes to see.
Fieldfx allows you to alter the value displayed in the infoj. This is particularly useful if you wish to apply formatting to a number, convert values or change the field "ROUND(numeric_value,2)"
. This can be provided as an SQL query, but must all be provided on a single line. If you wish to provide an SQL query, you must ensure the WHERE
clause includes WHERE id= $1
.
SELECT ROUND(numeric_value2,2) FROM table_2 LEFT JOIN table_1 ON t1.id = t2.id WHERE id=$1
It is possible to query a json field key through the fieldfx using the json arrow notatrion. The following fieldfx will return the 'age' value from the json_field column.
"fieldfx": "json_field -> 'age'",
Using a combination of jsonb_field and jsonb_key allows to update individual key values in a json type column.
The following example uses the json arrow notation to extract the age value from the json_field. The field
value must be unique in order to assign the value from the get location request to the correct entry.
{
"field": "json_field_age",
"fieldfx": "json_field -> 'age'",
"jsonb_field": "json_field",
"jsonb_key": "age",
"edit": true
}
The combination of of json_field and json_key may be used to create editable entries for a single json key/value.
A type:json entry must be added to the infoj array. The json_field
value will be used as lookup to identify the entry with the matching field value.
The location.update method will update the key/value in the json entry before updating the object in the location data at rest.
{
"field": "json_field",
"type": "json",
"skipEntry: true
},
{
"json_field": "json_field",
"json_key": "age",
"edit": true
}
The query template to use for a query which will populate the entry.value
The queryparams are used to create the url params for a request to the Query API. The layer.queryparams{}
, and locale.queryparams{}
will be assigned to the entry.queryparams{}
.
The following queryparams flags are reserved.
"queryparams": {
"locale": true, // locale key.
"layer": true, // layer key.
"table": true, // layer table.
"filter": true, // layer current filter.
"z": true, // mapview current z.
"viewport": true, // mapview [west,south,east,north] bounds.
"center": true, // mapview lat/lng center.
"email": true, // user email.
}
A query will be run by the infoj process and the response will be assigned as entry.value
before the entry.type
method is called.
The entry.value
will be populated from the field or fieldfx value in location get response, or from a entry.query
response.
The value to be rendered into the title element which is appended to the entry.node.
The entry.css_title
value will be applied as inline style to the title element inside the entry.node.
The entry.css_val
value will be applied as inline style to the value element inside the entry.node.
The value to show as a tooltip when hovering over the title.
This will also append an SVG of a question mark to the end of the title so the user is aware that it has a tooltip.
The value element will be displayed in a separate row below the title element. If entry.inline: true
the title and value will be rendered in the same row in the location view entry.node.
Prefix allows you to add a prefix to the start of the field value in the infoj. This is useful if you are displaying currencies.
prefix: '£'
Suffix allows you to add a suffix to the end of the field value in the infoj. This is useful if you are displaying percentages.
suffix: '%'
You can put infoj objects into a group to help break up the information. You must provide a group name to do this, which will be displayed above the first infoj object with that group associated to it.
The group drawer will be expanded if any of the entries which are added to a location view group have the .groupClassList: "expanded"
flag set.
(Note: .expanded: true
is deprecated)
The .objectMergeFromEntry
value can be used to look up an entry with matching type. The lookup entry will be merged into the entry.
{
"title": "Merge into this entry",
"objectMergeFromEntry": "mergeEntry"
},
{
"type": "mergeEntry"
"title": "This title will overwrite the original entry title."
}
The entry.class
value will be concatenated as class[List] property for the creation of the entry.node
element. Assigning the display-none
class prevent the entry.node from being displayed.
If configured null
will be replaced as entry.value
with the entry.nullValue
.
The entry will not be processed by the infoj method if flagged as true.
The entry will not be processed by the infoj method if the entry value is null (entry.value === null
).
The entry will not be processed by the infoj method if the entry.value is falsy, e.g. undefined, null ,NaN ,0 ,"" (!entry.value
).
The entry will not be processed by the infoj method if the entry.value is undefined (typeof entry.value === 'undefined'
).
If a filter is taking a long time to load on the MAPP instance and it is a numeric or integer field - apply the max and min settings and make sure to apply an index to that field on the table on the database.
Creates a slider bar and manual input box to filter numeric values that are greater than and less than the provided values.
- For numeric filters specifying the min and max makes the filter query faster as it saves two calculations on the data.
- Although min and max are not a requirement for
field
definitions there are mandatory forfieldfx
definitions. - Uses the numeric formatting of the
infoj
entry that the filter is applied to.
"filter": {
"type": "numeric",
"min": 123.45678,
"max": 123456.78
}
Creates a slider bar and manual input box to filter integer values that are greater than and less than the provided values.
- For numeric filters specifying the min and max makes the filter query faster as it saves two calculations on the data.
- Although min and max are not a requirement for
field
definitions there are mandatory forfieldfx
definitions. - Uses the numeric formatting of the
infoj
entry that the filter is applied to.
"filter": {
"type": "integer",
"min": 123,
"max": 123456
}
Creates a free text box that will filter on exactly what is provided in the text box with the database field value.
By default this will search for your search term only search_term
.
To search for the search term and anything before it, add leading_wildcard: true
. This will search for %search_term
.
"filter": {
"type": "match"
}
Creates a free text box that will filter the database field value where the value contains the data provided in the free text box.
By default this will search for your search term and a wildcard for anything following it search_term%
.
To search for the search term anywhere in the field, add leading_wildcard: true
. This will search for %search_term%
.
"filter": {
"type": "like"
}
An in[]
of filter values can be configured. A distinct values query will be used without an array of filter values.
A entry.field
is required for layer filter.
Returns a list of checkboxes by default to toggle the individual in [array] values.
Can be defined as dropdown
or searchbox
UI filter elements.
"field": "table_column",
"filter": {
"type": "in",
"in": ["A", 1, "Foo"],
"dropdown": true
}
An ni[]
of filter values can be configured. A distinct values query will be used without an array of filter values.
A entry.field
is required for layer filter.
Returns a list of checkboxes by default to toggle the individual in [array] values.
Can be defined as dropdown
or searchbox
UI filter elements.
"field": "table_column",
"filter": {
"type": "ni",
"ni": ["A", 1, "Foo"],
"searchbox": true
}
Provides a filter using a calendar which includes both the date calendar and date time.
"filter": {
"type": "datetime"
}
This allows you to use a query to build a json_object that can then be passed into an object in the infoj
.
This is particularly useful if you wish to define the title using values that may change (ie you wish to display the year from a year field that can be updated).
Here, you first create an infoj
object to define the title, and set it to display-none (so the user cannot see). This infoj
object will have a fieldfx to create the json object.
Then, you create a second infoj
object for the field value (perhaps a count for a year), and assign the objectAssignFromField to this.
This will then assign your title object to the infoj
object.
If you wish to use the field from this within a filter you will need to provide a label for the filter within the filter block.
{
"field": "pass_yr_minus_1_title",
"fieldfx": "json_build_object('title', concat(('April ',(current_year - 2)))",
"type": "json",
"class": "display-none"
},
{
"field": "pass_yr_minus_1",
"objectAssignFromField": "pass_yr_minus_1_title",
"type": "integer",
"inline": true,
"filter": {
"title": "Passengers (past year)",
"type": "numeric"
}
}
A plugin may add a custom entry method to mapp.ui.locations.entries{}
. These entry methods behave the same as any entry method and will receive the entry itself as only argument. The location, layer, and mapview can all be inferred from the entry object.
The type: key
entry will be displayed by the layer name in the location view.
{
"type": "key"
}
The type: pin
entry will create a labelled and coloured pin for the location. The value must resolve to a coordinate array matching the entry srid. The layer.srid is assumed as the default.
{
"type": "pin",
"field": "pin",
"fieldfx": "ARRAY[ST_X(geom_p_4326), ST_Y(geom_p_4326)]"
}
The type:text
is the default entry type which will be assigned if not implicit. The edit config supports a placeholder for the input element and to define the maxlength for the input.
"type": "text",
"edit": {
"placeholder": "Input placeholder text",
"maxlength": 7
}
The type:textarea
will provid a multiline textarea input for editing. The edit config supports a placeholder for the input element and to define the maxlength for the input.
"type": "textarea",
"edit": {
"placeholder": "Input placeholder text",
"maxlength": 7
}
The type: integer
entry will parse the value as an integer.
{
"field": "field_name",
"type": "integer"
}
The type: numeric
will parse the value as a float. A formatterParams
object can be provided to configure a toLocaleString
conversion of the value for display.
Typically this will just want to be maximumFractiondigits
which is the number of decimal places.
Further options can be found Here, by default the locale is set to en-GB
{
"field": "field_name",
"type": "numeric",
"formatterParams": {
"options": {
"maximumFractionDigits": 5
},
"locale": "en-GB"
}
}
rounnd:int
can be used as a shorthand for formatterParams.options.maximumFractionDigits
{
"field": "field_name",
"type": "numeric",
"round": 1
}
type: date
Adds a date infoj
entry.
Database field must be of type bigint.
By default this will show as dd/mm/yyyy, hh:mm:ss.
To return just the date in format dd/mm/yyyy add the locale
and options
object.
{
"field": "date",
"type": "date",
"locale": "en-UK",
"options": {
"year": "numeric",
"month": "2-digit",
"day": "2-digit"
}
}
type: datetime
Adds a datetime infoj
entry.
Database field must be of type bigint.
By default this will show as dd/mm/yyyy, hh:mm:ss.
You can control this with the locale
and options
object.
{
"field": "date",
"type": "datetime",
"locale": "en-UK",
"options": {
"year": "numeric",
"month": "2-digit",
"day": "2-digit"
}
}
type: time
Adds a timeinfoj
entry.
Database field must be of type numeric or varchar.
{
"title": "Time",
"field": "time_field",
"type": "time"
}
The type:link
entry will create a node containing an icon and anchor tag (link). The default icon class is mask-icon open-in-new
. The default label for the link is "Link". An URL path must be defined as entry.url
. The URL parameter are constructed from the params object.
The icon style can be set as inline style provided as icon_style
string value.
{
"type": "link",
"icon_class": "mask-icon open-in-new",
"label": "Link",
"url": "https://geolytix.com",
"params": {
"param": "value"
}
}
Creates a button element in the location view which run a parameterised query. The host
, query
[template] and queryparams
can be configured in the entry.
An array of dependents [fields] can be defined. The matching entry values will be synched after the query has been resolved.
{
"label": "Snap to Postal Sector",
"type": "query_button",
"query": "catchment_statistics_snap_to_postal_sector",
"queryparams": {
"id": true
},
"alert": "Query has executed!",
"reload": true,
"dependents": [
"geom_3857",
"perimeter",
"area"
]
}
The type:report
entry is a legacy configuration that will resolve without warning to a type:link
.
type: html
This will allow you to output HTML directly into the infoj field.
This is useful as we can use this to control colouring, and text-formatting of information in the infoj for that field.
{
"field": "field_name",
"type": "html",
"fieldfx": "CONCAT('<a href=',field,'>Hyperlink</a></span>')"
}
type: title
This will allow you to just define a title as that infoj entry.
There is an optional css_title
key that can be used to control the styling of the title.
{
"type": "title",
"title": "This is a title",
"css_title": "font-weight:400"
}
The type:json
entry value is a json object. The SQL field must be type json to support a json entry. The edit interface will attempt to parse a json object before allowing to store a new value in the location data at rest. .json_field
with .json_key
entries can be used to update individual key/values in the json field.
{
"field": "json_field",
"type": "json",
"edit: true
}
The type:pills
entry value requires an array value. The array values will be displayed as pills.
{
"field": "arr_field",
"type": "pills"
}
The type:image
entry will show a thumbnail of an image from a cloudinary url stored as the entry.field value. If editable it is possible to delete the image or upload an image if the value is null.
A cloudinary_folder
must be provided to determine the location where the images are stored.
{
"field": "field_name",
"type": "image",
"cloudinary_folder": "folder_name",
"edit": true
}
A valid CLOUDINARY_URL
must be in the process env in order to upload or remove images.
The type:images
entry will be displayed as a gallery of thumbnails in the location view. The thumbnails can be previewed by clicking. An interface to upload or delete images is available with the entry.edit:true
flag.
A cloudinary_folder
must be provided to determine the location where the images are stored.
{
"field": "field_name",
"type": "images",
"cloudinary_folder": "folder_name",
"edit": true
}
The field to store references for cloudinary resources must be defined as a text array in the layer table.
images text[] DEFAULT '{}'::text[]
A valid CLOUDINARY_URL
must be in the process env in order to upload or remove images.
The type: dataview
allow output to a chart or table to the infoj, tabview or a HTML location within a custom view (report).
A Table Dataview returns a table. This uses the Tabulator Package to do so, please refer to the documentation for table formatting options.
Further Dataview Functionality may be present in the Dataview Section.
{
"label": "Table Infoj Dataview",
"type": "dataview",
"target": "location",
"query": "query_name",
"queryparams": {
"id": true,
"table": true,
"filter": true
},
"table": {
"layout": "fitColumns",
"columns": [
{
"title": "Field",
"field": "field"
},
{
"title": "Value",
"field": "value",
"formatter": "toLocaleString"
}
]
}
}
Here we can provide:
-
label
(optional) - This generates a checkbox with the name in the infoj, without the label the dataview cannot be toggled on/off. -
target
- This can be tabview (the tab at the bottom of the MAPP), location (the infoj), or a HTML location ('html-dataview').
The HTML location is used when we wish to draw a chart directly into a report. -
SkipEntry: true
(optional) - This is used when we wish to skip the drawing of the chart, this is used when we want to draw a dataview to a HTML location within a report. -
queryCheck: true
(optional) - This will check whether the query for the dataview returns data, and if not will disable the checkbox if one is provided, or hide the dataview from display. -
display: true
(optional) - This will set the dataview to automatically display, the default is false. -
queryparams
- This provides the parameters you wish to pass to a query.
This is typicallyid: true
to select just information for a particular location.
You can also providetable: true
which will provide the table defined on the layer. This is especially useful when using a template but defining the table for each locale within the layer.json.
This requires the SQL query to containFROM ${table}
to ensure it only returns information from the relevant table location.
You can providefilter: true
which will pass the filters selected on the layer to the query. This requiresWHERE true ${filter}
to be added to the query. -
formatter: toLocaleString
- This will add thousand separators to the number (1000 becomes 1,000).
A Chart Dataview returns a chart. This uses the ChartJS Package to do so, please refer to the documentation for chart formatting options.
Further Dataview Functionality may be present in the Dataview Section.
{
"label": "Chart Infoj Dataview",
"type": "dataview",
"display": false,
"target": "location",
"query": "query_name",
"queryparams": {
"id": true,
"table": true,
"filter": true
},
"chart": {
"options": {
"aspectRatio": 1.4,
"indexAxis": "x"
}
}
}
Here we can provide:
-
label
(optional) - This generates a checkbox with the name in the infoj, without the label the dataview cannot be toggled on/off. -
target
- This can be tabview (the tab at the bottom of the MAPP), location (the infoj), or a HTML location ('html-dataview').
The HTML location is used when we wish to draw a chart directly into a report. -
SkipEntry: true
(optional) - This is used when we wish to skip the drawing of the chart, this is used when we want to draw a dataview to a HTML location within a report. -
queryCheck: true
(optional) - This will check whether the query for the dataview returns data, and if not will disable the checkbox if one is provided, or hide the dataview from display. -
display: true
(optional) - This will set the dataview to automatically display, the default is false. -
queryparams
- This provides the parameters you wish to pass to a query.
This is typicallyid: true
to select just information for a particular location.
You can also providetable: true
which will provide the table defined on the layer. This is especially useful when using a template but defining the table for each locale within the layer.json.
This requires the SQL query to containFROM ${table}
to ensure it only returns information from the relevant table location.
You can providefilter: true
which will pass the filters selected on the layer to the query. This requiresWHERE true ${filter}
to be added to the query.
The type type:geometry
field value must be geojson. The geometry will be added to the mapview with the provided style. The location style will be assigned to the entry.style. The location.layer.srid
will be assumed as projection if not implicit as entry.srid
. A fieldfx function can be used to generate the required format in the location.get() request.
A draw config block can be defined in the entry root or within the edit block. Drawing will always be available if defined on the root or can be toggled with editing if defined in the edit block.
The entry will be skipped with the hideNoEdit
flag set and editing disabled.
{
"label": "Label",
"field": "field_name",
"srid": "4326",
"fieldfx": "ST_asGeoJson(geom_4326)",
"type": "geometry",
"style": {
"strokeColor": "#e65100",
"fillColor": "#e65100",
"strokeWidth": 2,
"fillOpacity": 0.2
},
"dependents": ["pin"],
"hideNoEdit": true,
"edit": {
"modifyBtnOnly": {
"label": "Move Site"
},
"draw": {
"polygon": true
}
}
}
type: mvt_clone
allows you to create an infoj object from a different format: mvt
layer.
To use this, you must have a layer.json
in the workspace.json
that you wish to copy the thematic from.
This infoj object will then create a tickbox and the thematic from the other layer.json
when you select the location.
-
zIndex
(optional) - This allows control of the order of drawing. If thezIndex
for thetype: mvt_clone
is higher than for the geometries on the location, then thetype:mvt_clone
thematic will be drawn on top. -
display
(optional) - When set totrue
the thematic will load automatically when you click on a location. -
layer
- This is the layer that you wish to clone the thematic from. -
label
- This is the label associated with the checkbox in the infoj. -
query
- This is a query to select only the relevant geometries from the same table as is used in the layer to clone.
For instance if you click on a polygon and want to clone the thematic for hexagons that have a polygon_id associated to them, the query would beSELECT hexagons FROM table WHERE polygon_id=%{id}
. -
queryparams
- This is the parameters for the query. -
style
- If left off will default to the style from the layer you are cloning from, otherwise will use the style provided.
{
"type": "mvt_clone",
"zIndex": 99,
"display": true,
"layer": "footfall_2021",
"label": "Footfall Count",
"query": "footfall_rp",
"queryparams": {
"id": true
},
"style": {
"theme": {
"type": "graduated",
"field": "glx_ff_21",
"cat_arr": [
{
"value": "0",
"label": "0 - 5,000",
"style": {
"fillColor": "#8BB9E4"
}
},
{
"value": "5000",
"label": "5,000 - 25,000",
"style": {
"fillColor": "#a1ccbd"
}
}
]
}
}
}
type: vector_layer
allows you to create an infoj object from a query (this is the equivalent of mvt_clone
but for point data).
This infoj object will then create a tickbox and when checked will draw the points to the mapview.
You can apply thematic styling to this layer and use labels as you can with other layer formats.
-
zIndex
(optional) - This allows control of the order of drawing. -
display
(optional) - When set totrue
the points will load automatically when you click on a location. -
label
- This is the label associated with the checkbox in theinfoj
. -
query
- This is a query to select only the relevant geometries.
This requires a particular format as it cannot be asrc
but must be atemplate
NOTE - You need to return the geometry in the correct format for that layer type. e.g.wkt
requiresST_AsText(geom)
.
"query_vector": {
"template": "SELECT ST_AsText(geom_p_4326), thematic_field, thematic_label FROM table WHERE site_id=%{id}"
}
-
queryparams
- This is the parameters for the query.
You MUST passreduce:true
to the queryparameters. -
style
- The style for the points.
Note, to uselabel
andtheme/themes
you must passparams.fields
array containing thefields
used.
{
"label": "Label",
"type": "vector_layer",
"format": "wkt",
"srid": "4326",
"display": true,
"query": "query_vector",
"queryparams": {
"id": true,
"reduce": true
},
"params": {
"fields": [
"thematic_field",
"thematic_label"
]
},
"style": {
"default": {
"icon": {
"type": "dot",
"fillColor": "#f2fc"
}
},
"label": {
"field": "thematic_label",
"title": "Label"
},
"theme": {
"title": "Thematic",
"type": "graduated",
"field": "thematic_field",
"cat_arr": [
{
"value": 0,
"label": "0 to 500",
"style": {
"fillColor": "#f7fcf5",
"fillOpacity": 0.5
}
},
{
"value": 500,
"label": "500 to 750",
"style": {
"fillColor": "#e5f5e0",
"fillOpacity": 0.5
}
}
]
}
}
}
Editing is possible on locations, so the user could for instance alter a field name, add a comment or move a geometry and this would be stored to the database.
Adding toggleLocationViewEdits: true
will add a spanner to the location entry that can be toggled for editing.
This is particularly useful if any of your fields use formatting or fieldfx
.
This should be used as the default as it is much neater for the user.
It is also possible to edit field values within a location, and save these to the database.
"edit": true
If configured a placeholder will be set on the edit input element where available (eg. text, textarea, options)
"edit": {
"placeholder": "Select from list",
"options": ["A", "B"]
}
Three options here:
- Provide defined options
"edit": {
"options": ["A", "B"]
}
- Provide empty options array
This will then use thedistinct_values
template to get all values from the field on the table as provide them.
"edit": {
"options": []
}
- Provide query
This will then run the provided query to get the values for the options.
This query must in theworkspace.templates
object.
"edit": {
"query": "edit_options",
"options": []
}
If you wish to edit geometry, then we must specify this in the edit
object.
"infoj": [
{
"type": "geometry",
"display": true,
"field": "geom_p_4326",
"fieldfx": "ST_asGeoJSON(geom_p_4326)",
"edit": {
"geometry": true
}
}
]
- When you edit a geometry, you open up a panel to click modify geometry and then an extra button.
- To avoid this, you can specify
ModifyBtnOnly
as true, which will give the user a single click to modify geometries. - The added benefit of this is that you can control the label defined on the button, giving the user a tailored label rather than the default 'Modify Geometry'.
"edit": {
"geometry": true,
"modifyBtnOnly": {
"label": "Move Site"
}
}
Dependents allow us to set certain fields to be updated when another is edited.
For instance, if the user can edit type: geometry
we may wish to set the type: pin
as a dependent, so that the pin is always shown in the correct location.
We also set dependents
on a field that is not editable by the user, but will be edited via a trigger on the database side.
Here you can provide an array of field
values that you wish to reload upon changes to the field in question.
{
"type": "geometry",
"display": true,
"field": "geom_p_4326",
"fieldfx": "ST_asGeoJSON(geom_p_4326)",
"dependents": ["pin","field_1","field_2"],
"edit": {
"geometry": true
}
},
A Layer Dataview (chart or table) is linked to a particular layer. Here the query used to create the dataview would likely select all rows from the table associated with the layer.
These Layer Dataviews are created within the dataviews
object in the layer.json
file.
A Table Dataview returns a table to the tabview
. This uses the Tabulator Package to do so, please refer to the documentation for table formatting options.
"dataview_key": {
"target": "tabview",
"display": true,
"query": "query_name",
"placeholder": "No Data Available",
"queryparams": {
"table": true,
"filter": true
},
"viewport": true,
"mapChange": true,
"events": {
"rowClick": {
"util": "select",
"layer": "uk_health",
"zoomToLocation": true
},
"rowDblClick": {
"util": "select",
"zoomToLocation": true
}
},
"table": {
"selectable": true,
"layout": "fitColumns",
"columns": [
{
"title": "Field",
"field": "field",
"headerSort": false
},
{
"title": "Count",
"field": "value",
"headerSort": false,
"formatter": "toLocaleString"
}
]
}
}
Here we can provide:
-
Dataview Name
- This generates a checkbox with the name provided in the Dataviews pane of the layer. -
target: tabview
- This generates the dataview in the bar on the bottom of the MAPP window. -
display: true
(optional) - This generates the dataview and but hides it from display. By default this isfalse
. -
placeholder
(optional) - This will display the text string to the user when no data is returned. -
selectable: true
(optional) - This will allow the rows to be highlighted on hover
This must be provided inside thetables
object, and the query used must return an id column. -
selectable: true
must also be paired with theevents
object. -
events
- This allows you to provide any Tabulator event and a function to run when that event occurs.
Typically we would want to providerowClick: select
which would perform a function on a single click.
If we wish to return a location from a different layer (cross-layer selection), then within the event we need to provide the key of that layer (uk_health in the example above), otherwise it will just return the location within the current layer.
We can also provide on double click to select and also zoom to that location. -
viewport: true
(optional) - This will only return locations within the viewport (the map window) display.
The query must contain `WHERE true ${viewport}' for this to work. -
mapChange: true
(optional) - This will refresh the dataview each time you stop zooming or panning in the map display display. -
queryparams
- This provides the parameters you wish to pass to a query.
You can providetable: true
which will provide the table defined on the layer. This is especially useful when using a template but defining the table for each locale within the layer.json.
This requires the SQL query to containFROM ${table}
to ensure it only returns information from the relevant table location.
You can providefilter: true
which will pass the filters selected on the layer to the query. This requiresWHERE true ${filter}
to be added to the query.
But can provide whatever we want, perhaps atable
orfilter: true
to ensure all filters are applied to the dataview. -
formatter: toLocaleString
- This will add thousand separators to the number (1000 becomes 1,000).
headerFilters are provided to allow the user to filter the information in the Tabulator tables.
We have 3 headerFilters:
set
numeric
like
date
This returns a dropdown with multiple options of which any number can be selected.
{
"title": "Field",
"field": "field",
"headerFilter": "set",
"headerFilterParams": {
"placeholder": "Select to Remove",
"distinct": true,
"layerFilter": true,
"type": "ni"
}
}
The headerFilterParams allow you to provide:
- A placeholder that is used on the dropdown on initial load.
-
distinct: true
which will return all values in that field on the database. - You may also provide
options: ["A", "B"]
instead ofdistinct:true
. -
layerFilter: true
which will update the map with the filters applied within the table. -
type: ni
which will remove from the table those values selected. The default istype: in
.
This returns two input boxes Min and Max for numeric filtering.
{
"title": "Field",
"field": "numeric_field",
"headerFilter": "numeric"
}
This returns a free text box for filtering.
{
"title": "Field",
"field": "field",
"headerFilter": "like"
}
The field to use this on must be of type bigint
.
This returns two input boxes Min and Max for date filtering.
A full list of formatterParams for dates can be found here.
{
"title": "Field",
"field": "date_field",
"headerFilter": "date",
"formatter": "date",
"formatterParams": {
"options": {
"year": "numeric",
"month": "numeric",
"day": "numeric"
}
}
}
Adds a toolbar button which will clear all current headerFilter.
"toolbar": {
"clear_table_filters": true
}
- The
.download_csv
can be set to a value oftrue
which will just download the data using the built in Tabulator formatter on any Tabulatordataview
.
"dataviews": {
"table": {
"display": true,
"target": "tabview",
"query": "query_dv",
"toolbar": {
"download_csv": true
},
"table": {
"autoColumns":true,
"columns":[]
}
- You can also specify a custom object for the download the data which will specify: the fields, the titles and the formats of these fields.
-
string: true
- Add this to a field to escape any value (this is required to prevent the download incorrectly breaking lines at commas if they exist in a field value). - Header - To specify that the title of each field is used as the header column, pass a value of
true
, by default this isfalse
. - Separator - To specify the separator, by default this is a comma.
- Type - To specify the download type, by default this is UTF-8 CSV.
- Join - To specify the join, by default this is '\r\n'.
- Title - To specify the title, by default this is
file
.
"download_csv": {
"title": "DOWNLOAD_TITLE",
"header": true,
"fields": [
{
"field": "field_1",
"title": "Field 1",
"string": true
},
{
"field": "field_2",
"title": "Field 2"
}
]
}
A Chart Dataview returns a table to the tabview
. This uses the ChartJS Package to do so, please refer to the documentation for chart formatting options.
"Dataview Name": {
"target": "tabview",
"display": true,
"query": "query_name",
"queryparams": {
"table": true,
"filter": true
},
"chart": {
"options": {
"aspectRatio": 1.4,
"indexAxis": "x"
}
}
}
Here we can provide:
-
Dataview Name
- This generates a checkbox with the name provided in the Dataviews pane of the layer. -
target: tabview
- This generates the dataview in the bar on the bottom of the MAPP window. -
display: true
(optional) - This generates the dataview and but hides it from display. By default this isfalse
. -
queryparams
- This provides the parameters you wish to pass to a query.
You can providetable: true
which will provide the table defined on the layer. This is especially useful when using a template but defining the table for each locale within the layer.json.
This requires the SQL query to containFROM ${table}
to ensure it only returns information from the relevant table location.
You can providefilter: true
which will pass the filters selected on the layer to the query. This requiresWHERE true ${filter}
to be added to the query.