1 2 3 Previous Next

Qlik Design Blog

39 Posts authored by: Francis Kabinoff

cyc.png

The biggest tournament in soccer is in full swing today, and if you haven't checked out our Choose Your Champion demo app, take a second to check it out now Choose Your Champion. We've gotten some questions about how we built it, so I'm going to go through a high-level summary. Before we begin, note that there's really two parts of the Choose Your Champion app, the Create a Bracket part, and the Historical Analysis part, which we really took two different approaches for.

 

 

 

bracket.png

Create a Bracket

For the “Create a Bracket” half of the Choose Your Champion app, we connect to a Qlik Sense app with enigma.js on page load. We get all the data we need from Qlik Sense using Qlik expressions and pagination to select from the associated data, which is fast and easy. The data we get from Qlik Sense we then put into a Redux store, and manage state from there. We decided this was the best approach for this part of the app for us for quite a few reasons, but it would be pretty trivial to have Qlik Sense manage all the state here if desired with a few Qlik Sense variables and a bit of set analysis.

 

Once we have the data from Qlik Sense saved in a Redux store, we just use html, css, and javascript to build the bracket and charts. Any selections the user makes just updates the Redux store. The charts here really are very simple, just some divs with conditional widths/heights. We allow the user to authenticate with Facebook and save their bracket, which we just save to a database, and fallback to localstorage to save the state if the user isn’t authenticated or hasn’t yet saved a bracket.

 

And this really demonstrates the power and flexibility of Qlik Sense APIs. We can easily get the data we need, and then do whatever we’d like with it.

 

 

historical.pngHistorical Analysis

The “Historical Analysis” half of the Choose Your Champion app is probably a more familiar Qlik Sense experience. We connect to the app using our qdt-components library so we have access to our prebuilt QdtSelectionToolbar component and then also built a custom filter and table component (fun fact: the bar chart is also the custom table component, with a few special props). We also connect to the Visualization API using qdt-components to create and embed some native Qlik Sense visualizations.

 

That’s really it, this part of the app is pretty straightforward.

 

A few comments

Somebody had asked if the custom visualizations were extensions, and the answer is no, there are no extensions used here. While Qlik Sense extensions are great if you want to reuse them across multiple apps, or enable non-developers to create the objects in the Qlik Sense client, if you don’t have those requirements it’s easier to just build some components that interface with the Qlik Sense engine but don’t have to worry about being extensions. This also means those components can be used in other projects where you may not be connecting to the Visualization API and you won’t have to load all of the assets required to use the Visualization API.

 

And that’s it. Like I already stated, I think this demo shows the power and flexibility of the Qlik Sense APIs and what is possible with them, and I hope there’s something to take away for everyone here. If you guys have any questions about any of it, let me know.

If you want to use data from a hypercube to create a chart with picasso.js you're probably going to want to use the picasso.js q plugin. The q plugin makes it easy to extract data from a hypercube for use with picasso.js. In this post I'm going to go through the steps needed to use the q plugin for picasso.js to show you how to use hypercube data to create a chart with picasso.js, and also go over updating the chart when the hypercube data changes, and making selections in the QIX Engine from a picasso.js chart.

 

picasso.js scatter plot with hypercube data.png

Check out this observable notebook of creating a scatter plot with hypercube data and the q plugin

Setup picasso.js

You'll need to install picasso and picassoQ, and register picassoQ with picasso. You can install them with npm install --save picasso.js picasso-plugin-q, and then register picassoQ with picasso like below.

import picasso from 'picasso.js';
import picassoQ from 'picasso-plugin-q';

picasso.use(picassoQ); // this registers the picasso q plugin with picasso.js

 

Create and update picasso.js chart with hypercube data

You'll need a hypercube of course. I'm going to assume here that you know how to create a hypercube with the App API or enigma.js, and if not, there's other resources for learning how to do that, so we won't cover it again here. Below is a general pattern for creating and updating a picasso.js chart after creating a hypercube with enigma.js

(async () => {
const hypercube = await qDoc.createSessionObject(/* hypercube def */);
const layout = await hypercube.getLayout();
createPic(layout); // function that calls chart method on a picasso instance
hypercube.on('changed', async () => {  // listen for updates to hypercube
    const newLayout = await hypercube.getLayout();  // get new layout
    updatePic(newLayout); // function that calls update method on a picasso instance
})
})()

