Charts
It is recommended to read the documentation about Data beforehand.
The API at a Glance
Let's look at two examples of charts with static data and data coming from a MDX query.
Static Data
You can display a chart with static data:
import {ActiveUIConsumer, Container} from '@activeviam/activeui-sdk';
import _ from 'lodash';
import PropTypes from 'prop-types';
import React from 'react';
const configuration = {
type: 'scatter',
mapping: {
x: {from: 'x'},
y: {from: 'y'},
color: {from: ['category']},
r: {from: 'count'},
},
};
const headers = [
{value: 'x', caption: 'X', numeric: true},
{value: 'y', caption: 'Y', numeric: true},
{value: 'count', caption: 'Count', numeric: true},
{value: 'category', caption: 'Category', numeric: false},
];
const content = [
[20, 3, 10, 'A'],
[30, 1, 20, 'A'],
[18, 5, 13, 'B'],
[40, 2, 6, 'B'],
[14, 3, 18, 'B'],
];
const App = ({query}) => (
<Container
defaultValue={{
name: 'Simple Chart',
value: {
body: {
layers: [{configuration, query}],
},
containerKey: 'chart',
showTitleBar: true,
},
}}
/>
);
App.propTypes = {
query: PropTypes.object.isRequired,
};
export default () => (
<ActiveUIConsumer>
{({data: {toTable}}) => (
<App query={_.pick(toTable(headers, content), ['content', 'headers'])} />
)}
</ActiveUIConsumer>
);
import React from 'react';
import {render} from 'react-dom';
import {createActiveUI, ActiveUIProvider} from '@activeviam/activeui-sdk';
import App from './App';
const activeUI = createActiveUI();
render(
<ActiveUIProvider activeUI={activeUI}>
<App />
</ActiveUIProvider>,
document.getElementById('root'),
);
<div id="root"></div>
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
font-variant: tabular-nums;
}
.CodeMirror pre {
/* Using !important because CodeMirror will apply its own style after but we want to force this font stack. */
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace !important;
}
body {
margin: 0;
}
html,
body,
#root {
height: 100%;
}
Another example displaying in a Gantt chart:
import {ActiveUIConsumer, Container} from '@activeviam/activeui-sdk';
import _ from 'lodash';
import PropTypes from 'prop-types';
import React from 'react';
const getCell = date => ({value: date, caption: date.toLocaleDateString()});
const configuration = {
type: 'gantt',
mapping: {
start: {from: 'from', scaleType: 'time'},
end: {from: 'to', scaleType: 'time', grid: true},
y: {from: ['name']},
color: {from: ['name']},
},
leftMargin: 10,
rightMargin: 0,
bottomMargin: 15,
topMargin: 0,
};
const headers = [
{value: 'from', caption: 'From', numeric: true},
{value: 'to', caption: 'To', numeric: true},
{value: 'name', caption: 'Name', numeric: false},
];
const content = [
[getCell(new Date(2015, 5, 15)), getCell(new Date(2015, 5, 20)), 'Sprint 1'],
[getCell(new Date(2015, 5, 20)), getCell(new Date(2015, 6, 5)), 'Sprint 2'],
[getCell(new Date(2015, 6, 0)), getCell(new Date(2015, 6, 10)), 'Sprint 3'],
[getCell(new Date(2015, 6, 10)), getCell(new Date(2015, 6, 21)), 'Sprint 4'],
[getCell(new Date(2015, 6, 21)), getCell(new Date(2015, 7, 21)), 'UAT'],
[getCell(new Date(2015, 6, 21)), getCell(new Date(2015, 7, 5)), 'Testing'],
];
const App = ({query}) => (
<Container
defaultValue={{
name: 'Gantt Chart',
value: {
body: {
layers: [{configuration, query}],
},
containerKey: 'chart',
showTitleBar: true,
},
}}
/>
);
App.propTypes = {
query: PropTypes.object.isRequired,
};
export default () => (
<ActiveUIConsumer>
{({data: {toTable}}) => (
<App query={_.pick(toTable(headers, content), ['content', 'headers'])} />
)}
</ActiveUIConsumer>
);
import React from 'react';
import {render} from 'react-dom';
import {createActiveUI, ActiveUIProvider} from '@activeviam/activeui-sdk';
import App from './App';
const activeUI = createActiveUI();
render(
<ActiveUIProvider activeUI={activeUI}>
<App />
</ActiveUIProvider>,
document.getElementById('root'),
);
<div id="root"></div>
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
font-variant: tabular-nums;
}
.CodeMirror pre {
/* Using !important because CodeMirror will apply its own style after but we want to force this font stack. */
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace !important;
}
body {
margin: 0;
}
html,
body,
#root {
height: 100%;
}
As one can see we need to give two inputs to the chart, its data and its configuration. The configuration will be explained here.
You can look at the Gant sample for a live example.
From an MDX Query
Creating a chart from an MDX query is quite similar, and for example on the Sandbox one can do:
import {Container} from '@activeviam/activeui-sdk';
import React from 'react';
const configuration = {
type: 'scatter',
mapping: {
x: {from: '[Measures].[pnl.SUM]'},
y: {from: '[Measures].[contributors.COUNT]'},
row: {from: ['[Booking].[Desk].[Desk]']},
color: {from: ['[Currency].[Currency].[Currency]']},
text: {from: '[Measures].[pv.SUM]'},
},
};
const mdx = `
SELECT NON EMPTY {
[Measures].[contributors.COUNT],
[Measures].[pnl.SUM],
[Measures].[pv.SUM]
} ON COLUMNS,
NON EMPTY CrossJoin(
Hierarchize(DrilldownLevel([Booking].[Desk].[ALL].[AllMember])),
Hierarchize(DrilldownLevel([Currency].[Currency].[ALL].[AllMember]))
) ON ROWS FROM [EquityDerivativesCube]`;
const App = () => (
<Container
defaultValue={{
name: 'Chart With Multiple Scatter Plots',
value: {
body: {
layers: [{configuration, query: {mdx}}],
},
containerKey: 'chart',
showTitleBar: true,
},
}}
/>
);
export default App;
import React from 'react';
import {render} from 'react-dom';
import {createActiveUI, ActiveUIProvider} from '@activeviam/activeui-sdk';
import App from './App';
const activeUI = createActiveUI();
const servers = activeUI.queries.serversPool;
servers.addActivePivotServer({url: "https://your.activepivot.server"});
render(
<ActiveUIProvider activeUI={activeUI}>
<App />
</ActiveUIProvider>,
document.getElementById('root'),
);
<div id="root"></div>
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
font-variant: tabular-nums;
}
.CodeMirror pre {
/* Using !important because CodeMirror will apply its own style after but we want to force this font stack. */
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace !important;
}
body {
margin: 0;
}
html,
body,
#root {
height: 100%;
}
The main difference with the static data example is that the mapping given in the configuration of the chart must refer to the unique names of the level or measures contained in the query result (see TableFromCellSet
).
Configuration
Let's dive more into the configuration of the chart itself.
Attribute Mapping
All chart types display a graphical element per tuple in the Table
they receive.
Each type of chart has its own list of graphical properties that can be configured, they are called chart attributes.
The main goal of the configuration is to map columns of the input Table to the graphical properties of the displayed elements.
So for instance on a scatter plot chart that displays a circle per tuple in the data, the list of attributes that can be mapped is:
Name | Type | Description | Mandatory |
---|---|---|---|
x | numeric | The circle center x coordinate | Yes |
y | numeric | The circle center y coordinate | Yes |
color | color | The color filling the center | |
strokeColor | color | The color of the border of the circle | |
strokeWidth | color | The size of the border of the circle | |
r | numeric | the radius of the circle | |
text | text | The text to display next to the circle | |
textColor | color | The color of the text |
To map any of these attributes to a column of the table, one just has to add an entry in configuration.mapping
with the name of the attribute as key.
So mapping x
to a Table column whose header value is v
is made with:
{
mapping: {
x: {
from: 'v';
}
}
}
Attribute Type
As you could see in the table listing the attributes of the scatter plot, attributes have different types. This type is here to constrain the mapping between the data and the chart attributes to be meaningful. For instance the goal of a scatter plot is to compare two measures by putting them on the X and Y axes to visually detect correlation clustering and so on... So it makes no sense to put on these axes a currency information for instance. If one wants to plot a measure against a currency then an histogram will be more suited. This is why the X attribute of these two chart types is of type ordinal instead of numeric.
The chart library will read the isNumeric
information of the header to decide if it can be mapped to an attribute.
Columns with isNumeric
set to true are called numeric columns, the other ones are called ordinal columns (in reference to the same d3 naming).
There are four types of attributes, each one of them can or not be mapped to numeric columns or ordinal columns.
Type | Numeric | Ordinal | Description |
---|---|---|---|
numeric | Yes | No | Represent a numerical chart attribute that can take any real value. |
ordinal | No | Yes | Represent a chart attribute that can only have a finite set of values, like the positions on a histogram X axis. |
color | Yes | Yes | Will be used as a color in a chart. This attribute can be mapped to a numeric or an ordinal column. When mapped to a numeric column a gradient will be created to convert the value to a color, when mapped to an ordinal column one color will be picked per value found in the column among a palette of colors. |
text | Yes | Yes | Will print the caption of the corresponding cell in the chart, be it a numeric or an ordinal column. |
Attributes of type numeric
can only be mapped to a single numeric column: it doesn't make sense to map the radius of the scatter plot circle to contributors.COUNT
and pnl.SUM
, we can use only one of the two values.
On the other hand, ordinal
attributes can be mapped to multiple columns.
This will be converted to a cartesian product in the charts library.
So, for instance, we can map the scatter plot circle color to a first column with 3 distinct values and a second column with 4 distinct values.
The charts library will create a color scale with 12 different colors for all the possible combinations.
Mapping Value
The mapping part of the configuration of a chart is a map whose keys are attribute names and the values are called mapping values.
There are two possible types of mapping values: constant and dynamic. The constant type should be used when all elements in the charts have the same value for this attribute, otherwise the dynamic type should be used.
To define a constant mapping, we use the key value
instead of from
in the mapping value.
So for instance to have all circles of a scatter plot pink one can write:
{
mapping: {
color: {
value: 'pink';
}
}
}
In opposition, the dynamic mapping uses the from
key.
Its value depends on the type of the attribute, since numeric attributes can only be mapped to a single column the value of the mapping value will directly be the value of the header of the Table column that we want to map to.
When mapping to ordinal value, we will by contrast use an array because in this situation we can map to multiple columns.
The UI will handle this automatically but you have to be careful when writing your own chart configuration: not putting an array where the charts library expects an array will prevent the chart from rendering.
If we look back at the configuration of the scatter plot on a MDX query:
mapping: {
x: {from: '[Measures].[pnl.SUM]'},
y: {from: '[Measures].[contributors.COUNT]'},
row: {from: ['[Booking].[Desk].[Desk]']},
color: {from: ['[Currency].[Currency].[Currency]']},
}
This is the reason why the mapping values of row and color use arrays and the mapping values of x and y use directly a string, even if the arrays contain only one element.
You can use this mechanism to use a numerical column like an ordinal one, by putting its header value into an array of size one as the
from
of an ordinal attribute. So for instance if your Table has only 3 different values for a given numerical column, mapping it to a color this way will map one color to each of these values instead of creating a gradient that respects the numerical values.
Mandatory Attributes
As you could see in the table listing the attributes of the scatter plot, X and Y are mandatory. This means a chart will refuse to render if any of them is not mapped to a data column. An explicit error message will be rendered instead. Each chart type has its own list of mandatory attributes.
Common Attributes
All chart types have different attributes, but there are a few attributes that are common to all charts:
- rows and columns: these two ordinal attributes can be used to display multiple charts (called sub-charts) side by side in multiple rows and columns. The only chart types that do not work with them are Geographical ones.
- cardinality: this attribute doesn't map to any visual property of any chart. It can be used when connecting a Chart to a MDX query, mapping a new level to this attribute will make the UI add this level in the MDX query, crossJoining it on the ROWS axis thus multiplying the number of displayed points (the cardinality of the chart) by the number of members of this level.
Automatic Mapping
In addition to the mapping declared in the configuration given to the charts library, each type of chart contains rules on how to map additional attributes automatically based on the currently mapped ones.
This is called configuration post-processing.
This is this mechanism that will map for instance the lineColor
attribute of a Line Chart to be the same as line
.
Each chart type has different rules per attributes that are triggered if no mapping is given and if the rule can be applied.
So the later rule will not apply if lineColor
is already mapped (even on a constant color), or if line
is not mapped.
If an automatic mapping is not wanted, the simplest way to disable it is to map the attribute to a constant value.
Mapping Options
The dynamic mapping object can have more keys than just from
, the other keys are options that control the way the mapping is performed.
Here is the list of options that one can use:
Key | Available on attributes | Accepted value | Description |
---|---|---|---|
grid | on Axes | Boolean | Render a grid on the given axis. |
noAxis | on Axes | Boolean | Render or not the axis. False by default. |
notTime | on Axes and Ordinal | Boolean | If set and true disables rendering the members on a time axis respecting the time scale (producing the same type of charts not respecting time dimensions that ActivePivot Live 3 produced). |
labelsInterval | on Axes and Ordinal | Integer | Display only one member every n along the axis to avoid captions overlap. |
ticks | on Axes and Numeric | Integer | Give the number of ticks to display along the axis. If not set d3 decides automatically how many ticks to display but this might be incorrect in some edge cases and can be customized here. |
scaleType | Numeric | linear , sqrt , pow , log | Indicate the type of numerical function used to convert the data in the column to the graphical property in the chart. |
factor | Numeric and not on Axes | Number | A linear factor applied to the graphical property (after the scaleType). |
exponent | Numeric and scaleType is pow | Number | Choose the exponent of the power function to use. Defaults to 1. |
center | Numeric | Boolean | Enforce the range of the created d3 scale to be centered on zero. |
forcedMin | Numeric | Number | Enforce the minimum of the created d3 scale. |
forcedMax | Numeric | Number | Enforce the maximum of the created d3 scale. |
padding | Numeric | Number | Adds some padding to the created d3 scale. The value entered will be added to the maximum value of the range and substracted to the minimum value of the range. Useful to prevent elements from overflowing the chart. This setting is ignored if forcedMin or forcedMax is set. |
colors | Colors mapped to Ordinal | activeviam , d3-10 , google-chart | Choose the palette of colors to use. |
colors.min | Color mapped to Numeric | Color | Change the color to use in the gradient for the smallest value. |
colors.max | Color mapped to Numeric | Color | Change the color to use in the gradient for the highest value. |
colors.intermediate | Color mapped to Numeric | Color | Change the color to use at the middle of the gradient. |
formatter | on Numeric Axes | Plugin | A serialized formatter plugin implementation. |
timeFormatter | on Time Axes | Plugin | A plugin of type plugin.types.chartTimeFormatter. |
tickSizeInner | on Axes | Integer | The inner tick size controls the length of the tick lines. |
tickSizeOuter | on Axes | Integer | The outer tick size controls the length of the square ends of the domain path. |
Integer means a natural number (1, 2, 3, etc...).
Number means a real number (1.2, 1.3, etc...).
Axes attributes are x
and y
.
For example, if you want to change the color scheme on a chart, you can modify the colors
mapping option in the following way, where the name of the color scheme should match an implementation key of plugin ordinal-color-scale
:
mapping: {
x: {from: '[Measures].[pnl.SUM]'},
y: {from: '[Measures].[contributors.COUNT]'},
color: {from: ['[Currency].[Currency].[Currency]'], colors: 'd3-10'}
}
Type
In the configurations
object, the type
attributes define the type of chart to use.
The built-in implementations are:
- scatter
- line
- lineArea
- histogram
- horizontalHistogram
- gantt
- pie
- gauge
- treeMap
- pointMap
- vectorMap
- histogramMap
Other Configuration Properties
The configuration can take other parameters outside of the mapping. These parameters change the rendering of the non data-related items of the chart. We list here the properties read by all types of chart, some chart types read additional ones.
key | Type | Effect |
---|---|---|
backgroundColor | Color | background color of the chart |
backgroundBorderRadius | Integer | radius of the background in pixels |
topMargin | Integer | margin top around the chart drawing area |
bottomMargin | Integer | margin bottom around the chart drawing area |
leftMargin | Integer | margin left around the chart drawing area |
rightMargin | Integer | margin right around the chart drawing area |
titleMargin | Integer | height left for the title of each sub-chart |