Skip to content

Instantly share code, notes, and snippets.

@BenSimonds
Last active October 9, 2017 14:23
Show Gist options
  • Select an option

  • Save BenSimonds/5decc728b106d5c1ee6e27bfb0a9b5c7 to your computer and use it in GitHub Desktop.

Select an option

Save BenSimonds/5decc728b106d5c1ee6e27bfb0a9b5c7 to your computer and use it in GitHub Desktop.
Qlik UI/UX Design

Qlikview UI/UX Design

This is somewhere to note down some ideas about how to design UI's in qlikviews. It's possible to do lots of things in qlik, but that doens't mean we should just do whatever we feel like. In particular in this document, I want to think about how we implement interactions with the UI in Qlik - I've made mistakes in this regard in the past and ended up with applications that were particularly difficult to maintain (chains of macros, lots of hidden/overlapping objects, a million variables driving show/hide conditions, etc.). Requirements from clients can often make certain ways of interacting with an object seem like a good idea:

It would be cool if I could click on this object and have another view pop up on top with some extra information. Can we use a macro to do that?

But it's a rare occasion that decisions that deviate from native qlik methods for interactions end up being a good idea. Whilst they may (or may not) look pretty, they are usually time consuming to maintain and prone to causing bugs.

First Principles

Some first principles for managuing UI interactions in Qlikview.

  • Qlik's native UI tools should be used wherever possible.
  • Use the minimum number of objects possble.
  • Use the minimum amount of infrastructure to to define how those objects interact.
  • Wherever possible, capture the information about that infrastructure in the script.

Design Practices

Based on the principles above, here are a few ideas I think are useful.

Use Native Interactions wherever possible

Don't build an elaborate variable or a macro to change something in the UI that could be done via native funcitonality. For example you could use a button to change a variable, which contained an expression to be displayed in a chart, but really you should be grouping expressions in the chart settings.

Avoid Macros

This often becomes an issue with trying to maintain a dasboard that works on multiple platforms (IE Plugin, Ajax, Desktop). Qliks Macros run differently depending on the client and can introduce all sorts of problems because of this. Avoid wherever possible.

Define Variables in the Script

This is something of a general point, as variables are useful for many things, but it bears mentioning here. Whilst you can define variables using the variables overview alone, defining them in the script is much more robust for the following reasons.

  • A default state for the variable is restored with every refresh. This prevents issues resulting from inadvertent changes to variables from persisting between reloads.
  • It makes maintenance easier and provides an obvious point to document the purpose of the variable in a comment.
  • If using any version control on your script, it exposes your variables to being version controlled.

I would reccommend having a specific tab in your load script that contains your UI variables. For example:

// UI Variables
set vUI_ShowDevSheets = 0; // Show hide condition for develoment pages.
set vUI_SalesBarChart = 0; // Show hide condition for sales bar chart on front page.

Avoid Pop-Ups and Overlays

Layering objects over one another can seem like a nice idea - for example letting the user click on a chart, and popping up a table with the underlying data. But this can rapidly become difficult to manage once you have multiple hidden object on multiple layers, with different show/hide conditions.

Use Separate Sheets Instead

When you want to show a detail view based on the current selection, and the sheet you are building can't accomodate it, build a new sheet with that view instead. Use a button to allow the user to visit the detail view, and implement a "back" button to allow them to return after. The back button can be added using a vPreviousSheet variable that is updated when the user clicks to visit the detail view, and then used to define the sheet ID to be returned to when the user wishes to return.

Layout states should be Mutally Exclusive

This is a slightly harder one to explain. Lets imagine you have a dashboard where you want the user to be able to choose between two charts - a bar chart showing YTD sales by region, and a trendline showing sales over time. These charts are different enough (different dimensions, different chart types), that they should be made using separate chart objects. We could drive their visibility using variables in two ways. One would be to have a variable with a show/hide conndition for each object.

// Bad way
set vShowBarChart = 1; Show condition for bar chart.
set vShowTrendline = 0; Show condition for trend line.

If we want the user to click a button to switch between charts, then the button will need two actions, one for each varriable. Not only that, but if the two charts occupy the same space, it's possible that both vairables might get set to 1, resulting in overlapping charts. The same condition. We could better achieve the same result with just one varaible.

// Better way
set vChooseChart = 0; // 0 = Bar Chart, 1 = Trend

The show conditions for the bar chart now reference the same variable, each looking for a different state. This has a few advantages:

  • We only have one variable to maintain.
  • We can add more charts by defining other states for the same variable.
  • Only one action is needed to update the layout state.

This is a more obvious case, but it can be easy to arrive in a situation like this when developing a dashboard, as new objects and UI elements are added over time.

Cloned Objects with Different Layout States

This is more of a trick than a guidline. Say you have a chart that appears on two sheets in your document. This should be two linked instances of the same object right? Right. But what if one instance needs a different show hide condition to another? This makes things difficult, but an easy way to resolve this is to place the object with a separate show/hide condition in a container, and apply the condition to the container rather than the object. The container can be set to grid presentation with one row and one column to make the container itself more or less invisible.

Note: this can be confusing for other developers though, as unless they look closely they will just see an object appearing and dissappearing even though it appears to have no show/hide conditions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment