Hexagon Geospatial
MENU

API

M.App Portfolio provides a modern, cloud-based platform for creating and delivering diverse geospatial web applications.
Through the M.App Studio, our partners can design, build, and deploy their own Hexagon Smart M.Apps.
Showing results for 
Search instead for 
Do you mean 

Working with the GVC Javascript Library

by Technical Evangelist on ‎05-13-2016 03:41 AM (1,347 Views)

Working with the GVC Javascript Library

 

GVC API is part of Hexagon Geospatial Smart M.App solution ©.

 

GVC API and GVC configuration are part of the Smart M.App Business Intelligence BI API.

 

Kind: global namespace

 

Version: 0.2.11-SNAPSHOT

 

Last modified: 2016-05-13

 

API Reference: See article API Reference.

 

Dependencies

 

Normally GVC is delivered within the Smart M.App framework where all the dependencies are already resolved. For reference the dependencies are:

 

  • DC.js Dimensional Charting Javascript library. Version: 2.0.0-beta.19
  • D3 Data Driven Documents Javascript Library. Version: 3.5.12
  • Crossfilter JavaScript library for exploring large multivariate datasets. Version: 1.3.11
  • Leaflet JavaScript library for mobile-friendly interactive maps. As part of the Smart M.App © solution, GVC library provides renderers for the Smart M.App Leaflet map adapter. Version: 0.7.3

Stage configuration

 

Goal of the GVC library is to be able to define complex BI scenes with configuration. When dataStage is created, it should take a unique name as its sole formal parameter.

 

gvc.dataStage("stageName")

 

The returned dataStage object is the entry point for

  • configuring BI
  • customizing BI

 

Before the stage is rendered, it must be configured. Configuration of the stage consists of:

  • features
  • table with attributes (optional if GeoJson features contain properties)
  • stageModel (it may be passed to the render method)
  • widgets configuration
  • choropleth configuration (emphasised as a special type of widgets as it interferes with the mapping engine)

 

Features

 

Features are passed as GeoJSON objects. It is also necessary to provide unique id for the features. This name should match the id defined in the stageModel.

 

stage.features(featureDesc, geojson);
  • {Object} featureDesc - featureDescription
    • {String} id - id of the feature class
    • {Boolean} convertToTable - (Optional) Whether to convert GeoJSON attributes to a data table
    • {String} key - (Optional) Primary Key of the data table (unique attribute). it is recommended to define it in the stage model
  • {GeoJSON} geojson - geojson feature collection object

 

Table with attributes

 

Currently it is possible to pass only 1 data table:

 

stage.table(tableData)
  • {Object[]} tableData - this is an array of plain javascript objects where each array element represents the row and each object's property name represents the column

Data table can be simply obtained from a CSV data source by leveraging the d3.csv function.

 

Working with maps

 

Within the Smart M.Apps that use Map or BI Map components, only the Smart M.App $GP API is supported for manipulating the map state. Direct manipulations on the Leaflet L object handle is not recommended, as it may collide with behavior of this object driven by the Smart M.App.

 

For development, prototyping and using the Custom Panel component, it is possible to use the GVC library with the Leaflet L object, but it is important to remember of a few constraints:

 

  • any sophisticated layer management should be avoided - it will be impossible to port this code to the Map/BI Map Smart M.App later
  • it is recommended to instantiate gvc.chart.choropleth objects as bound to leaflet L.LayerGroup objects:
    ///...
    var lmap = new L.map('map', {
    zoomControl: false,
    layers: [
        L.tileLayer("http://{s}.example.com/{z}/{x}/{y}.png", {maxZoom: 18})
    ]
    });
    ///...
    var layerGroup = L.layerGroup();
    layerGroup.addTo(lmap);
    var choropleth = gvc.chart.choropleth("map", layerGroup);
 this recommendation is formulated in order to make sure that the resulting SVG elements will be present within one logical layer, so that it will be easier to port such custom code to the Smart M.App. In the Smart M.App layer management is performed by the mapping engine and should be accessed only with a dedicated API.

 

