1 2 3 Previous Next

Qlik Design Blog

32 Posts authored by: Yianni Ververis

There are cases where we need to switch among charts in a mashup. The easiest way is with jQuery show/hide or if you are using Angular then show the chart based on the model value.

 

But what about if we have many charts, with the same measures but only the dimensions change? What if we could just change the dimension in the engine and let the engine take care of all the changes and animations?

 

This is possible through the Visualization API and the applyPatches() method.

 

Here I will explain how to create a simple dropdown that changes based on the dimension selected. Since I am using Angularjs 1.5.8 like Qlik Sense September 2017, I have created a component that

a) gets first object,

b) populates a dropdown with titles and

c) upon change, the chart is changing based on the dimension provided

 

First, we get the first object as usual and display it in our mashup. This is what the html looks like

<sense-object-multi-dropdown

                qvid="'BRjnYJ'"

                height="300"

                data="[

                    {title:'Total Costs by Branch', dimension:'Branch'},

                    {title:'Total Costs by Work Center', dimension:'Work Center Name'},

                    {title:'Total Costs by Division', dimension:'Division'},

                    {title:'Total Costs by Collection', dimension:'Collection'}

                ]"

            ></sense-object-multi-dropdown>

 

Here, in the "qvid" is the id (BRjnYJ) of the first object. In the "data" we add the title as we want it to display in our dropdown and the actual dimension.

 

In our components's Javascript code, we get and then show the object as usual

qlik.app.visualization.get($ctrl.qvid).then(function (viz) {

        $ctrl.viz = viz;

        $ctrl.viz.show($element.find('#obj'))

        $element.find('.qv-object-header').remove();

    });

 

Here is the html code for the component

<div class="sense-object-multi-dropdown">

    <div class="v title-1">{{ $ctrl.currentData.title }}</div>

    <div class="dropdown">

        <a class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">

            <i class="fa fa-chevron-down" aria-hidden="true"></i>

        </a>

        <div class="dropdown-menu" aria-labelledby="dropdownMenuButton">

            <a class="dropdown-item" href ng-repeat="item in $ctrl.data" ng-click="$ctrl.change(item)">{{item.title}}</a>

        </div>

        </div>

    <div class="qvobject" id="obj" height="{{$ctrl.height}}"></div>

</div>

 

Now, by just this, the page should have a chart and a dropdown populated.

2017-10-12 10_41_09-Plant Operations.png

 

Now, let's add the code that will change the dimension

    $ctrl.change = function(item) {

        $ctrl.currentData = item;

        $ctrl.viz.model.applyPatches([{

            qOp: "replace",

            qPath: "/qHyperCubeDef/qDimensions/0/qDef/qFieldDefs/0",

             qValue: `\"${$ctrl.currentData.dimension}\"`

  }], true);

    }

 

Here we are telling the engine that, hey for this object (model), replace the first field (qFieldDefs) of the first dimension (qDimensions) to the one I am giving you.

 

That's it. Once the engine receives the new change via websocket, it will redraw automatically, without any flickering and it will animate from one chart to the next.

 

Attached is my entire component if you want to use it in your Angular apps. Feel free to remove all the unnecessary libraries to make it work.

 

 

Live example: Plant Operations "Total Costs by Division"

 

Yianni

While ago I wrote a simple tutorial on how to connect to Trello API and get the lists and cards into Qlik SenseTrello and Qlik Sense.

 

Today I will go one step further and add more fields into Trello so we can import them into sense and use them as filters. I will use the labels and due dates.

 

I like to use labels to highlight the importance or urgency of each project. So I named all of the labels as:

2017-07-19 08_19_31-_ SaaS Demo on Qlik - Demos &amp; Best Practices _ Trello.png

 

So in one of my cards, I have given it a label of normal and I have added a due date for today which I also marked it as complete. So, this is how my card should like

 

2017-08-18 16_26_22-_ Qlik Design Blog on Qlik - Demos &amp; Best Practices _ Trello.png

 

Now lets go to my Qlik Sense and try to re import the cards.

 

I have changed the api path from last time to :

https://api.trello.com/1/boards/[board-id]/cards?fields=all&members=true&key=[key-id]&token=[token-id]

 

Here is my load script

 

LIB CONNECT TO 'Demos - Trello-cards';

