cancel
Showing results for 
Search instead for 
Did you mean: 

Heat Map Formatting and Legend Bug

gwolfe
10 - ETL
10 - ETL

Hey! Does anyone know how to:
1. Know how to get rid of all the white space at the top of this widget?

2. Know how to widen the first column with the headers?

3. A work-around for the bug on the legend where it breaks anytime a filter is touched? 

Thanks in advance!

gwolfe_0-1682613253915.png

 

4 REPLIES 4

Ido_QBeeQ
9 - Travel Pro
9 - Travel Pro

Hey @gwolfe 

We'd be happy to help where is this plugin/script from? If you send it over we can have one of our Sisense experts have a look.

QBeeQ develop a wide range of advanced visualisations which can be found in our Advanced Data Viz PowerUp,

This includes a Dynamic Heatmap which can be configured in a radial, semi-circular or flat view,

Please do not hesitate to reach out for more information, always happy to help the Sisense eco-system

[email protected]

QBeeQ - Gold Sisense implementation & Development Partner

Ido_QBeeQ_0-1682945086691.png

Ido_QBeeQ_2-1682945105887.png

 

Ido_QBeeQ_1-1682945093864.png

 

gwolfe
10 - ETL
10 - ETL

Thank you @Ido_QBeeQ  this is from the Sisense Color Heatmap plugin. Linked here https://community.sisense.com/t5/knowledge/color-heatmap/ta-p/9439

Please let me know if you need anything else. 

 

Ido_QBeeQ
9 - Travel Pro
9 - Travel Pro

Hey @gwolfe See my recommendations below, if you have any additional questions, please do not hesitate to reach out, we're always here to help

[email protected]

  1. In the HCColorHeatmap.js file, there is margin array. The values are in this order [top, right, bottom, left]. If you set top value to at most 40 or less, it will free up some space from the top of the chart.
  2. In the HCColorHeatmap.js file, there is margin array. The values are in this order [top, right, bottom, left]. If you set left value to 100 or even 160, it will add space to the left side of the chart.
  3. In widget.js, if we wrap the DisplayColorHeatmap method inside setTimeout method for 1 sec or higher, it will fix the issue.

setTimeout(() => { DisplayColorHeatmap ( widget, ChartDivName, svgWidth, svgHeight ); }, 1000);

gwolfe
10 - ETL
10 - ETL

Thanks @Ido_QBeeQ ! 

The first 2 answers worked perfectly. I can't seem to get the third one to work. Here is the widget.js script. Anyway you could take a look and see if I am doing something wrong?

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Highchart Highchart Color Heatmap
// Version : 1.4
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