.

In the above block, we create a hypercube, get the layout, and call a function we define that calls the chart method on an instance of picasso.js. Then we watch for the hypercube to update, and can use the update method of picasso.js to simply update the data for the chart. The createPic and updatePic functions might look something like this.

let chart;
const createPic = (layout) => {
chart = picasso().chart({
   element: document.querySelector('#container'), // some DOM element
   data: [{
     type: 'q', // this tells picasso the data is from a hypercube
     key: 'qHyperCube', // path to the hypercube from the layout,
     data: layout.qHyperCube
   }],
   settings: {} // the chart settings (scales, components, etc.)
});
}

const updatePic = (layout) => {
chart.update({ // we just need to update the data
    data: [{
     type: 'q',
     key: 'qHyperCube',
     data: layout.qHyperCube
    }]
});
}


 

Making selections in the QIX engine

The picasso q plugin has helper functions for generating methods to make QIX selections from a picasso.js brush. You just get a reference to the brush using the brush method of picasso, then use the selections method of picassoQ to generate the QIX methods, then apply them to your QIX model. It would look something like this.

const brush = chart.brush('name-of-brush'); // get reference to brush
const selection = picassoQ.selections(brush)[0]; // generate selection method
qDoc[selection.method](...selection.params); // apply selection method to model

 

 

And that's it. You can check out the observable notebook I created for this blog post, and the picasso-plugin-q too.

Francis Kabinoff

Introducing qdt-lui

Posted by Francis Kabinoff Apr 13, 2018

If you follow our blog posts regularly, you'll know we've been working on a library called qdt-components which includes a bunch of custom components we're using in our Qlik-powered apps. We've been using Bootstrap 4 with reactstrap, which is a collection of React components that use Bootstrap 4. The thing is that made Bootstrap 4 a dependency, and many of its styles are global, and that was a problem. We also wanted to be able to use Qlik's own Leonardo UI as a general style guide, but we needed the functionality of things like Bootstraps dropdowns. So we've been working on a new library called qdt-lui, which is a collection of React components that use Leonardo UI,  Just today we finally finished replacing all of the reactstrap components in qdt-components with qdt-lui components! There's still a bit of styling to touch up on because of this transition, but for the most part it's looking and working great.

 

So the general idea is very similar to reactstrap, but instead of creating React components that use Bootstrap for styles, we use Leonardo UI. So far, we have 6 components, and they are - LuiButton, LuiDropdown, LuiIcon, LuiList, LuiListItem, and LuiSearch. If you're familiar with Leonardo UI, you may be aware that Leonardo UI doesn't have a dropdown component at all, it's actually a select component that just reskins an actual html select element. But for our use cases, select elements are generally not very useful, so we borrowed the styles from the Leonardo UI select component and built something very similar to a bootstrap dropdown.

 

The LuiSearch component uses the Leonardo UI search component styles, but makes it a controlled react component which accepts as props a value and a clear method, so you can control the value from the parent component, and we can call the passed down clear method to clear the value in the parent component when you click on the clear symbol that's in the component. Again, this pattern is very similar to reactstrap, and what we've been using as a reference when building these components.

 

So check it out here - https://github.com/qlik-demo-team/qdt-lui and hopefully you find it useful. You'll be seeing it used a lot from us now in most of our projects on the demo team, and we'll have a lot of examples soon. Documentation is non-existent at the moment, but checking the source of each component and taking a look at the prop-types it should be pretty clear for now, but documentation will be coming. It's still marked as alpha, but we'll be moving it to beta soon. Let us know what you guys think, if you find this useful, and any features that you would like to see. Oh, and any pull requests submitted would have us spinning in our chairs excited, so if you're so inclined to contribute, that would be very, very cool.

As many of you know, custom themes shipped with Qlik Sense February 2018, and we covered how to start creating custom themes which you can check out here -How to create a custom theme in Qlik Sense. But did you know that Qlik Sense February 2018 also shipped with a new Theme API under the Capability APIs collection?

 

What can you do with the Theme API?

