Monday, January 8, 2024

Enhance Oracle Analytics Custom Visualization Plug-Ins with Color Palettes

Color is a significant design element in data visualizations that contributes to a more compelling and engaging story for your audience, spontaneously capturing their attention. People intuitively associate colors with sentiments, brands, food, and other concepts. These associations make your visualizations more meaningful and easier to understand.

The Color Series property in Oracle Analytics contains various unique color palettes that you can select with ready-to-use visualizations. This article explains how to enable custom visualization plug-ins to directly inherit and consume these ready-to-use color palettes.

Figure 1 shows a canvas with four ready-to-use visualizations that display the default Redwood color series.

Enhance Oracle Analytics Custom Visualization Plug-Ins with Color Palettes
Figure 1: The Default (Redwood) Color Series

You can change the color of the visualizations in two ways:

1. As shown in figure 2, click the menu in the top-right corner of the canvas, click Workbook Properties, and select a color series. You can also add a new color palette by clicking the Add Palette option.

Enhance Oracle Analytics Custom Visualization Plug-Ins with Color Palettes
Figure 2: Steps to change color series option (method 1)

2. As shown in figure 3 and 4, click the menu in the top-right corner of the chart, select Color, click Manage Assignments, and select a color series.

Enhance Oracle Analytics Custom Visualization Plug-Ins with Color Palettes
Figure 3: Steps to change color series option (method 2)

Enhance Oracle Analytics Custom Visualization Plug-Ins with Color Palettes
Figure 4: Steps to change color series option (method 2)

By selecting the Glacier color series option for instance, all visualizations in the canvas inherit that color series.

Enhance Oracle Analytics Custom Visualization Plug-Ins with Color Palettes
Figure 5: The Glacier Color Series

Plug-in code changes to inherit the Color Series property


Color series changes don't apply automatically to custom visualizations. To achieve this, you update your custom plug-in code.

To understand the code changes, see the example with a custom plug-in called Oracle Analytics Marimekko custom visualization plug-in. You can download this plug-in from Oracle Analytics extensions library.

Enhance Oracle Analytics Custom Visualization Plug-Ins with Color Palettes
   Figure 6: Marimekko plug-in files

Open the marimekkoViz.js file. The script has two parts: the generateData function and the render function.

Enhance Oracle Analytics Custom Visualization Plug-Ins with Color Palettes

You must make a few changes in both parts of the code.

Changes in the generateData function


