Databound objects are similar to static objects, however they typically deal with data selection. We will be changing the color associated with the data point.
See commit for what was added at this step.
Similar to static objects, we will define another object in the capabilities
colorSelector
is the internal name that will be referenced in the dataView
.
displayName
is the name that will be shown on the property pane.
fill
is a StructuralObjectValue
and is not associated with a primitive type.
"colorSelector": {
"displayName": "Data Colors",
"properties": {
"fill": {
"displayName": "Color",
"type": {
"fill": {
"solid": {
"color": true
}
}
}
}
}
}
For more information, see the section about using Objects.
Similarly with static objects, we will need to retrieve object details from the dataView
. However, instead of the object values being within metadata, the object values are associated with each category.
/**
* Gets property value for a particular object in a category.
*
* @function
* @param {DataViewCategoryColumn} category - List of category objects.
* @param {number} index - Index of category object.
* @param {string} objectName - Name of desired object.
* @param {string} propertyName - Name of desired property.
* @param {T} defaultValue - Default value of desired property.
*/
export function getCategoricalObjectValue<T>(category: DataViewCategoryColumn, index: number, objectName: string, propertyName: string, defaultValue: T): T {
let categoryObjects = category.objects;
if(categoryObjects) {
let categoryObject: DataViewObject = categoryObjects[index];
if(categoryObject) {
let object = categoryObject[objectName];
if(object) {
let property: T = object[propertyName];
if(property !== undefined) {
return property;
}
}
}
}
return defaultValue;
}
See objectEnumerationUtility.ts for source code.
Each color is now associated with each category inside dataView
. We will set each data point to its cooresponding color.
for (let i = 0, len = Math.max(category.values.length, dataValue.values.length); i < len; i++) {
let defaultColor: Fill = {
solid: {
color: colorPalette.getColor(category.values[i]).value
}
}
barChartDataPoints.push({
category: category.values[i],
value: dataValue.values[i],
color: getCategoricalObjectValue<Fill>(category, i, 'colorSelector', 'fill', defaultColor).solid.color,
selectionId: host.createSelectionIdBuilder()
.withCategory(category, i)
.createSelectionId()
});
}
enumerateObjectInstances
is used to populate the property pane with objects.
For this instance, we would like a color picker per category we have. Each category be rendered on the property pane.
We will do this by adding an additional case to the switch statement for colorSelector
and iterate through each data point with the associated color.
Selection is required to associate the color with a datapoint.
/**
* Enumerates through the objects defined in the capabilities and adds the properties to the format pane
*
* @function
* @param {EnumerateVisualObjectInstancesOptions} options - Map of defined objects
*/
public enumerateObjectInstances(options: EnumerateVisualObjectInstancesOptions): VisualObjectInstanceEnumeration {
let objectName = options.objectName;
let objectEnumeration: VisualObjectInstance[] = [];
switch(objectName) {
case 'enableAxis':
objectEnumeration.push({
objectName: objectName,
properties: {
show: this.barChartSettings.enableAxis.show,
},
selector: null
});
break;
case 'colorSelector':
for(let barDataPoint of this.barDataPoints) {
objectEnumeration.push({
objectName: objectName,
displayName: barDataPoint.category,
properties: {
fill: {
solid: {
color: barDataPoint.color
}
}
},
selector: barDataPoint.selectionId.getSelector()
});
}
break;
};
return objectEnumeration;
}