Nevertheless, please find a Leaflet example as follows:

 

    var lmap = new L.map('map', {
        zoomControl: false,
        layers: [L.tileLayer("http://{s}.example.com/{z}/{x}/{y}.png", {
            maxZoom: 18
        })]
    }).setView([52.0068, -0.7328], 12);

    var layerGroup = L.layerGroup();
    layerGroup.addTo(lmap);

    queue()
        .defer(d3.json, "../../data/geometries.json")
        .defer(d3.csv, "../../data/attributes.csv")
        .await(ready);

    var stage;

    function ready(error, geometry, attributes) {
        if (error) {
            return console.warn(error);
        }
        stage = gvc.dataStage("example");
        stage.target('map', lmap);
        stage.table(attributes);
        stage.features("features", geometry, false, "uniqueId");
        stage.widgets(chartModel, gvc.chart.row(div));
        stage.widgets(thematicModel, gvc.chart.choropleth(lmap, layerGroup));
        stage.render(stageModel);
    }

 

Adding and removing widgets dynamically

 

Widgets can be added and removed dynamically.

 

To add widgets dynamically, use dataStage.mountWidgets method with the same parameters as dataStage.widgets. mountWidgets additionally redraws the stage.

 

To remove widgets dynamically, use dataStage.unmountWidgets passing either widgetId or widgetModels.

 

Adding custom DC widgets to the data stage

 

Sometimes it is desirable to use widgets which are not present (yet?) in the GVC library. To do it, just use:

 

    var composite = dc.compositeChart("#test_composed");
    // configure the chart
    dataStage.widgets({ id: "customModel", target: "test_composed" }, composite);

(or dataStage.mountWidgets respectively)

 

Expressions syntax

 

This section describes expressions that can be used in StageModel configuration. The same expressions may be used in the M.App Studio © wizard.
Expressions are parsed from strings.

 