The Theme API can basically be used for two purposes, to get and to apply themes. You can view the documentation here - Theme API. Getting a theme is useful for applying styles to extensions, widgets, and mashups that are identical to the theme style. You can also apply themes to both Qlik Sense apps and independently of the theme set in the Qlik Sense app to native Qlik Sense objects created or embedded using the Visualization API (or app.getObject, if you're still using that).

 

You can get a theme using one of two different methods, the `get` method and the `getApplied` method. The difference is that the `get` method you call on the `qlik` object and pass a theme id to get any theme in your extensions, while the `getApplied` method you call on an instance of an `app` and it simply returns the current theme applied to that app. The `getApplied` method is particularly useful for widgets and extensions, since it allows you to style your widgets and extensions in such a way that they will match the theme the user applies to their app.

 

Both the `get` method and the `getApplied` method returns a promise which resolves to a `QTheme` object. The `QTheme` object currently has two methods available on it, the `getStyles` method, and the `apply` method. The `getStyles` method can be used to get a particular style by passing it a few parameters. It's an easy way to find the style you are looking for in the `QTheme` object. The `apply` method is one of the ways in which you can apply a theme to all visualizations on the page.

 

You can also apply a theme using the `apply` method of the Theme API without first fetching a `QTheme` object. The `apply` method of the Theme API just requires that you pass the theme id. These apply methods are particularly helpful for applying a theme to mashups and other embedded visualizations. Below is a code sample and image of the mashup with the theme applied.

 

require( ["js/qlik"], function ( qlik ) {


 qlik.theme.apply('high-contrast-theme');

 var app = qlik.openApp('Helpdesk Management.qvf', config);

 app.getObject('QV03','rJFbvG');
 app.getObject('QV02','xfvKMP');
 app.getObject('QV01','a5e0f12c-38f5-4da9-8f3f-0e4566b28398');
} );

mashupthemed.png

 

There's one final method to mention, and that is the `save` method. The `save` method allows you to programmatically set the theme in a Qlik Sense app. This differs from simply applying a theme, as it actually sets and saves the theme in the Qlik Sense app, and not just for the session like the apply methods do.

 

And that's the introduction to the Theme API.

banner_react.jpg

On the demo team we end up working with both the Viz API to create and embed native Qlik Sense charts in apps, as well as creating custom components powered by the Qlik Engine using enigma.js, and we do this in Angular, React, and plain html, as we try to demo all of the ways that Qlik can be used. So after my last blog post (Starter project for developing QAP-powered apps with React and enigma.js) we had an idea on the demo team: let's try to unify all of our different custom components and templates. So we've been hard at work accomplishing that.


You may have seen Yianni's last blog post, qdt-components - A Components Library that can be used in simple Html, Angular 5 and React, introducing this effort. The goal is to have the qdt-components library include custom components powered by Qlik Engine, as well as a way to create and embed native Qlik Sense charts. Right now, the qdt-components library contains a few components, but we're not totally ready to start talking about all of them yet, so we're just sticking to the component that allows you to create and embed native Qlik Sense charts by interfacing with the Viz API.


The big addition since Yianni's post is that we've added a React template, so now we have an Angular 5 template, a plain html template, and a React template, all which load the qdt-components, which is pretty cool. This means that the components only need to be built once, but can be used in a project with almost any frontend stack. I say "almost" because in order to use the component that interfaces with the Viz API there's no getting around loading Angular 1.5 and RequireJS into the global namespace, which means they still have the chance to create conflicts. But you can choose not to use the component that interfaces with the Viz API if you don't have a need for native Qlik charts, and it will avoid loading all of the Capability API stuff, but if you choose to use it, you don't have to worry about writing any of the boilerplate you usually do when connecting to the Capability API.


Documentation, examples, and custom components are coming (and oh yea, we plan on using https://picassojs.com/), but that's the update for now. You can check out the qdt-components library and the templates here - Qlik Demo Team · GitHub. And demos of each of the 3 templates below

 

Angular 5 with qdt-components

React with qdt-components

Simple html with qdt-components


I've been doing most of my projects lately with React and enigma.js, and developing some general patterns along the way that I've been working into a starter project that I can use as a starting point. I'd like to share that with you today, and potentially start a discussion around the design decisions I've made thus far.

 

The starter project can be found at GitHub - fkabinoff/qlik-react-starter: Starter project for rapidly developing QAP-powered apps. It's still very much in development, but there's a decent framework and dev environment in place, as well as a few useful components.

 

Overview

The project uses enigma.js to interface with the Qlik engine, along with React, webpack, Babel, ESLint, Sass, and a few other goodies. Really, a pretty standard React app with enigma.js added. The qDoc, which is the name the enigma.js docs use for the connection to the Qlik app is created in a plain Javascript module and simply imported to any file that needs to use it.

 

I use react-hot-loader, which allows you to change react components without refreshing the page or losing state, and I really like it. It has it's problems, most noticeably to me that it doesn't play very nicely with higher order components, but the ability to change my React components and not have to reload the page or lose state helps me develop faster.

 

I'm using the latest Babel preset, which enables es2015, es2016, and es2017, and Babel plugins which enable decorators, spread syntax, and class properties. I can't believe we actually wrote Javascript before this stuff.

 

I use the very popular airbnb config for ESLint. It helps keep the code healthy and uniform.

 

I make use of reactstrap, a library of Bootstrap 4 components for React, and SASS for customizing and mixing in Bootstrap styles, as well as creating a few utility classes. I prefer using reactstrap over some of the more feature-rich React UI libraries, because I often find it creates more work trying to make the components of those UI libraries, such as Material UI, play nicely with how I want a component in a Qlik-powered app to function since in a Qlik-powered app the Qlik engine acts as a state machine, and many of the UI libraries with more features expect the state to be managed and changed by the client. Reactstrap gives me what I need, without being too opinionated about it.

 

I use the "render prop" pattern in place of higher order components. The render prop pattern is simply passing a component as a prop to another component for that component to render it. It basically works like a higher order component does, but to me it's a bit simpler, a little more flexible, and doesn't mess with react-hot-reload or PropTypes checking.

 

Notably, I don't use a state manager like Redux or MobX, and this may be my most contentious decision. To me, the use of a state manager in most instances is redundant when building a Qlik-powered app. Qlik already manages my state, and shares it between components. I hardly, if ever, have state that needs to be managed outside of Qlik in my Qlik-powered apps, and using a state manager forces me to do extra work to keep the client state and Qlik state in sync. I don't like it.

 

It would be very interesting to hear what you think about these design decisions, and the decisions that you've made with your own Qlik projects.

 

Components

Now, let's take a look at the actual components. There are currently 4 Qlik-specific components, but I expect to add more as I continue developing this. I tried to design the Qlik-specific components to expect props which are identical to values defined in Qlik docs, and pass down values directly returned by the Qlik engine, in order to standardize as much as possible. Though in some instances, I broke that rule. For instance, since the QlikObject wrapper, which I'll talk about in a moment, is really only designed to work with an object that fetches one page, it didnt make sense to pass down the qDataPages returned by the Qlik generic object getData method. Instead, I simply pass down the object at the first index of qDataPages.

 

QlikObject.jsx

The QlikObject component implements the render prop pattern, and contains the logic to create and manage a Qlik generic object and its state. It passes down the Qlik generic object information to the component defined in the Component prop, which is responsible for rendering something.


QlikVirtualScroll.jsx

The QlikVirtualScroll component implements the render prop pattern, and paginates data on vertical scroll so only data in view gets rendered. It passes down a subet of the qMatrix to the component defined in the Component prop, which is responsible for rendering something. It is used by the QlikFilter and QlikTable components.


QlikFilter.jsx

The QlikFilter component renders a dropdown that acts as a Qlik Sense filter. It's meant to be used as the `Component` prop of a `QlikObject` component a type of `qListObject`. This component doesn't need to be passed any props other than the props passed to it by `QlikObject`.


QlikTable.jsx

The QlikTable component renders a table. It's meant to be used as the `Component` prop of a `QlikObject` component with a type of `qHyperCube`. This component requires a prop `columnWidths` to be passed to it, defining the widths of the columns of the table. This prop should be passed using the `componentProps` prop of the `QlikObject`.



Finishing up

Go to GitHub - fkabinoff/qlik-react-starter: Starter project for rapidly developing QAP-powered apps, download the zip, run npm install, and npm run dev, and you can check out the QlikFilter and QlikTable components in action, and check out the code. I'll be adding more components and styles as I'm still pretty actively developing it, so watch the repo if you're interested, and let me know what you think.

Wow! There are some really mind-blowing trends developing in BI and data analytics. Here are a few that have me the most excited, and my favorite examples of each from the past year.

 

Augmented Analytics

artificial-intelligence-2228610_640.jpg

Augmented intelligence incorporates machine learning to supplement and support human analysis. Qlik Sense is now capable of Advanced Analytics Integration through the use of server-side extensions, and Qlik Sense + Advanced Analytics = Augmented Intelligence. Go get started augmenting your own intelligence today, using Qlik Sense Advanced Analytics Toolbox.

 

speech-bubbles-303206_640.png

Conversational Analytics

As virtual assistants like Alexa and Google Assistant and chatbots in messaging services like Slack and Telegram become more ubiquitous, interest in conversational analytics continues to grow. Conversational analytics is the ability to provide a query in natural language, either spoken aloud or as text, and receive a response. The ability to simply ask a question and get an answer about your data is pretty cool. Ask some questions and get some answers by trying out QlikBotNode.

 

Immersive Analytics

thumbnail.png

Immersive analytics utilizes virtual and augmented reality to enable analytics in immersive environments. While widespread adoption of immersive analytics may be a little further off that either augmented intelligence or conversational analytics, the possibilities are truly exciting. Immerse yourself today and take a glimpse into the future with Qlik Healthcare Analytics AR.

I posted back in May about creating an app that allows a user to authenticate with Facebook, grabs the user's post data, generates a load script, and creates a Qlik Sense session app with enigma.js (When do you post to Facebook?). At the time, I still had to overcome a few hurdles to put it up live so you could check it out yourself. Since then, it's also become possible to create a Qlik Sense session app with the Capability APIs so that you can use the Visualization API with your on-the-fly Qlik Sense session apps, which I posted about in September (Creating apps on the fly).

 

The demo is now up live, and there's two versions of it, one using enigma.js, and one using the Capability APIs. They're pretty minimal when it comes to design yet, I plan on building them out a bit more still, but it's cool to just see this all working, authenticating a user with Facebook, grabbing their data, generating a load script, creating a Qlik Sense session app, and visualizing the data. It's easy to see how something like this could be applied to a business use case where users may have very user-specific data. Check the demos out below!


Capability APIs version - Qlik Sense Session App Demo - Capability APIs

enigma.js version - Qlik Sense Session App Demo  - enigma.js


One of the most useful features of Qlik Sense for me when developing a front-end is how easy it is to paginate data. Any front-end developer knows that updating thousands of dom elements is not exactly ideal, because dom updates are slow. But Qlik Sense makes it so easy to avoid ever having to do that.


For instance, take a look at the location dropdown for the Solar Eclipse demo at https://webapps.qlik.com/solar-eclipse/index.html. There’s over 29,000 rows there! But, here’s the trick – there’s only ever 10 rows in the dom at any time, and when a user scrolls what’s actually happening is the dropdown is receiving new data from Qlik Sense.


To paginate data with Qlik Sense is pretty simple. With enigma.js you’ll just create your object, either a hypercube or a list object, like usual, but you don’t need to pass it any qInitialDataFetch attribute. Then anytime you need some data, you just call a method to get data. Which method you call depends on your object. For a straight hypercube, you’d just call getHyperCubeData method like below -

 

doc.createSessionObject({
  qInfo: {
    qType: "visualization"
  },
  qHyperCubeDef: {       
    qDimensions: [
      // qDimensions
    ],
    qMeasures: [
      // qMeasures
    ]
}).then((object) => {
  object.getHyperCubeData('/qHyperCubeDef', [
   // this will fetch 1 page of data, but you could request multiple pages by adding more qPages here
    {
      qTop: 0,
      qLeft: 1,
      qHeight: 2,
      qWidth: 10
    }
  ]).then((data) => {
    // do stuff with data
  });
});

 

If your hypercube is in pivot, stack, or tree mode, or if your object is a list object, you’ll have to use the corresponding method in place of getHyperCubeData, which you can find here https://help.qlik.com/en-US/sense-developer/September2017/Subsystems/EngineAPI/Content/Classes/GenericObjectClass/GenericObject-class.htm.

 

If you’re using the Capability APIs, while not technically supported, the same methods work with the object that is returned from the promise (not the layout returned in the callback).

Overview

I've seen a few questions regarding integrating Qlik Sense visualizations into existing webapps lately, and figured I'd lay out a few tips here that may be of help.

 

There's really two ways of integrating Qlik Sense visualizations into your webapp, by either using the Capability APIs or iFrames. I'll discuss the pros and cons of both.

 

Capability APIs

The Capability APIs include the Root API, the App API, and the Visualization API, among a few others. The Root API is used to connect to an app, and either the App API or the Visualization API can be used to then embed Qlik Sense objects onto the sheet. There's quite a few resources regarding the details of actually doing this available already, so I'll skip that, but if there's any questions surrounding it, let me know. What I do want to talk about is the pros and cons of using the Capability APIs vs iFrames.

 

The pros of the Capability APIs are that all you have to do to use them is load the assets that are conveniently served from the Qlik server, supply a config, require the qlik.js file, and you're set. You can quickly get up and running, and you're able to not only embed existing visualizations, but you can create visualizations on the fly using the Visualization API and patch them as you go. So, it's easy to get going, and to embed, create, or even update visualizations on the page.

 

The downside is that the assets needed for the Capability APIs include Require.js and Angular 1.5.8, and they're both globals that can be quite intrusive, and force you to redesign your existing app to play nicely with their residency in the global scope.

 

iFrames

And that's exactly the best thing about iFrames. Since an iFrame is totally encapsulated from its parent page, there's no issues with existing assets and assets needed to embed Qlik visualizations colliding. And for all the other features that the Capability APIs offer, you can simply use enigma.js, which can share the same session as the iFrame'd objects.

 

One of the things to watch out for when using iFrames is that Internet Explorer, by default, only allows a maximum of 6 concurrent connections. So that's a limitation if you need to support IE. Another thing that you won't be doing is creating any visualizations on the fly.

 

Hybrid

To help overcome the websocket number limit, or if you really need to create visualizations on the fly, but also want to use the iFrame approach, what you can do is instead of embedding visualizations using iFrames, you can create a mashup, and then embed that into your webapp in an iFrame. Using HTML5's window.postMessage API, you can enable communication between your app and the mashup in the iFrame, and you can also still use enigma.js in your webapp.

Some of you may remember that I recently posted about a similar topic here When do you post to Facebook?, where I talked about creating an app that allows users to authenticate with Facebook, grab their data with Facebook APIs, use halyard.js to generate a load script, and then create a session app. But when I did this just a few months ago, one of the things I really wished I could do was use the Visualization API so I could simply create charts on the fly using Qlik Sense, but it wasn't possible then because a session app could not be created from or associated with the Capability APIs.

 

However, new APIs were introduced with Qlik Sense June 2017 that makes it possible to create apps on the fly using the Capability APIs, so now it is possible to create an app, load data, and create visualizations, all on the fly! This is made possible by the addition of some new methods to the Capability APIs, including the qlik.sessionApp method, the qlik.sessionAppFromApp method, the setScript method, and the getScript method.


There's already some pretty decent documentation for doing this at Qlik Sense Help - Creating apps on the fly, and I recommend you check that out, but I want to make everyone is aware of this very cool new capability of Qlik Sense June 2017, and just briefly address some issues you may run into.


First thing first, which is something I ran into while trying to create an example for this blog post -- anonymous users cannot create session apps, and this does not seem to be able to be controlled by security rules. Unless I'm missing something, it's entirely impossible. So, no anonymous users.


Next, there's been a few questions about just how to go about loading data. The simple answer is you need to set a load script using the setScript method, and then use the doReload method to load the data. But where do you get the load script from in the first place? Well you can use the getScript method on an app that already exists, or you can just write a script, though, of course, you'll need to also create the data connections you'll need somehow too if they don't already exist. And for many instances that I can think of where I would want to create an app on the fly, I'd use halyard.js. You could also create a session app from an existing app, get the load script from that app, and do some kind of search and replace on the load script which would custom tailor the data for the current user. The point is, there's a lot of possibilities, and it's really up to you and your use case how you want to go about this.

 

With being able to create apps, load scripts, and visualizations all on the fly, there's really a ton of potential to do some awesome stuff here. It would cool to hear about how some of you are using these capabilities!

I've seen a few people asking recently if and how they can use webpack to build their mashup. The answer is yes, and I'm gonna discuss a few implementation details and provide some example code.

 

So to use the Qlik Capability APIs, you're probably already aware that you need to load the Qlik Capability API code, which includes loading a custom require.js file, and then requiring the qlik.js file through the loaded instance of require.js. The thing is, there's really no way to get around this, that's how the Qlik Capability APIs are loaded.

 

But you can still use webpack for all of your own project code, you just have to decide how you are going to load the custom require.js file and where you'll use the require.js instance to require qlik.js. This is how I've been doing it.

 

First, I load the Qlik custom require.js file in a script tag in the head of the document. Can you get fancier if you'd like with something like the script-loader, yea sure you can, but the goal here is to load that Qlik custom require.js file in a global context, and to me the simplest way to do it is to just include it in a script tag in the head of my html document.

 

Then, you'll need to set the require.js config and require the qlik.js file through require.js somehow. The trick here is that the require.js instance can be accessed with window.require. Also, since requiring files with require.js is asynchronous, and you'll almost certainly want to return some stuff when qlik.js is done loading, it's useful to use a promise here. This is what my module looks like for this in ES2015 -

 

webpackcapabilityconfig.png

 

You'll notice the config object which you should be used to for mashups, then how I'm using window.require.config to set the require.js config. Also, I explicitly set the path for 'qlik' because I find this helps avoid some errors, especially with regards to loading extensions. Then, I export a promise which resolves with the app from the openApp() method as the value. You can resolve this promise with the 'qlik' object, or multiple apps, or whatever your needs are, but for myself, most of the time, I'm just opening 1 app and I just resolve the app.

 

So in summary, if you want to use webpack with the Capability APIs then the Qlik custom require.js file will need to be loaded in a global context in some way, and then you'll be able to access the require.js instance on 'window.require' (but not just simply 'require' since webpack will use that keyword).

With the Qlik Sense June 2017 release comes server side extensions, which allow you to extend the Qlik built-in expression library with functionality from external calculation engines. We've released an open source server side extension that enables interaction with R, and if you use the R-Plugin, you know that you have to start Rserve.exe and SSEtoRserve.exe, then restart the Qlik Sense Engine Service. What I'm going to walk you through is how to setup Rserve.exe and SSEtoRserve.exe to run as services, and then make the Qlik Sense Engine Service depend on those services so that they start whenever the Qlik Sense Engine Service starts.

This post is for people who have already installed the open source R-Plugin and would like to run the plugin as a Windows service instead of starting it manually. If you haven't gotten started with the open source R-Plugin, and would like to, please check out this guide sse-r-plugin - get started.

 

The first thing we need is NSSM. Download and unzip, then open a command prompt with admin privileges and change directory to  <path-to-nssm>\nssm-{x}.{x}{x}\win64.

nssm.png

 

Now we need to install our 2 new services. In the command prompt, enter nssm install RserveService. An interface will pop up where we can define the service. Enter <directory>\Rserve.exe into "Path", and set "Startup directory" to the directory Rserve.exe is in. Then, go to the "Environment" tab, and enter PATH=%Path%;C:\R\R-3.4.1\bin\x64 (assuming you have R-3.4.1 installed in the C:\R directory, otherwise make adjustments as necessary). Now click the "Install service" button.

rservepath.pngrserveenv.png

 

Next, we need to install a service for SSEtoRserve.exe. So, again, at the command prompt enter nssm install SSEtoRserveService, and then enter <directory>\SSEtoRserve.exe into "Path", and set "Startup directory" to the directory SSEtoRserve.exe is in. Now click "Install service".

ssetorserve.png

 

Now that the two services are installed, we can set the Qlik Sense Engine Service to depend on them, so that any time the Qlik Sense Engine Service starts, these services will be available. Back at the command prompt enter nssm edit QlikSenseEngineService. Go to the "Dependencies" tab and add RserveService and SSEtoRserveService, each on their own new lines under the already existing QlikSenseRepositoryService.

engineservice.png

 

All of you have to do now is restart the Qlik Sense Engine Service and you should be good to go.

If you're creating a mashup that includes embedded Qlik Sense charts, there's a couple issues you may run into that you'll want to be aware of.

 

First, if your mashup scrolls, and you scroll down the page, you will notice that the tooltips on the Qlik Sense charts are not positioned correctly, like below:

2017-06-07 11_20_25-Marató Barcelona.png

The tooltips will get more and more displaced the further down the page you scroll. For the tooltips to be positioned correctly, you'll have to adjust how scrolling happens on your page a little bit.

 

The easiest option that you can implement with just some CSS is to set the html and body tags to a height of 100%, hide the overflow on the html tag, and add use overflow: auto on the body tag. That looks like this:

html, body {
height: 100%;
overflow: hidden;
}
body {
overflow: auto;
}









 

Now the tooltips will no longer be displaced when you scroll your mashup. However, there are times when it may be necessary to watch the scroll position of the page, or be able to set the scroll position of the page programmatically, and for some reason, when using the above method the scrollTop attribute of the body tag never actually updates, so there is no way to observe when the page scrolls or set the scroll position programmatically.

 

In instances like this, just a simple extra step will fix the issue. What you'll need to do is add a wrapper element that wraps the entire content of your mashup, and also set that to a height of 100%, and put the overflow on that element. That element's scrollTop will be set correctly, and you can observe or set it programmatically. So, it would be something like this:

<head>
<style>
  html, body, #page-content {
    height: 100%;
    overflow: hidden;
  }
  #page-content {
    overflow: auto;
  }
</style>
</head>
<body>
<div id="page-content">
  <!-- All of your content -->
</div>
</body>









 

The other issue you may run into is the chart tooltip not be styled correctly, since it may be affected by the CSS in your mashup. The most common example I see of this is if using Bootstrap v4. Bootstrap v4 adds some negative margins to the .row class, and the tooltip also uses the row class, and it makes the text in the tooltip get cut off, like this:

2017-06-07 12_11_20-Marató Barcelona.png

To fix this, and any other styling issues you may have with the tooltips, it's helpful to be able to inspect it. A div with the class .qs-chart-tooltip will be appended near the end of the body. If you inspect the page and find that element, then expand it, it's first child element is a div that has display: none set, just uncheck that style and you'll be able to view the tooltip in it's last location. Then you can continue to expand those child elements and inspect the element, looking for any issues. In the case I show above, as I stated, the problem is with Bootstrap v4 and it's negative margins on the .row class. So the css below fixed the tooltip:

.qv-chart-tooltip-inner .row {
margin-left: 0;
margin-right: 0;
}


 

So, now you should be able to address these Qlik Sense chart tooltip issues I often see in mashups. If you have any questions, let me know!

Halyard.js is a new open source library that simplifies the Qlik Sense data load experience as it abstracts away the need to write a load script. Halyard.js includes a mixin for enigma.js for loading your halyard representation into the QIX engine. Using halyard.js and enigma.js, it’s now pretty trivial to generate a load script and create an app on the fly.

 

I built an app that uses Facebook’s API to grab user’s posts, halyard.js to generate a load script, enigma.js to create a session app and objects, and then displays a few filters and a visualization just to test out the whole flow, and it was awesome. I made a video of the results below, check it out.



I want to put this app up live so everyone can try it out because it's so cool, but I’m waiting on Facebook approval. In the meantime, you can grab the source code below and try it out on your own machine.


There’s a few steps to do that. First, download the source code and run npm install. Then go to the qapp.js file and enter session info for your Qlik Sense server in the config variable on line 8. Next, you’ll have to go to https://developers.facebook.com/ and create an app. Once your Facebook app is created, grab the App ID and enter it in the fb.js file, on line 26.

For your Facebook App to be able to authorize users, you’ll need to add a platform and app domain in the “Settings” page of the Facebook app.

It’s up to you how to host this. I’ve included a .qext file if you just want to use Qlik Sense Desktop.

 

Once you’ve done that, run npm run webpack to build the project, and it should be good to give it a go!

Filter Blog

By date:
By tag: