Heat Map Formatting and Legend Bug
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
04-27-2023 09:34 AM
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!
- Labels:
-
Dashboards & Reporting
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-01-2023 05:46 AM
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
QBeeQ - Gold Sisense implementation & Development Partner
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-02-2023 02:13 PM
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-04-2023 07:33 AM
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
ido.darnell@qbeeq.io
- 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.
- 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.
- 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);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-19-2023 08:29 AM
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
}
});