RestConnectorMasterTable:
SQL SELECT 
"id" AS "id_u1",
"name" AS "name_u0",
"idList",
"url",
"due",
"dueComplete",
"__KEY_root",
(SELECT 
"id",
"idBoard",
"name",
"color",
"uses",
"__FK_labels"
FROM "labels" FK "__FK_labels"),
(SELECT 
"id" AS "id_u0",
"avatarHash",
"fullName",
"initials",
"username",
"__FK_members"
FROM "members" FK "__FK_members")
FROM JSON (wrap on) "root" PK "__KEY_root";

[labels]:
LOAD [id] AS [trello.label.id],
[idBoard] AS [trello.board.id],
[name] AS [trello.label.name],
[color] AS [trello.label.color],
[uses] AS [trello.label.uses],
[__FK_labels] AS [__KEY_root]
RESIDENT RestConnectorMasterTable
WHERE NOT IsNull([__FK_labels]);

[members]:
LOAD [id_u0] AS [trello.member.id],
[avatarHash] AS [trello.member.avatarHash],
[fullName] AS [trello.member.fullName],
[initials] AS [trello.member.initials],
[username] AS [trello.member.username],
[__FK_members] AS [__KEY_root]
RESIDENT RestConnectorMasterTable
WHERE NOT IsNull([__FK_members]);

[root]:
LOAD [id_u1] AS [trello.card.id],
[name_u0] AS [trello.card.name],
[idList] AS [trello.list.id],
[url] AS [trello.card.url],
//[due] AS [trello.card.due],
    Date([due],'MM/DD/YYYY') as [trello.card.due],
[dueComplete] AS [trello.card.dueComplete],
[__KEY_root] AS [__KEY_root]
RESIDENT RestConnectorMasterTable
WHERE NOT IsNull([__KEY_root]);

DROP TABLE RestConnectorMasterTable;

 

If everything works well you should be able to get all of your cards in the QVF. Now, lets add the filters for priority and completed

2017-08-18 16_43_49-.png

 

That's it!

 

Yianni

Yianni Ververis

Trello and Qlik Sense

Posted by Yianni Ververis Jul 21, 2017

Are you a Trello user and want to start integrating your cards with Qlik Sense and getting some statistical analysis out of your projects' workflow? Here I will show you how to connect to you boards and get your lists and cards into Qlik Sense.

 

First, you need to have a developer’s key and an authorization token, both generated for you by trello.com.

  • To get you Key you need to go to https://trello.com/app-key
  • To get your Auth token, at the same page, right under your key, there is a link "Token". Click on that and it will take to a page that asks you "Let Server Token use your account?". You need to click "Allow" and then copy the key.

 

Then, lets go to Qlik Sense and setup our Rest Connector to get our data. All of the desired template links are in Trello Developers. Here I will just create a simple connection that retrieves all of the lists and their cards from a single board

  • Go to your "Data Load Editor"
  • Create a new section and name it Trello
  • Create a new connection using the "Qlik REST Connector"
  • In the url add "https://api.trello.com/1/boards/[board_id]/lists?cards=open&card_fields=name&fields=name&key=[key]&token=[token]". Don't forget to substitute the key and token that you got above. To get your board id, simply open your trello board and go to the url. It should be in the form of "https://trello.com/b/[board_id]/[your-board-name]".
  • Method is "GET"
  • Under Authentication select "BASIC" and add your username and password, give it a name and save it.
  • 2017-07-19 07_49_08-Qlik Sense Desktop.png
  • Click on "Select Data" and select what you want to get. If you select "root", you will get only the lists. If you select cards too, then you will get all of the lists with their cards
  • The REST Connector should generate the load script for you and should look something like this

 

LIB CONNECT TO 'Trello-board-list';

RestConnectorMasterTable:
SQL SELECT
"id" AS "id_u0",
"name" AS "name_u0",
"__KEY_root",
(SELECT
"id",
"name",
"__FK_cards"
FROM "cards" FK "__FK_cards")
FROM JSON (wrap on) "root" PK "__KEY_root";

[cards]:
LOAD [id] AS [card_id],
[name] AS [card_name],
[__FK_cards] AS [list_key]
RESIDENT RestConnectorMasterTable
WHERE NOT IsNull([__FK_cards]);

[root]:
LOAD [id_u0] AS [list_id],
[name_u0] AS [list_name],
[__KEY_root] AS [list_key]
RESIDENT RestConnectorMasterTable
WHERE NOT IsNull([__KEY_root]);

DROP TABLE RestConnectorMasterTable;






 

The end result should be something like :

2017-07-18 10_48_40-Qlik Sense Desktop.png

 

