D3 and Qlik Sense

Qlik Sense offers a great extension interface for adding new visualizations.  The initial install of Sense has the standard visualizations found in most tools, like Power BI, but if you want to show more advanced visuals, you will have to create your own.  In our example, we will create a Sunburst visual that acts like a TreeMap with hierarchical data, but is presented in a radial fashion.  Here is what will will be building:



If you do not have Sense desktop installed go here and download it for free.  Follow the installer wizard and it should install without any problems.  Once Sense is installed you will have a link on your desktop.  If you don't have a link, either search for it through Windows, or navigate to its install directory C:\Users\<USERNAME>\AppData\Local\Programs\Qlik\Sense and click on the QlikSense.exe file.

When Sense launches, you will arrive at the Qlik Sense Desktop hub.  It will look like this:









Since we are going to create an extension, the best place to start is using the Qlik Dev Hub.

Click on the drop down menu that looks like a hamburger and select Qlik Dev Hub.







This will launch your browser and take you to http://localhost:4848/dev-hub.  Here it is:











Once you are here go to the left menu and select Extension Editor.  Click on the menu toolbar and select Create new project.












A dialog box will appear, name the project Sunburst, and choose Basic Visualization template from the template drop down.  Click Create & edit.











Once the project is created, three tabs will be displayed.

  1. Sunburst.qext
  2. Sunburst.js
  3. preview.png
  4. wbfolder.wbl
This information will be stored on the file system under the following location:

C:\Users\<USERNAME>\Documents\Qlik\Sense\Extensions\Sunburst

Sunburst.js


This is the main extension file where most of the properties and rendering will take place.  The initial generated code is sparse, but I will take you through it.  Below is the annotated code.

define( [  // this is a require.js statement that loads your files and provides a callback function
],
function ( ) {  // this is the callback function that is called when your files are loaded

return { // returns a hash of functions, in this case only a paint() function
paint: function ($element) { // function used by Sense to render your extension
//add your rendering code here
$element.html( "Test" ); // writes out Test
}
};

} );

This is just some boilerplate code generated and it does not do much except print "Test".  Our code will be much more involved, so I will put it on Github for you to download and play with.  I want to point out some features in our code.

// here is where we load our files - jquery, a CSS file, and D3
define(["jquery", "text!./sunburst.css", "./d3.min"], function($, cssContent) {'use strict';
$("<style>").html(cssContent).appendTo("head");
return {
                // these are properties for loading the hypercube
               // width = 4 for 4 dimension and height = 1000 for getting 1000 rows
initialProperties : {
qHyperCubeDef : {
qDimensions : [],
qMeasures : [],
qInitialDataFetch : [{
qWidth : 4,
qHeight : 1000
}]
}
},
definition : {
type : "items",
component : "accordion",
items : {
                                // min and max of 4 dimension for the visual
dimensions : {
uses : "dimensions",
min : 4,
max : 4
},
                               // min and max of 1 measure
measures : {
uses : "measures",
min : 1,
max : 1
},
                                // allow sorting and settings
sorting : {
uses : "sorting"
},
settings : {
uses : "settings"
}
}
},
snapshot : {
canTakeSnapshot : true
},
                // our paint function used for rendering - annotated below
paint : function($element, layout) {

Paint Function

                paint : function($element, layout) { // jquery $element and layout from Sense
                        // variable for our 4 dimension by 1000 row matrix
var matrix = layout.qHyperCube.qDataPages[0].qMatrix;
                        // data that is going to be sent to D3 for rendering the visualization
var data = matrix.map(function(d) {
return {
DimRegion: d[0].qText,
DimState: d[1].qText,
DimCounty: d[2].qText,
Measure: d[3].qNum
}
});

var width = $element.width();
var height = $element.height();
var id = "container_" + layout.qInfo.qId;

if (document.getElementById(id)) {
$("#" + id).empty();
}
else {
$element.append($('<div />;').attr("id", id).width(width).height(height));
}
                        // function to draw the visual using D3
drawVisual(data, width, height, id);
}

There is a bunch more code for D3, but I want to get to the end result.  The code will reside here https://github.com/ebunt when I upload it.

Sense Extension


Once everything is developed, you can refresh Sense desktop and see the visualization in the Chart section on the left.




















Next, drag the chart to the canvas and you will see our 4 dimensions and 1 measure we stated in the properties above.
















I have a dataset for tornado sightings in the USA that has dimensions for Region/State/County for our hierarchy and number of sightings for the measure.  The chart will then render and look like this:


I added filters on the left to show that it works with existing visuals in Sense. 









Here is our visual side-by-side with the TreeMap that Sense has as a default visual.














Here is filtering on the TreeMap that cross filters our Sunburst visual.














Sense provides an excellent environment for creating your own visuals.  It is much easier to debug and deploy than Power BI.  If I had to choose which tool to use for our clients, I would recommend Sense without hesitation.

Ed