219          MarimekkoViz.prototype._generateData = function(oDataLayout, oTransientRenderingContext){
220           
221          var oDataModel = this.getRootDataModel();
222                if(!oDataModel || !oDataLayout){
223                    return;
224                }
225              //  this.setRowDisplayNames([]);
226              this.setRowDisplayNames(new Map());
227               var aAllMeasures = oDataModel.getColumnIDsIn(datamodelshapes.Physical.DATA);         
228                var nMeasures = aAllMeasures.length;
229                var nRows = oDataLayout.getEdgeExtent(datamodelshapes.Physical.ROW);
230                var nRowLayerCount = oDataLayout.getLayerCount(datamodelshapes.Physical.ROW);
231                var oDataLayoutHelper = oTransientRenderingContext.get(dataviz.DataContextProperty.DATA_LAYOUT_HELPER);
232                var oColorContext = this.getColorContext(oTransientRenderingContext);
233                var oColorInterpolator = this.getCachedColorInterpolator(oTransientRenderingContext, datamodelshapes.Logical.COLOR);
234    
235                var rowLabels = [];
236               for(var nRow = 0; nRow < nRowLayerCount; nRow++){
237                
238                    var rowKey = oDataLayoutHelper.getLogicalEdgeName(datamodelshapes.Physical.ROW, nRow);
239                    var displayName = oDataLayout.getLayerMetadata(datamodelshapes.Physical.ROW, nRow, data.LayerMetadata.LAYER_DISPLAY_NAME);
240                    this.getRowDisplayNames().set(rowKey, {order: nRow, name: displayName});
241                    if(rowKey == "row"){
242                        this.setXDisplayName(displayName);
243                    }
244                    else if(rowKey == "color") {
245                        if (displayName)
246                        this.setYDisplayName(displayName);
247                    }

<strong>var oColorContext = this.getColorContext(oTransientRenderingContext);</strong>

The variable oColorContext (line #232) fetches the color context from the oTransientRenderingContext.

The oTransientRenderingContext provides the context for rendering a visualization. It reads the color series label for each row from the input dataset (in the generateData function) using the color context object.

Next, refer to the switch case statement for 'row Type' as 'color' (line #277), as shown in the following code example. It reads the value from the color grammar in the visualization. 

Changes in the 'color' case:


264       switch (rowType) {               
265                       case "row":
266           month = row!="" ? row + ", "              +oDataLayout.getValue(datamodelshapes.Physical.ROW, nRowLayer, nRow, false)
267                                : oDataLayout.getValue(datamodelshapes.Physical.ROW, nRowLayer, nRow, false);
268                                  if(gmonth == "")
269                                   {
270                                  gmonth = month;
271                                   }
272                                   else{
273                                      gmonth = gmonth+','+month;
274                                   }
275                          xSet.add(month);
276                           break;
277                        case "color":
278                    colorObj = this.getDataItemColorInfo(oDataLayoutHelper, oColorContext, oColorInterpolator, nRow, 0);
279                           color_hash = colorObj.sColor;
280                           cause = colorObj.sSeriesColorLabel;
281                           break;
282                    }
283                }
284              var aOutput =[];
285           
286           
287                aOutput = {month: gmonth, cause: cause, value: value, color: color_hash, row: nRow};
288                if(value >= 0)
289                {
290                outputMap.push(aOutput);
291                }
292            }

The 'color' case:

case "color":<strong>
            </strong> colorObj = this.getDataItemColorInfo(oDataLayoutHelper, oColorContext, oColorInterpolator, nRow, 0);
                           color_hash = colorObj.sColor;
                           cause = colorObj.sSeriesColorLabel;
                           break;

The variable 'color_hash' stores the hex color code of the inherited color series and the variable 'cause' holds the value from the data visualization color grammar.

Changes in the render function


Refer to the CSS style property (line #599) in the Marimekko plug-in that returns 'd.color' to inherit the data visualization color series. 'd.color' returns the value stored in the 'color_hash' variable.

566       causes.append("rect")
567            .attr("data-row", function(d) {
568                return d.row;
569            })
570            .attr("y", function (d) { …
584            })
585            .attr("height", function (d) { …
594            })
595            .attr("width", function (d) { …
597            })
598            .style("fill", function (d) {
599                  return d.color;        
600            })
601            .on("mouseover", function(d) { …
607            })
608            .on("mousemove", function(d) { …
613            })
614            .on("mouseout", function(d) { …               
617            })
618            .on("click", function(d, i ){ …       
633            })
634            .on("contextmenu", function (d, i) { …
644            });

.style("fill", function (d) {
                  return d.color;         
            })

With the code changes listed above, the custom plug-in considers the selected color series, but the color change isn't reflected instantly. To have the custom visualization instantly reflect changes to the color palette, add the following lines of code:

1198    MarimekkoViz.prototype._OnDefaultColorSettingsChange = function(/*oClientEvent*/){
1199    var oTransientVizContext = this.createVizContext();
1200    if(!this._handleVizPlaceholderState(oTransientVizContext)){
1201       //this.readyForData({aEventTriggers:[DEFAULT_COLOR_SETTINGS_CHANGED_EVENT_TRIGGER]});
1202        var oTransientVizContext = this.assertOrCreateVizContext();
1203      var oTransientRenderingContext = this.createRenderingContext(oTransientVizContext);
1204      this._render(oTransientRenderingContext);
1205    }
1206  };
1207
1208 MarimekkoViz.prototype._doInitializeComponent = function() {
1209       
1210   MarimekkoViz.superClass._doInitializeComponent.call(this);
1211
1212   this.subscribeToEvent(events.types.INTERACTION_HIGHLIGHT, this.onHighlight, this.getViewName() + "." +       events.types.INTERACTION_HIGHLIGHT);
1213   this.subscribeToEvent(events.types.DEFAULT_COLOR_SETTINGS_CHANGED, this._onDefaultColorsSettingsChange, "**");
1214
1215 };

Add a function, 'Marimekkoviz.prototype._onDefaultColorSettingsChange' to render the required context (line #1198).

Add subscribeToEvent 'DEFAULT_COLOR_SETTINGS_CHANGED' (line #1213).

With these code changes, when the default settings of color changes in the workbook, it re-renders all visualizations to reflect the changes. For example, on selecting the Glacier color series, the custom visualization (Marimekko plug-in on the left) inherits the selected color series, as shown in figure 7.

Enhance Oracle Analytics Custom Visualization Plug-Ins with Color Palettes
Figure 7: The Glacier color series

Adjusting text font-color based on the background color


When you implement a custom color series in the plug-in, sometimes the font color isn't legible, as shown in figure 8:

Enhance Oracle Analytics Custom Visualization Plug-Ins with Color Palettes
Figure 8: Default font color for custom plug-ins

To work around this issue, the following code sample explains an approach to display text in a white font if the background color is dark and a black font for light-colored backgrounds.

767   .style("fill", function(d) {
768          var hex = d.color;
769                var red = parseInt(hex.substring(1, 3), 16);
770                var green = parseInt(hex.substring(3, 5), 16);
771                var blue = parseInt(hex.substring(5, 7), 16);
772
773                    console.log(red, green, blue);
774                    if ((red*0.299 + green*0.587 + blue*0.114) > 130) {
775                  return "black";
776                } else
777                return "white";
778            }

The 'd.color' holds the inherited data visualization color. Break the hex code into three pieces to extract the individual red, green and blue colors. Each two digits of the code represent a value in hexadecimal (base-16) notation. You can read about the conversion details online.

Once you have the intensities for the individual colors, you can determine the overall intensity of the color and choose the corresponding text color. 

The Marimekko plug-in considers a threshold value as 130. If the converted value exceeds 130, the font color is black and, if the value is less than 130, then the font color is white. You can select a threshold value based on your judgement. Figure 9 shows an example of this font color implementation.

Enhance Oracle Analytics Custom Visualization Plug-Ins with Color Palettes
Figure 9: Font colors based on background color in a Marimekko chart

Call to Action:


Download custom plug-in code from the Oracle Analytics Extensions Library. Edit the custom plug-in code as explained in this article to leverage the color series property of the canvas into your custom visualizations, just like in any other prebuilt visualizations.

Source: oracle.com

Related Posts

0 comments:

Post a Comment