There are a lot of possibilities here. You can combine this with some power ups/custom fields that you would like to track and get more detail into your visualizations.

 

This is it!! Now with few steps you can add your lists and cards intro Qlik Sense and create charts or KPIs based on these data.

 

https://branch-blog.qlik.com/trello-and-qlik-sense-2da6e1912967

 

Yianni

A while ago I blogged about 2 of our most beautiful mashups in the Demo Team, Salesforce and CIO dashboard.

 

Case study: Salesforce mashup

Jazzing up your Mashups

 

After I was asked by many for the source files, here are the 2 github pages

 

GitHub - yianni-ververis/CIO: CIO mashup created by the Demo Team

GitHub - yianni-ververis/Salesforce: Salesforce Mashup created by the Demo Team

 

Upload the qvfs on your server and put the ids into the project.json file. Then in the command line type "npm install" to install all the required libraries and "gulp" to build and run the project.

 

Depending of the version of Qlik Sense you are running, most likely you will get CORS errors and some fonts may not load up. If you have valid certificates for localhost then under ./gulp-tasks/server.js comment out lines 15-18

 

Mashups:

https://webapps.qlik.com/salesforce/index.html

CIO Dashboard

 

Best,

Yianni

Last year I blogged about our  Mobile Friendly Horizontal Bar Chart that we use in most of our mashups in the Qlik Demo Team.

 

Since then, many things have changed. For a start, if you have a mashup that uses many objects, you will see the load time to be much faster since I used d3.v4 and I have added a break point on how many bars to create, You can define if you want to show all or only the first 50.

 

I have also changed the currency. If you select the measure to be displayed as 'auto' then extension will use the custom format. You can abbreviate the measure with their respective symbol like 'B' for billions, 'T' for trillions etc and use your custom currency symbol

2017-05-24 18_04_56-Nordea Masters - CBO _ Sheets - Qlik Sense.png

Another new feature is the custom text to display when there is no data. If you make a selection in the sheet and that produces no results then this text will be displayed.

2017-05-25 19_33_42-_Nordea Masters - CBO - 2017 Nordea Golfers _ Sheets - Qlik Sense.png

 

Also, the tooltip is more elegant now and different from the standard Qlik Sense one. I changed it to follow the mouse instead of always aligned center at the top of the bar

2017-05-25 17_40_21-_Nordea Masters - CBO - 2017 Nordea Golfers _ Sheets - Qlik Sense.png

YIANNI

 

Files

Qlik Branch

After reading Michael's wonderful post on the 3.2 features, https://community.qlik.com/blogs/qlikviewdesignblog/2017/04/04/introducing-qlik-sense-32?et=blogs.comment.created#commen…, I admit, I wanted to get into more details on each of the topics he mentioned. Even though this is impossible since there are so many goodies hidden in 3.2, I decided to focus more on the properties panel while creating custom extensions.

 

Some of these will make us retouch some of our extensions since, personally, I used workarounds like custom color in an input field as hex, inject dropdowns as html etc

 

Below I show the latest properties and at the end I attach an extension with everything working... Please note that, as the help pages suggest, some of these are "considered EXPERIMENTAL and may be subject to change or be removed in future releases."

For more details, please bookmark Qlik Sense Developer's help page

http://help.qlik.com/en-US/sense-developer/3.2/Subsystems/APIs/Content/extensions-api-reference.htm

 

SIMPLE TEXT DESCRIPTIONInteger
2017-04-28 23_07_23-Helpdesk Management - Google Charts _ Sheets - Qlik Sense.png2017-04-28 23_08_10-Helpdesk Management - Google Charts _ Sheets - Qlik Sense.png

text: {

    label:"This is a description for the properties panel (Text Component)",

    component: "text"

},

fontSize: {

    type: "integer",

    expression: "none",

    label: "Font Size (Integer)",

    defaultValue: "10",

    ref: "vars.fontSize"

},


 

INPUT TEXTBUTTON
2017-04-28 23_09_25-Helpdesk Management - Google Charts _ Sheets - Qlik Sense.png2017-04-28 23_09_40-Helpdesk Management - Google Charts _ Sheets - Qlik Sense.png

inputText: {

    type: "string",

    expression: "none",

    label: "String (Input Text)",

    defaultValue: "This is a test app to checkout custom properties",

    ref: "vars.inputText"

},

