“…Thirteen’s just obnoxious.”
Apologies for the lag between posts lately, but we at Axis Group are ridiculously busy…in a good way.
In fact, we could use the help of some additional experienced QlikView consultants, if you’re looking for an opportunity with our company. We’re hiring both engineer- and architect-level positions.
- QlikView knowledge
- Ability to use Tuftean in a sentence
See our job page for more information, but bear in mind that the location is negotiable if you are willing to travel.
We look forward to hearing from you.
I’ve uploaded a new extension to GitHub called the d3 visualization library, or d3vl for short. It is a collection of 30 examples from the d3js.org gallery incorporated into a single Qlik Sense extension. The goal is to show how easily d3 can be integrated with Qlik Sense.
The d3vl also demonstrates the concept of using an extension as a library of charts, rather than a single chart. Using an extension as a library of similar charts has a few advantages, such as an easy installation, minimal impact on Sense’s chart object list, and common themes across the charts. In the future I hope to see more libraries like these, as opposed to one-off extensions. A great example would be a network extension that contains charts related to networking, all with a common styling and notation.
The senseUtils library has also been updated with new functions. I will write up a future post about how to use them, but here is a quick rundown:
- pageExtensionData: pages an extension’s data; currently, the max page size for an extension is 10,000 cells, so anything beyond that will not be returned to your extension object. if you need to use more data than that, you can use this function
- flattenData: flattens pages of extension data into one array. Currently, the page arrays are contained in an outer array. This function concatenates them into a single array
- getDimLabel: gets the dimension labels for an extension
- getMeasureLabel: gets the measure labels for an extension
- setupContainer: sets up the container for an extension, which includes logic for emptying the container on redraw
- extendLayout: extends the layout object by adding some useful properties. An example is a property on the qMatrix row data that has a pre-defined function for selecting that row’s values. This makes it possible to easily incorporate selections into visualization libraries like d3 without having to write new selection functions
A post demonstrating how to use these new functions will be available soon. In the meantime, d3vl uses a lot of these new methods and can be used as an example.
Stephen Redmond is a QlikView expert, as indicated by his book Mastering QlikView in which he clearly illustrates myriad advanced techniques from data modeling and performance tuning to expression writing and visualization best practices. While there is a disclaimer in the beginning of the book that the content caters to more advanced QlikView developers, I believe that Mastering QlikView is a must-read for anyone endeavoring to create QlikView applications. Though having in-depth knowledge of the tool does help to provide more context to the optimization portions, Redmond does an excellent job of giving the reader a basic overview of each chapter’s content prior to delving into more detail; it doesn’t read at all like a technical manual, but more like a tutorial.
Mastering QlikView starts with a very technical-heavy performance tuning and optimization guide with detailed instructions on how to debug any QlikView application for slow behavior; the section on using JMeter for user simulation is particularly well-written and explains each step carefully without assuming foreknowledge of the tool itself. Redmond also explains how to most efficiently acquire test data and provides links to sources he uses when testing a QlikView environment. He then goes on to detail the process of data modeling, theories on data warehousing, and performance testing on the front end – he even includes a guide on how to use Expressor to optimize the ETL process.
What struck me most about this book is that it not only answers the question of “How?” but also the question of “Why?”. Redmond gives sound reasoning and empirical proof of the benefits of using a variety techniques for each topic he covers. The section on data visualization is imperative for any developer to have in his or her back pocket in order to understand how and why users interact with QlikView applications (or really anything) the way that they do – he uses an example of a door with a handle that says “PUSH”, a situation to which I’m sure all of us can relate.
Mastering QlikView is a great addition to any QlikView developer’s bookshelf – even the most sophisticated developer would certainly come away with something new or at the very least a better understanding of QlikView. I will certainly be referring back to this book in my future engagements and would recommend that any QlikView developer, novice or expert, keeps Mastering QlikView close at hand while creating QlikView applications.
Animation in data visualization is a relatively new area that we still don’t know much about. Like any visual component of a visualization, animations used in the wrong way can be unnecessarily flashy and distracting. However, there is evidence that animations can also add value to visualizations when used appropriately.
In this interactive example, Mike Bostock demonstrates the concept of object constancy:
a graphical element that represents a particular data point…can be tracked visually through the transition. This lessens the cognitive burden by using preattentive processing of motion rather than sequential scanning of labels.
Animation therefore can help users track changes in the data. When filtering, this can help the user discern what changes their filters caused, as opposed to having to reset their bearings on a newly appearing chart. When data in a chart is filtered, there are three possible events that can happen: data elements either update with new properties, exit because they were filtered out of the data set, or enter because they are filtered in to the data set. These are the main events we handle in typical Qlik Sense extensions. For more on animation possibilities, check out https://www.youtube.com/watch?v=vLk7mlAtEXI#t=54
Recently, Justin Fox of Harvard Business Review shared a chart about law school enrollment that he found interesting:
— Justin Fox (@foxjust) December 12, 2014
The chart shows how law school enrollment has seen a relatively drastic decline in the last 3 years. You may have noticed that the chart’s y-axis doesn’t start at 0. This design decision caused a bit of an outrage amongst what are now being called “Y-Axis-Zero Fundamentalists”.
Justin shares a lot of the feedback and discussion around this point in his post The Rise of the Y-Axis-Zero Fundamentalists.
The discussion around this point is pretty thorough but I want to add my two cents.
Line charts aren’t just for displaying quantities. They are also used to examine changes in quantities. Sometimes, the change in quantity in relation to the entire size of the quantity is not as important as visualizing the direction and magnitudes of the changes in relation to each other. The chart Justin showcased is a perfect example of this type of analysis. It is probably not important to the average reader that law school enrollment was at ~38,000 in 1974, ~52,000 in 2010, and ~40,000 in 2013. What is important is that the change from 2010 to 2013 was significantly large and fast when compared to the historical trend of enrollment numbers. This analysis comes from comparing the slopes and positions to each other, not from comparing the distance of each point to a zero-based axis.
The exact same chart can be viewed with a zero-axis thanks to a slight variation. By changing the metric being plotted, we get:
Is this chart now valid because the axis has a 0 next to it at the baseline? One could argue that each point is now quantified by it’s distance from the axis. That isn’t the point of this visualization however. The average reader probably does not want to quantify the % change since 1974. The metric also doesn’t provide any means to derive the nominals, a metric that is more real to a reader and easier to interpret.
The original chart’s trade-off of using a non-zero axis with nominal amounts in order to focus on relative changes while retaining a link to the nominal source data so that exact quantities can be derived is valid. The distance of each point to the axis is not visually defined like in a bar chart, so the implication that the distance is equal to the size of the value is not there. Scatter plots use the same positional method of encoding each data point, but I have never heard anyone say that scatterplot axes should start at zero.
In most cases, a zero-based axis makes sense, but it ultimately depends on the data and visualization used. If you are tracking the trend in revenue of a multi-billion dollar company with a line chart for example, you probably won’t learn much if you start the axis at 0.
I’ve added a new component to senseUtils called filterPanel. filterPanel allows a user to define a list of fields in a Qlik Sense application. The object will then generate all of the list objects, retrieve the data from the Qlik Sense server, and build or update the existing filterPanel UI. The panel can be created in an existing element on a webpage.
The panel features badges for the # of selections and collapsible filters by default. These settings can be easily changed with the .badges() and .autoCollapse() methods.
CSS is used for the collapsing behavior as well as the styling. The base css file (filter-panel.css) can be used as a starting point for applying custom styling to the panel. Alternatively, the filterPanel could just be used to create the list objects and keep track of their values. This is possible with the .fields() method, which returns a list of the current fields in the panel as well as attribute like the number selected, the total number of elements, and all of the values of the filter.
Documentation for the panel’s use is in the README of the senseUtils’ repository. An example use, taken from the repository:
app; // assume a Qlik Sense app object exists in this variable var filterPanel = senseUtils.filterPanel() // creates a new filterPanel .app(app) // sets the app for panel to pull from .container("#filter_container") // sets an element with id "#filter_container" as the parent .addFields(["Region","Country"]); // adds the fields Region and Country to the panel filterPanel.badges(false); // disables badges filterPanel.removeField("Region") // removes the Region filter from the panel
The live demo above also uses Bootstrap’s CSS. This helps with some of the text centering, but is not necessary for the panel to function.
The Qlik Sense Workbench API gives us an easy way to create hypercubes from the browser on a webpage. With these hypercubes, we can create custom visualizations on the web that are driven by dynamic Qlik Sense data. However, one method that is not covered in the Workbench API is removing hypercubes once they have been created. When a hypercube is created, it will continue to process the data on the server and send it back to the browser as long as a user has their current session open. This can cause performance issues in single-page applications that use different cubes in different views.
For example, imagine you built a single-page application with a Dashboard view and a Details view. When you initialize your Dashboard view, you may create some hypercubes for the visualizations on that view. Users may navigate to the Details view next, which also initializes its own set of hypercubes. However, your hypercubes from the previous view will remain active. They will continue to utilize resources on the server, send data back to your browser, and execute their callback functions. This will lead to performance problems as you add views; the server will try to send all of the data across the views back to your browser at once.
Read the rest of this entry »
Inspired by Qlik Sense’s lasso tool, I’ve built a lasso tool for D3 that accomplishes similar functionality.
The lasso takes in a d3 selection of elements that are lasso-eligible and allows a user to draw a custom path around those elements. Elements are tagged based on whether they are inside or outside the loops. Custom functions can be defined to do things with these elements, such as style them:
The lasso code and documentation is available on GitHub.
There are more things in heaven and earth, Horatio,
Than will fit in our engagement strategy.
Hath ye spied that client feedback? It is an email
Told by an idiot, full of sound and fury,