prism.registerWidget("colorheatmap", {
	name : "colorheatmap",
	family : "line",
	title : "Color Heatmap",
	iconSmall : "/plugins/ColorHeatmap/ColorHeatmap.png",
	styleEditorTemplate: "/plugins/ColorHeatmap/styler.html",
	style: {
		LegendPosition	: 'Bottom',
		XAxisPosition	: 'Bottom',
		YAxisPosition	: 'Left',
		ClickFilters	: 'Off'
	},
	data : {
		selection : [],
		defaultQueryResult : {},	
		panels : [
			{
				name: 'X-Axis',
				type: "visible",
				metadata: {
					types: ['dimensions'],
					maxitems: 1
				},
				visibility: true
			},
			{
				name: 'Y-Axis',
				type: "visible",
				metadata: {
					types: ['dimensions'],
					maxitems: 1
				},
				visibility: true
			},
			{
				name: 'Value',
				type: "visible",
				itemAttributes: ["color"],
				allowedColoringTypes: function() {
					return  {
						color: false,
						condition: true,
						range: true
					};
				},
				metadata: {
					types: ['measures'],
					maxitems: 1
				},
				itemAdded: function(widget, item) {
					item["format"] = 
					{
						mask : 
					
							{

								type: 'number',
								abbreviations: {
									t: true,
									b: true,
									m: true,
									k: true
								},
								separated: true,
								decimals: 'auto'
							},
						color :
							{
								rangeMode : 'auto',
								steps:0,
								type: 'range',
								
							}
					};
					
				},
				visibility: true
			},
			{
				name: 'filters',
				type: 'filters',
				metadata: {
					types: ['dimensions'],
					maxitems: -1
				}
			}
		
		],
		
		canColor: function (widget, panel, item) {
			console.log('canColor');
			
			
			if (panel.name == "Value") {
				return true;
			}
			else {
				return false;
			}
			
		},

		
		
		buildQuery: function (widget) {
			console.log('buildQuery');
			var query = { 
					datasource: widget.datasource, 
					format: "json",
					isMaskedResult:true,
					metadata: [] 
				};
				
			
			widget.metadata.panel("X-Axis").items.forEach(function (item) {

                        query.metadata.push(item);
            });				
			
			widget.metadata.panel("Y-Axis").items.forEach(function (item) {

                        query.metadata.push(item);
            });				
				
			widget.metadata.panel("Value").items.forEach(function (item) {

                        query.metadata.push(item);
            });			
			
			// force a sort by 
			//if ($$get(query, 'metadata.1.jaql')) {
			//	query.metadata[1].jaql.sort = "desc";
			//};

			// pushing filters
			widget.metadata.panel('filters').items.forEach(function (item) {
				item = $$.object.clone(item, true);
				item.panel = "scope";
				item.filterType = "widget";
				query.metadata.push(item);
			});
			
			
			return query;		
		},

		
		
		//Create widget  Data Object and populate all values 
		processResult : function (widget, queryResult) {	
			console.log('processResult');
			var 
				Data = [],
				nodeDimX,
				nodeDimY,
				XAxis = {},
				YAxis = {},
				Values = [],
				minDataValue = 0,
				maxDataValue = 0,
				RangeMode = 'auto',
				ColorFormatType = '',
				minColor = '#FF0000',
				maxColor = '#008000',
				dashboardFiltersX = null,
				dashboardFiltersY = null;
			
			
			// find if there is any matching dashboard filters
			nodeDimY = widget.metadata.panel("Y-Axis").items[0];
			nodeDimX = widget.metadata.panel("X-Axis").items[0];
			
			widget.dashboard.filters.$$items.forEach(function(f){
				if (f.isCascading){
					f.levels.forEach(function(f2){
						if(f2.dim == nodeDimY.jaql.dim) {
							dashboardFilterY = f2.filter;
						}
						if(f2.dim == nodeDimX.jaql.dim) {
							dashboardFilterX = f2.filter;
						}
					})
				} else {
					if (f.jaql.dim == nodeDimY.jaql.dim) {
						dashboardFiltersY = f.jaql.filter;
					};
					if (f.jaql.dim == nodeDimX.jaql.dim) {
						dashboardFiltersX = f.jaql.filter;
					}
				}
			});
			
			
			// Create Categories list for X Axis
			
			if (queryResult.columns().length > 0){
				queryResult.columns()[0].forEach(function (item, i) {
					XAxis[item.text] = 0;				
				});			
			};
			
			XAxis = Object.keys(XAxis)

			// Create Categories list for Y Axis
			if (queryResult.columns().length > 1){
				queryResult.columns()[1].forEach(function (item, i) {
					YAxis[item.text] = 0;
				});			
			}
			YAxis = Object.keys(YAxis);
			// sort the list if it is a datatime field
			if (widget.metadata.panel('Y-Axis').items[0].jaql.datatype == 'datetime'){
				YAxis.sort();
			};
			
			
			// Create value list in order to calc min, max values
			if (typeof widget.metadata.panel("Value").items[0] != 'undefined'){
				if (queryResult.columns().length > 2){
					queryResult.columns()[2].forEach(function (item, i) {
						Values[i] = item.data;
					});	
				};
				maxDataValue = Math.max.apply(Math, Values);
				minDataValue = Math.min.apply(Math, Values);
			}
			
			
			// Build the points for plotting the heatmap
			queryResult.$$rows.forEach(function (item, i) {
				
				Data[i] = {
						x		:(typeof item[0] != 'undefined') ? item[0].text : null,
						y		:(typeof item[1] != 'undefined') ? item[1].text : null,
						value	:(typeof item[2] != 'undefined') ? item[2].data : null, 
						xdata	:(typeof item[0] != 'undefined') ? item[0].data : null,
						ydata	:(typeof item[1] != 'undefined') ? item[1].data : null,
						color 	: (typeof item[2] != 'undefined') ? item[2].color : null,
						selected: false
					}
				
				var isSelectedX = IsSelected(dashboardFiltersX, Data[i].x),
					isSelectedY = IsSelected(dashboardFiltersY, Data[i].y);
				
				if (!(isSelectedX && isSelectedY)){
					Data[i].color = Highcharts.Color(Data[i].color).setOpacity(0.3).get();
				};
				// Save selected state
				Data[i].selected = (isSelectedX && isSelectedY); 
				
			});
			
			// determine the color mode and set min max colors accodingly 
			if (typeof widget.metadata.panel("Value").items[0] != "undefined"){
				ColorFormatType = widget.metadata.panel("Value").items[0].format.color.type;
				
			};
			
			
			
			switch (ColorFormatType){
				case 'range':
					RangeMode = widget.metadata.panel("Value").items[0].format.color.rangeMode;
					if (RangeMode == 'auto') {
						minColor = '#FF0000',
						maxColor = '#008000'
					}
					else {
						minColor = widget.metadata.panel("Value").items[0].format.color.min;
						maxColor = widget.metadata.panel("Value").items[0].format.color.max;
					}
						
					break;
					
				case 'condition':
					minColor = widget.metadata.panel("Value").items[0].format.color.conditions[0].color;
					maxColor = widget.metadata.panel("Value").items[0].format.color.conditions[widget.metadata.panel("Value").items[0].format.color.conditions.length - 1].color;
					//minColor = null;
					//maxColor = null;
					break;
				default:
					minColor = null;
					maxColor = null;
			}
			
			return {minColor,maxColor,maxDataValue,minDataValue,XAxis,YAxis, Data};
			
			
			function IsSelected(dashboardFilters, Item){
				if (dashboardFilters == null) {
					return true
				}
				else if (dashboardFilters && (typeof dashboardFilters.all != 'undefined')) {
					return true
				}
				
				else if (dashboardFilters && (typeof dashboardFilters.exclude != 'undefined')) {
					var ItemsToExclude = dashboardFilters.exclude.members;
					return (ItemsToExclude.indexOf(Item) == -1) ? true : false
				}
				
				else if (dashboardFilters && (typeof dashboardFilters.members != 'undefined')) {
					var ItemsToInclude = dashboardFilters.members;
					if (ItemsToInclude.length == 0) {
						return true
					}
					else {
						return (ItemsToInclude.indexOf(Item) == -1) ? false : true
					}
				
				}
				
				else {
					return false;
				}
	
			}
		}
	},
	
	beforequery: function(widget, args){
		
		var	
			widgetPanels = [];
			
		// if filter mode is slice/filter then do nothing
		if (widget.options.dashboardFiltersMode == "filter"){
			return;
		};
			
		widgetPanels.push(widget.metadata.panel("X-Axis").items[0]);
		widgetPanels.push(widget.metadata.panel("Y-Axis").items[0]);
		
		for (var j=0; j <= (widgetPanels.length - 1); j++){
			var nodeDim = widgetPanels[j];
			
			//	Look for any dashboard filters
			var dashboardFilters = prism.activeDashboard.filters.$$items;

			//	Loop through the metadata
			for (var i=args.query.metadata.length-1; i>0; i--){

				//	Does this item match the node's dimension AND is a dashboard filter?
				var isMatch = (args.query.metadata[i].panel == "scope") && (args.query.metadata[i].jaql.dim == nodeDim.jaql.dim),
					isNotWidgetFilter = (args.query.metadata[i].filterType !== "widget"),
					isWidgetFilter = (args.query.metadata[i].filterType == "widget"),
					isDashboardFilter = $.grep(dashboardFilters, function(w){
						return (w.jaql.dim == args.query.metadata[i].jaql.dim) && (typeof w.jaql.filter.all == "undefined");
					}).length > 0;
				
				if (isMatch && isNotWidgetFilter && isDashboardFilter) {
				//if (isMatch && isDashboardFilter) {
					
					//	Create a new copy of the filter object
					var matchFilter = $$.object.clone(args.query.metadata[i], true);

					//	Remove the panel attribute
					delete matchFilter.panel

					//	Include with the node's dimension metadata
					//nodeDim.jaql.in = {selected: matchFilter}
					if (isWidgetFilter && defined(matchFilter.jaql.filter)) {
						nodeDim.jaql.filter = matchFilter.jaql.filter;
					}

					//	Remove from the metadata
					args.query.metadata.splice(i,1);
				}
			}		
		}
		
	},		

	render : function (widget, event) {
		console.log('render');
		var element = $(event.element),
			svgHeight = $(element).height(),
			svgWidth = $(element).width();
			
		
		element.empty();
		
		var num = Math.floor(Math.random() * 1000000);
		var MyDiv = element[0],
			ObjectID = widget.oid,
			ChartDivName = "colorheatmap-" + ObjectID + "-" + num;
			
		MyDiv.setAttribute("id",ChartDivName);
		MyDiv.setAttribute("style","width: 99%; height: 99%; margin: 0 auto");
			
//		element.append('<div style="width=97% height=97% margin: 0 auto" id="' + svgID + '"></div>');
		
		setTimeout(() => { DisplayColorHeatmap ( widget, ChartDivName, svgWidth, svgHeight ); }, 1000);

    options: {
        dashboardFiltersMode: "select",
        selector: false,
        title: false
    },
    sizing: {

        minHeight: 120, //header
        maxHeight: 2048,
        minWidth: 320,
        maxWidth: 2048,
        height: 200,
        defaultWidth: 512
    }

});