button: {

    label:"My Button (Button Component)",

    component: "button",

    action: function(data){

        alert("My visualization extension name is '"+data.visualization+"' and have id '"+data.qInfo.qId+"'.");

    }

},

 

BUTTON GROUPHeader 2
2017-04-28 23_09_54-Helpdesk Management - Google Charts _ Sheets - Qlik Sense.png2017-04-28 23_10_06-Helpdesk Management - Google Charts _ Sheets - Qlik Sense.png

weight: {

    type: "string",

    component: "buttongroup",

    label: "Font Weight (Button Group)",

    ref: "vars.weight",

    options: [{

        value: "bold",

        label: "Bold",

        tooltip: "Select for Bold text"

    }, {

        value: "normal",

        label: "Normal",

        tooltip: "Select for normal text"

    }],

    defaultValue: "normal"

},

show: {

    type: "boolean",

    label: "Show extra div? (boolean)",

    ref: "vars.show",

    defaultValue: false

},

 

COLOR PICKERDROP DOWN
2017-04-28 23_10_14-Helpdesk Management - Google Charts _ Sheets - Qlik Sense.png2017-04-28 23_10_24-Helpdesk Management - Google Charts _ Sheets - Qlik Sense.png

colorPicker: {

    label:"Background (Color-picker)",

    component: "color-picker",

    ref: "vars.color",

    type: "integer",

    defaultValue: 0

},

dropDown: {

    type: "string",

    component: "dropdown",

    label: "Select Options (dropdown)",

    ref: "vars.dropDown",

    options: [{

        value: "option1",

        label: "Option 1",

        tooltip: "Select for Option 1"

    }, {

        value: "option2",

        label: "Option 2",

        tooltip: "Select for Option 2"

    }, {

        value: "option3",

        label: "Option 3",

        tooltip: "Select for Option 3"

    }],

    defaultValue: "option2"

},

 

LINKSLIDER
2017-04-28 23_10_40-Helpdesk Management - Google Charts _ Sheets - Qlik Sense.png2017-04-28 23_10_59-Helpdesk Management - Google Charts _ Sheets - Qlik Sense.png

link: {

    label:"http://help.qlik.com/en-US/sense-developer/3.2/Subsystems/APIs/Content/ExtensionAPI/property-definition-link.htm",

    component: "link",

    url:"http://help.qlik.com/en-US/sense-developer/3.2/Subsystems/APIs/Content/ExtensionAPI/property-definition-link.htm"

},

slider: {

    type: "number",

    component: "slider",

    label: "Letter Spacing (Slider)",

    ref: "vars.slider",

    min: 1,

    max: 10,

    step: 1,

    defaultValue: 1

},

 

RANGE SLIDERSWITCH
2017-04-28 23_11_07-Helpdesk Management - Google Charts _ Sheets - Qlik Sense.png2017-04-28 23_11_14-Helpdesk Management - Google Charts _ Sheets - Qlik Sense.png

rangeSlider: {

    type: "array",

    component: "slider",

    label: "Range slider",

    ref: "vars.rangeSlider",

    min: 1,

    max: 20,

    step: 1,

    defaultValue: [8, 17]

},

switch: {

    type: "boolean",

    component: "switch",

    label: "Show Border (Switch)",

    ref: "vars.switch",

    options: [{

        value: true,

        label: "Show"

    }, {

        value: false,

        label: "Hide"

    }],

    defaultValue: false

},

 

TEXT AREAARRAYS
2017-04-28 23_11_23-Helpdesk Management - Google Charts _ Sheets - Qlik Sense.png2017-04-28 23_11_40-Helpdesk Management - Google Charts _ Sheets - Qlik Sense.png

textarea: {

    label:"Textarea",

    component: "textarea",

    rows: 7,//the amount of rows in the textarea component (default is 3)

    maxlength: 100,//will not allow more than 100 characters

    ref: "vars.textarea",

    defaultValue: "This can be your fottnote/legend to your visualizations"

},

MyList: {

    type: "array",

    ref: "listItems",

    label: "List Items",

    itemTitleRef: "label",

    allowAdd: true,

    allowRemove: true,

    allowMove: true,

    addTranslation: "Add Item",

    items: {

        label: {

            type: "string",

            ref: "label",

            label: "Label",

            expression: "none"

        },

        textarea: {

            label:"My textarea",

            component: "textarea",

            maxlength: 100,//you shouldn't write too much

            ref: "myTextarea"

        }

    }

}

 

Attached find the extension.

 

Yianni

Yianni Ververis