Operators can be tested using gvc.formula.parse("...").evaluate({/.../});

 

  • Aggregations

    • $sum(attribute) where attribute is a field (or a "column name" in the facts table) - computes sum of selected values of the attribute
    • $avg(attribute) where attribute is a field (or a "column name" in the facts table) - computes average value of the attribute
    • $ratio(attribute1, attribute2) where attribute1 and attribute2 are fields (or "column names" in the facts table). Ratio of $sum(attrubute1) to $sum(attribute2)
    • $count variable dynamically evaluated each time when the selected number of rows changes
  • Operators

    • + Addition x + y
      gvc.formula.parse("x + y").evaluate({x: 2, y: 3})
      5
      
    • - Subtraction x - y
      gvc.formula.parse("x - y").evaluate({x: 2, y: 3})
      -1
      
    • * Multiplication x * y
      gvc.formula.parse("x * y").evaluate({x:, y: 3})`
      6`
      
    • / Division x / y
      gvc.formula.parse("x / y").evaluate({x:, y: 3})
      0.6666666666666666
      
    • % Modulo x % 2
      gvc.formula.parse("x % y").evaluate({x:, y: 3})
      2
      
    • ^ Power x^2
      gvc.formula.parse("x^y").evaluate({x:, y: 3})
      8
      
    • , Append. x,y
      gvc.formula.parse("x, y").evaluate({x:, y: 3})
      [2,3]
      
    • || Concat. x||y
      gvc.formula.parse("x||y").evaluate({x:2,y:3})
      "23"
      
    • == equal. x==y
      gvc.formula.parse("x==y").evaluate({x:2,y:3})
      false
      
    • != notEqual x!=y
      gvc.formula.parse("x!=y").evaluate({x:2,y:3})
      true
      
    • > greaterThan x>y
      gvc.formula.parse("x>y").evaluate({x:2,y:3})
      false
      
    • < lessThan. x<y
      gvc.formula.parse("x<y").evaluate({x:2,y:3})
      true
      
    • >= greaterThanEqual. x >= y
      gvc.formula.parse("x>=y").evaluate({x:2,y:3})
      false
      
    • <= lessThanEqual. x <= y
      gvc.formula.parse("x<=y").evaluate({x:2,y:3})
      true
      
    • and andOperator x and y
      gvc.formula.parse("x and |y").evaluate({x:2,y:3})
      true
      
    • or orOperator. x or y
      gvc.formula.parse("x or y").evaluate({x:2,y:3})
      true
      
  • Functions
    • sin Math.sin
      gvc.formula.parse("sin(x)").evaluate({x:90})
      0.8939966636005579
      
    • cos Math.cos
      gvc.formula.parse("cos(x)").evaluate({x:90})
      -0.4480736161291702
      
    • tan Math.tan
      gvc.formula.parse("tan(x)").evaluate({x:90})
      -1.995200412208242
      
    • asin Math.asin
      gvc.formula.parse("asin(x)").evaluate({x:1})
      1.5707963267948966
      
    • acos Math.acos
      gvc.formula.parse("acos(x)").evaluate({x:1})
      0
      
    • atan Math.atan
      gvc.formula.parse("atan(x)").evaluate({x:1})
      0.7853981633974483
      
    • sinh sinh
      gvc.formula.parse("sinh(x)").evaluate({x:1})
      1.1752011936438014
      
    • cosh cosh
      gvc.formula.parse("cosh(x)").evaluate({x:1})
      1.5430806348152437
      
    • tanh tanh
      gvc.formula.parse("tanh(x)").evaluate({x:1})
      0.7615941559557649
      
    • asinh asinh
      gvc.formula.parse("asinh(x)").evaluate({x:1})
      0.8813735870195429
      
    • acosh acosh
      gvc.formula.parse("acosh(x)").evaluate({x:1})
      0
      
    • atanh atanh
      gvc.formula.parse("atanh(x)").evaluate({x:0})
      0
      
    • sqrt Math.sqrt
      gvc.formula.parse("atanh(x)").evaluate({x:4})
      2
      
    • log Math.log
      gvc.formula.parse("log(x)").evaluate({x:Math.E})
      1
      
    • lg log10
      gvc.formula.parse("lg(x)").evaluate({x:10})
      1
      
    • log10 log10
      gvc.formula.parse("log10(x)").evaluate({x:10})
      1
      
    • abs Math.abs
      gvc.formula.parse("abs(x)").evaluate({x:-10})
      10
      
    • ceil Math.ceil
      gvc.formula.parse("ceil(x)").evaluate({x:9.2})
      10
      
    • floor Math.floor
      gvc.formula.parse("ceil(x)").evaluate({x:9.7})
      9
      
    • round Math.round
      gvc.formula.parse("ceil(x)").evaluate({x:9.5})
      10
      
    • trunc Truncate
      gvc.formula.parse("trunc(x)").evaluate({x:-9.7})
      -9
      
    • - neg
      gvc.formula.parse("-x").evaluate({x:-9.7})
      9.7
      
    • + plus
      gvc.formula.parse("+x").evaluate({x:"2"})
      2
      
    • exp Math.exp
      gvc.formula.parse("exp(x)").evaluate({x:"2"})
      7.3890560989306495
      
    • random random
      gvc.formula.parse("random()").evaluate({})
      0.2676440024830653
      
    • fac factorial
      gvc.formula.parse("fac(x)").evaluate({x:5})
      120
      
    • min Math.min
      gvc.formula.parse("min(x,y)").evaluate({x:5, y:4})
      4
      
    • max Math.max
      gvc.formula.parse("max(x,y)").evaluate({x:5, y:4})
      5
      
    • hypot returns the square root of the sum of squares of its arguments
      gvc.formula.parse("hypot(x,y,z)").evaluate({x:5, y:4, z:3})
      7.0710678118654755
      
    • pow Math.pow
      gvc.formula.parse("pow(x,y)").evaluate({x:5, y:4})
      625
      
    • atan2 Math.atan2
      gvc.formula.parse("atan2(x,y)").evaluate({x:8, y:4})
      1.1071487177940904
      
    • if condition
      gvc.formula.parse("if(x<2, x, if(y<z, y, z))").evaluate({x:2, y:4, z: 5})
      4
      
    • asNum asNum
      gvc.formula.parse("asNum(x)").evaluate({x:"2.3"})
      2.3
      
  • Constants
    • E Math.E
      2.718281828459045
      
    • PI Math.PI
      3.141592653589793
Comments
by Technical Evangelist
‎11-11-2016 12:20 AM - edited ‎11-11-2016 12:20 AM

An interesting question from SMAPP forum - how does the $avg() function treat null values? Could it be possibly enhanced to ignore them? Similar for $count().

 

Jan