Archive for category Miscellany
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.
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,
The first two problems it addresses are:
- removing hypercubes after they’ve been created using the Workbench API; this can be useful for situations like a single page application where you need to disconnect from a dashboard view
- defining a visualization callback based on multiple cubes. A multicube function is included that can keep track of multiple hypercubes before calling a single callback function. This can be useful for complex visualizations that are dependent on more than one data source
Please feel free to contribute, whether it be by adding your own functions, reporting bugs, or requesting feature enhancements to the library. The latter two items can be entered in the Issues section of the repository.
A common problem when building QlikView dashboards is where to place listboxes. Often, users want to be able to filter many fields, but there isn’t enough room on the dashboard for all of the listboxes. Some common solutions to this problem are using multiboxes, dynamic listboxes, or creating entire sheets dedicated to housing just filters. I’d like to introduce another out-of-the-box solution to this problem: the filter tree.
The following tutorial will show how to create an extension using existing d3 code. The tutorial will go into a bit of detail, so following each step will take some time. However, the steps themselves are simple and without explanation can be completed in under 10 minutes. While the tutorial goes into some granular detail, there are 4 basic steps:
1) Get some d3 code to use
2) Get some test data to use and load it into Qlik Sense
3) Initialize a new extension and set up its properties
4) Insert the d3 code into the extension and modify it to source data from the extension
In QlikView, users are very familiar with the functionality of clicking a dimension in a drill group to navigate to the next level of a hierarchy. These drill downs can be simplified in some cases by using a hover to expand the drill down as opposed to a selection. The Qlik Sense extension above is one idea for using hovering as a drill down. Read the rest of this entry »
The QlikView and Qlik Sense platforms offer an amazing ability to interactively filter through dynamic data sets. However, the visualizations that sit on top of these data sets have in the past been mostly static.
Qlik Sense has introduced new functionality for interacting with visualizations beyond just filtering the data. Techniques like brushing, panning, and zooming are included that expand upon the data discovery process of QlikView 11. This is a new way to think about data discovery: users can interact with the visualizations themselves, not just the underlying data.
Thanks to the new user-friendly APIs, we can extend interactivity in Qlik Sense even further by building custom visualizations with powerful libraries like D3. These custom charts can improve the user experience and information design through elements like annotation, linking, and instant feedback loops.
I’ve built an example mashup that demonstrates some ideas for interactivity that I’ve seen used in data visualizations outside of QlikView. The source code and deployment instructions are posted on GitHub. For those not using Qlik Sense yet, you can view a sample of the visualization without the Qlik integration here.
The data set I’ve used for illustration is sales data. The data set includes two metrics: # of sales, and the average discount rate given per sale. The metrics are reported by sales office, which rolls up to region. There is also a Sales Type field to demonstrate Qlik Sense filtering.
The goal of the visualization is to understand how discount rates have changed year over year across offices.