BiPartite Extension

Posted by Yianni Ververis Mar 31, 2017

One interesting Qlik Sense extension that we have successfully used, is the BiPartite one. We have used it in couple of mashups like the UK Migration http://webapps.qlik.com/telegraph/uk-migration/index.html.

 

I like this one since you have a visual representation of all the values, selected and not and there is a nice animation moving from one dimension value to the next.

2017-03-30 14_00_01-_UKMigration _ Sheets - Qlik Sense.png

 

This is a responsive extension with minimum view of 320px. You add One dimension for the left column and one for the right and then one measure for the values in each column.


You can write your own labels for each column and add your custom coloring palette.


That's it! Give it a try


Branch : http://branch.qlik.com/#!/project/58b820c55efd3b8f0b6743ce

Git: https://github.com/yianni-ververis/SenseUI-BiPartite


Another great mashup from the Demo Team!

 

After my favorite CIO where we introduced KPIs into the navigation, salesforce is beautiful, elegant and made mostly of custom extensions!

 

I started with the custom Selection toolbar (Angular Directive) that I introduced in the CIO dashboard. This changes based on the number of selections, if it's only one item of that dimension selected, or more than 6, it displays "Dimension: item selected". If there are more than one, but less than 6 items selected, it changes to a dropdown menu with the x button to deselect it. This is listening to selections, which means that whatever selections are made in the webpage, they will be displayed here as well.

2017-03-03 08_51_07-Salesforce.png

Then, we needed Sense like filters but as drop down menus (Angular Directive). I have done this with the UN Gender Statistics site but this one is more advanced and stays open until you finish making all selections and sorts them by state. It scrolls if many items.

2017-03-03 08_56_03-Salesforce.png

 

Another issue we were faced with, was that we created a combo chart in Sense but we needed to customize the colors to match our webpage. This lead me to create the Combo Chart extension. This not only gives you the option of changing colors but, hover states, borders, set bar widths, dot widths, has a better display of the labels etc.

2017-03-03 11_23_51-Salesforce_Mashup_Demo_Team _ Sheets - Qlik Sense.png

 

In the same page, we had to display and compare two vertical bar charts. The problem is that when we placed the out-of-the-box ones, the y-axis max were different thus visually misleading.  So I used the combo chart with only one measure and set the max to achieve the desired results

2017-03-03 09_32_24-_Salesforce_Mashup_Demo_Team - Dashboard 2 _ App overview - Qlik Sense.png

2017-03-03 11_26_06-Salesforce.png

 

Moving on to the next page, we had two more issues to solve.

We needed to have a Stacked bar Chart based on the value of the measure and not the number of measures. For this, I created the SenseUI-ValueStackedbarChart. I used the same tooltips, coloring, hover states etc as I used in my other extension like my most popular one, SenseUI-BarChart.

2017-03-03 10_27_46-_Salesforce_Mashup_Demo_Team - Opportunities 1 _ Sheets - Qlik Sense.png

The other issue was that we needed a horizontal menu for quarters and years. For this I used an older extension, the SenseUI-Filter.

2017-03-03 10_47_36-Salesforce.png

Lastly, I used my SenseUI-BarChart extension for all of the horizontal bars. I used the same bar color, border and hover color to match the rest of the website's objects.

2017-03-03 14_04_16-Salesforce.png

The mashup is found at http://webapps.qlik.com/salesforce/index.html

Please note that this is a work in progress. I still have to work on the mobile version and some other UI issues

 

Extensions mentioned here:

Senseui-ComboChart

SenseUI-ValueStackedbarChart

SenseUI-BarChart

SenseUI-Filter

 

For more of our work, you can go to webapps.qlik.com

 

Yianni

As we were working on one of our projects, we had the need of creating multiple combo charts. The problem was that we could not change the colors to match our mashup/webpage. So, I decided to make an extension, that gives full control of the chart appearance and it's labels. The same as my Barchart extension this is wrapping text labels underneath the bars. If you still have problems with the text, then just increase the width of the bars and everything should be back in place.

 

Installation

