Part 2: Adding properties to the visualization
In part 1 of this tutorial, we added a palette property for the colors of the scatter
points. In part 2 we will add some more properties to the visualization like a title, point shape,
x- and y maximum, and show title flag. We will see various options for defining a property, like a
default value and the allowNull
flag, and property groups.
Before you start
Make sure you have completed Part 1: Creating a custom visualization or you have downloaded the source code for part 1.
Step 1: Modify the vizdef.xml file
We already saw that property definitions are part of the vizdef.xml file. In this step we will not only add properties, but we also organise the properties in property groups.
Property groups are a hierarchical organisation of properties. The host application will often show property groups as separate tabs or panels in the UI. Placing a property of your custom visualization in a group will make the property appear in the corresponding place in the UI.
For the scatter visualization, we want to define the following properties structure:
- visualization (group)
- general (group)
- color - palette property that we added in step 1 of part 1.
- pointShape - shape of a scatter point, ("circle" or "square").
- background - url to a background image.
- showBackground - flag that indicates whether the background should be displayed.
- axis (group)
- xmax - maximum value on x-axis, or null for automatic.
- ymax - maximum value on y-axis, or null for automatic.
- general (group)
The vizdef.xml entries for these properties look as follows:
<properties>
<group name="general">
<palette name="color" slot="categories" />
<enum name="pointShape" defaultValue="circle">
<possibleValue>circle</possibleValue>
<possibleValue>square</possibleValue>
</enum>
<string name="background" defaultValue="" />
<boolean name="showBackground" defaultValue="true" />
</group>
<group name="axis">
<number name="xmax" allowNull="true" />
<number name="ymax" allowNull="true" />
</group>
</properties>
Two attributes to notice here are defaultValue
and allowNull
.
The defaultValue
attribute represents the initial value that the property will get.
The allowNull
attribute indicate if null
values for the property
are allowed. By default, null
values are not allowed. For your custom visualization
code this means in the default situation you can always rely on a non-null value when calling
Properties.get
.
Step 2: Add code in Main.ts
pointShape
Changing the shape of a point is easy enough, since for each possible enum value there is a corresponding d3 symbol type available. Replace the current code that determines the palette and shape to:
// Determine color palette and shape from the properties.
const palette = props.get( "color" );
const shape = d3.symbol().size( 256 );
if ( props.get( "pointShape" ) === "square" )
shape.type( d3.symbolSquare );
else
shape.type( d3.symbolCircle );
If you want to support more that just these two shape types, feel free to extend this code a bit
more. Maybe you want to use a switch
statement to select the correct symbol type,
or use a lookup map.
Notice that the value of an enum property is always a string. We can safely compare the property
value with the literal string "square"
, or we can use the value of the property in
a switch statement.
xmax and ymax
In part 1 we already defined the domain for our axes by calling getDomain
on the
data. If xmax
or ymax
are non-null, we can use these property
values instead. So the code to create the y-axis should be changed as follows:
Line | Code |
---|---|
1 2 3 4 5 6 7 8 9 10 11 |
// Create the y-axis. const yHeight = _info.node.clientHeight - 2 * margin - xHeight; const yDomain = data.cols[ YPOS ].domain.asArray(); // [min, max] const yMax = props.get( "ymax" ); if ( yMax !== null ) yDomain[ 1 ] = yMax; const yScale = d3.scaleLinear().range( [ yHeight, 0 ] ).domain( yDomain ); if ( yMax === null ) yScale.nice(); // apply nice scale only if scale is automatic. const yAxis = svg.select<SVGGElement>( ".yaxis" ).call( d3.axisLeft( yScale ) ); const yWidth = yAxis.node().getBBox().width; |
The call to props.get( "ymax" )
on line 4 will return either
null
or a valid number. This is because allowNull = true
was set
on the property.
The code change for the x-axis is now trivial:
Line | Code |
---|---|
1 2 3 4 5 6 7 8 9 10 11 |
// Create the x-axis and position at bottom of y-axis. const xWidth = _info.node.clientWidth - yWidth - 2 * margin; const xDomain = data.cols[ XPOS ].domain.asArray(); // [min, max] const xMax = props.get( "xmax" ); if ( xMax !== null ) xDomain[ 1 ] = xMax; const xScale = d3.scaleLinear().range( [ 0, xWidth ] ).domain( xDomain ); if ( xMax === null ) xScale.nice(); // apply nice scale only if scale is automatic. const xAxis = svg.select<SVGGElement>( ".xaxis" ).call( d3.axisBottom( xScale ) ); xAxis.attr( "transform", `translate(0,${yHeight})` ); |
background and showBackground
To add a background to the scatter visualization, we add the following code to the
update
methods, just before you create the y-axis:
Line | Code |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 |
// Set the background image. let urlImage = null; if ( props.get( "showBackground" ) ) { const image = props.get( "background" ); if ( image !== "" ) urlImage = `url(${image})`; } _info.node.parentElement.style.backgroundImage = urlImage; // Create the y-axis. ... |
This code changes the backgroundImage
style of the parent element of the svg.
The parent of the svg is actually the _node
that was passed to us in
create
.
Step 3: Run and test the visualization
Create a new dashboard or report in IBM® Cognos Analytics and add the 'Preview Visualization'. After adding some data you should see the scatter visualization in action. Try changing some of the properties that we have just added. You will see that the properties have been added to the visualization tab and the text tab respectively.
- Download the source code for part 2.