- [Download zip file](https://github.com/yianni-ververis/SenseUI-ComboChart/archive/master.zip)

- Desktop - Unzip at the extension folder (C:\Users\<user>\Documents\Qlik\Sense\Extensions\SenseUIComboChart)

- Server - Upload the zip file

 

 

Usage

 

Dimensions and Measures

- Set 1 dimension for the x Axis

- Set 1 Measure for an additional Line Chart

 

 

General Settings

- Font Size

- Font Color

- Display the Legend

- Enable/Disable Selections

 

 

Bar Chart Settings

- Bar Color

- Bar Hover Color

- Bar Width (0 for auto scaling)

- Bar Border Color

- Bar Border Width

 

 

Line Chart Settings

- Line Color

- Line Width

- Dot Color

- Dot Stroke Color

- Dot Stroke Width

- Dot Radius

 

preview2.png

 

preview2.png

 

Barnch: http://branch.qlik.com/#!/project/5894e07a75db504d76ac3123

Git: GitHub - yianni-ververis/SenseUI-ComboChart: Qlik Sense Combo Chart

 

Yianni

UN was one of my most challenging projects in many aspects. This was not just a simple mashup or a simple webpage that uses the Capabilities Api and app.getObject() to display Qlik Sense objects. It was an entire solution that required many teams to be involved and share their expertise.

 

One of the most interesting problems I faced, was the structure of the qvf. In order for most of the charts to work, there had to be a group of selections made and in some cases, in a specific order.

 

For this example, I will talk about the chart on the Indicators page.

 

First we have to select the field "domain" and then get all of the available "Tier" in order to populate the drop down.

2017_01_06_11_22_06_UN_Gender_Statistics1.png

 

app.obj.app.field('DomainName').select([value], false, false)
.then(function(){
     me.getTier();
});



 

Then to get the HyperCube for the Field "Tier"

  me.getTier = function () {
       api.getFieldDataQ('Tier').then(function (data) {
          $scope.Tier = _.filter(data, function(obj){
          return (obj[0].qState!=='X' && obj[0].qState!=='L')?true:false;
     });
       $scope.selectTier($scope.Tier[0][0].qNum);
  });
  }

 

and populate the drop down with Angular's ng-repeat

<div class="dropdown" id="dropdownTier">
  <label>Select Tier:</label>
  <button class="btn btn-default dropdown-toggle btn-block text-left" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
  {{selection.Tier}}
  <span class="caret pull-right"></span>
  </button>
  <ul class="dropdown-menu scrollable-menu" aria-labelledby="dropdownTier">
  <li ng-repeat="item in Tier" ng-class="(selection.Tier==item[0].qNum) ? 'active' : ''"><a ng-click="selectTier(item[0].qNum)">{{ item[0].qText }}</a></li>
  </ul>
  </div>

 

Like this

2017_01_06_11_45_52_UN_Gender_Statistics.png

Then we select the first one so get the the data from the field "seriesName" as indicators for only that tier

$scope.selectTier = function (value) {
  $scope.selection['Tier'] = value;
  app.obj.app.field('Tier').selectValues([value], false, false)
  .then(function(){
  me.getIndicator();
  })
  }

 

me.getIndicator = function () {
  api.getHyperCubeQ(['IndicatorID','SeriesName'],[]).then(function(data3){
  $scope.SeriesName = _.filter(data3, function(obj3){
  return (obj3[1].qState!=='X' && obj3[1].qState!=='L')?true:false;
  });
  if (!$scope.SeriesName.length) {
  $scope.selectionDisplay.SeriesName = "No Data";
  $scope.selection.SeriesName = null;
  } else {
                        $scope.selectIndicator($scope.SeriesName[0][0].qNum, $scope.SeriesName[0][1].qText);
  }
  })
  }

 

and populate the indicator drop down

  <div class="dropdown" id="dropdownSeriesName">
  <label>Select Indicator:</label>
  <button class="btn btn-default dropdown-toggle btn-block text-left" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
  {{ selectionDisplay.SeriesName }}
  <span class="caret pull-right"></span>
  </button>
  <ul class="dropdown-menu scrollable-menu" aria-labelledby="dropdownSeriesName">
  <li ng-repeat="item in SeriesName" ng-class="(selection.SeriesName===item[1].qText) ? 'active' : ''"><a ng-click="selectIndicator(item[0].qNum, item[1].qText)"> {{ item[0].qText }}-{{ item[1].qText }}</a></li>
  </ul>
  </div>

 

Like this

2017_01_06_17_37_41_UN_Gender_Statistics.png

 

Last, select the indicator to get the final chart

2017_01_06_18_34_35_UN_Gender_Statistics.png

 

The entire thing takes about 3 seconds to load but there is no delay to the common user because while the selections are made the object is loading and the canvas is drawn.

 

The Angular Service Api that I use for HyperCubes is here

capabilities-api-angular-template/api.js at master · yianni-ververis/capabilities-api-angular-template · GitHub

 

URL: https://genderstats.un.org/#/indicators

 

Yianni

Qlik Sense is headed to a more flexible and customizable environment regarding the interface. With Qlik Sense 3 and above, we can manually change the default Theme or create a custom one and use it on our apps by just adding /theme/<themename> at the end of the url.

 

First of all, for those that do not know, once Qlik Sense desktop is running, we can access the hub from a regular browser like http://localhost:4848/hub/my/work. Now if we add our theme at the end of the url, every app that we open, will use that theme. So, if we go to http://localhost:4848/hub/my/work/theme/yianni, this will open the hub. Every app like the "helpdesk Management" that is opened, will use that theme.


I have created a simple theme and I only changed the background color of the sheet container and it looks like this

test.png

 

In Qlik Sense 3.1.2 and above, the theme templates have been moved to C:\Users\<username>\AppData\Local\Programs\Qlik\Sense\Client\themes\old. So we can place our files there.

 

Some of us, including myself, have used the Theme.palette in our extensions like

define([
     "qlik",
     "jquery",
     "core.utils/theme"
], function (qlik, $, Theme) {


 

The above would have to change to

define([
     "qlik",
     "jquery",
     "text!themes/old/sense/theme.json"
], function (qlik, $, Theme) {
     Theme = JSON.parse(Theme);


While I was working on one of my projects that has lots of kpis and charts, I thought what if, at least for the page change, I add a simple transition. While this can accomplished easily with Angularjs, I went a little bit further and I added transitions on all of the page objects. The best part of this, is not that its only interesting but also very very easy to put together. It's all CSS3 based, so no Javascript will be needed anywhere.

 

I used the css library Animate.css. First, let's start by adding it into our html page

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css">




 

Then comes the very hard part . Add the css class "animated" and the type of animation that you want in your object's div container. In this project I used zoom in from the right for each of the page objects:

<div class="col-md-2 no-margin-padding-right animated zoomInRight ms500">




 

To make it more interesting, since I have a side navigation for all my Qlik Sense filters, I decided to add a little drop/bounce effect.

 

Now, here comes the important stuff. Since there are a lot of animations, it is not good to get our audience confused or tired from all of the things that are happening. There has to be a sequence of things. Since most of the people are reading from left to right, it makes sense to give to the user the same experience, with animations happening one after the other, from left to right so the eye can follow them. Not too slow so its not boring and not too fast so its not confusing. You can achieve that by delaying each object few milliseconds with the "animation-delay" property (CSS3 animation-delay Property).

 

I found out that 250ms between each animation, was very close to what I wanted to achieve. So, I created a lot of css classes with each being 250 milliseconds apart, like "ms250", "ms500" etc. and I added them into each of my objects.

 

This is not perfect since there is a difference from loading stating text and giving it a few milliseconds delay, from Qlik Sense objects that need some time to get pulled and drawn from our websocket connection.


Here is the work in progress. The filters bounce only once when the entire app/mashup loads since they are the same on every page, but the objects inside the actual page are hidden and then zooming in on every page transition.


CIO Dashboard

https://branch-blog.qlik.com/jazzing-up-your-mashups-aca99809dbc7

 

Yianni

As I was working on one of my latest mashups, I had a task, to get all cells with numerous sets of dimensions and measures, with a HyperCube out of Qlik Sense. The worst part is that one of my sets, had a total of 3+ million cells!

 

We know that the initial HyperCube returns only up to ~10k cells, So the question is how do we paginate to get the rest or even get them all in one call!

 

We also know that, most of the Capability API methods are using promises, something very helpful, especially if we make a lot of calls to Qlik Sense and expect to return the results only when all of the promises have been resolved. This is where promises “.all()” come into play.

 

Even though ES6 has promises build in, not all browsers support it yet, so I will use Angular's $q to handle those promises.

 

First we have to make the initial call and get the maximum rows and columns. We start by creating the cube with the dimensions

 

app.createCube({
     qDimensions : qDimensions,
     qMeasures : qMeasures
}).then(function(model) {


 

Once we have the model ready, we make the initial call to get the first set of results and get the HyperCube info like total columns and total rows

 

model.getHyperCubeData('/qHyperCubeDef', [{qTop: 0, qWidth: 20, qLeft: 0, qHeight: 500}]).then(function(data) {


 

Once we have that we can determine how many total pages do we have

 

var columns = model.layout.qHyperCube.qSize.qcx;
var totalheight = model.layout.qHyperCube.qSize.qcy;
var pageheight = Math.floor(10000 / columns);
var numberOfPages = Math.ceil(totalheight / pageheight);


 

Now, if we got all of the results, we should end the method and return those results

 

if (numberOfPages==1) {
     deferred.resolve(data.qDataPages[0].qMatrix);
}


 

Otherwise, we should get the data from all pages and then return the results! Promises in full glory!!!

 

var Promise = $q;
var promises = Array.apply(null, Array(numberOfPages)).map(function(data, index) {
var page = {
          qTop: (pageheight * index) + index,
          qLeft: 0,
          qWidth: columns,
          qHeight: pageheight,
          index: index
     };                                                                                           
     return model.getHyperCubeData('/qHyperCubeDef', [page]);
}, this);                                                                
Promise.all(promises).then(function(data) {
     for (var j=0; j<data.length; j++) {
          for (var k=0; k<data[j].qDataPages[0].qMatrix.length; k++) {                                                       
               qTotalData.push(data[j].qDataPages[0].qMatrix[k])
          }
     }
     deferred.resolve(qTotalData);
});




 

This is how we get all of the results for a given set of Dimensions and Measures.

 

If you want to paginate just create a function that passes the page+1*500 to the qInitialDataFetch like

 

app.createCube({
     qDimensions : qDimensions,
     qMeasures : qMeasures,
     qInitialDataFetch : [{
          qTop : (pageIndex)*500,
          qLeft : 0,
          qHeight : 500,
          qWidth : 20
     }]
}, function(reply) {


 

Or

 

model.getHyperCubeData('/qHyperCubeDef', [{qTop: (pageIndex)*500, qWidth: 20, qLeft: 0, qHeight: 500 }]).then(function(data) {


In our Qlik Demo Team we are trying to create mashups that are suitable for all devices. This is why we created another version of a Horizontal Bar Chart that we use almost exclusively. This has various options like setting the bar height, color, text color, text hover color etc. It can also change from regular Horizontal Bar Chart to Horizontal Stacked Bar Chart, Grouped Bar Chart or a Lollipop.

 

All of the UI/UX guidance is coming from my colleague Michael Anthony | Qlik

 

Installation

 

Settings

Dimension and Measures

  • Set 1 dimension for the Labels and
  • up to 5 Measures for Grouped, Stacked Bar or Lollipop

 

General Settings

  • Text Color
  • Font Size

 

Bar

  • Height
  • Comma separated colors for the stacked bar fill color
  • Fill color when you mouse over
  • Text Color for each bar
  • Text Color when you mouse over
  • Border Weight
  • Border Spacing
  • Enable Selections
  • Toggle between Stacked and Grouped Bar Chart

 

Tooltip

  • Enable Tooltip
  • Show Dimension in the Tooltip

 

X-Axis

  • Show X-Axis
  • Show Legend (check Stacked Bar image below)

 

Y-Axis

  • Show Y-Axis
  • Label Width (Usually 150px, even for the smallest device )
  • Number of visible characters, if you want to truncate your labels.

thumb.png

 

stackedBar.png

 

grouped.png

 

lollipop.png

 

Even though we still have a long way to go to make this perfect, features are always welcome!

 

YIANNI

 

Files

Qlik Branch

Since my last blog where I created a Google Annotation Chart (Google Annotation Chart - Qlik Sense Extension and Angular Directive), I thought it would be interesting to add more extensions based on Google's visualization library.

 

Here I created a simple gauge based on Google's Gauge found at Visualization: Gauge  |       Charts  |       Google Developers.

 

  • Download the zip file as found at the end of this blog,
  • unzip it in your extensions folder, C:\Users<user>\Documents\Qlik\Sense\Extensions\GoogleGaugeChart
  • Open your Helpdesk app and drag and drop the extension into the canvas
  • As for the first measure put
    Count( {$<Priority={'High'}, Status -={'Closed'} >} Distinct %CaseId )
    with a label "High Priority Cases"
  • For the second measure, put
    Count( {$<Status -={'Closed'} >} Distinct %CaseId )
  • with a label "Total Closed Cases"
  • Make selections and see the Gauge animate

preview.png

 

Coming up: Extension settings...

 

Branch: http://branch.qlik.com/#!/project/57b76c10b3122e2cd1e7305d

 

Yianni

Filter Blog

By date:
By tag: