Who am I? Kevin McGovern

Kevin McGovern

  • Data Visualization Consultant at Slalom
  • Qlik Branch Contributor
  • Builds things with D3

Questions we will cover

  • What is D3?
  • How is D3 used?
  • Where would you use D3 in Qlik Sense Mashups?
  • What do you need to do differently for Extensions?

What is D3?

What D3 isn't

  • Not a charting library
  • Not a drawing library
  • Not optimized for canvas and WebGL
  • Not a framework

What D3 is

D3.js is a JavaScript library for manipulating documents based on data. D3 helps you bring data to life using HTML, SVG, and CSS. D3’s emphasis on web standards gives you the full capabilities of modern browsers without tying yourself to a proprietary framework, combining powerful visualization components and a data-driven approach to DOM manipulation.
Backing Up

"A JavaScript Library"

What is JavaScript?

D3: "A JavaScript Library"

What is JavaScript?
  • HTML sets document structure
  • CSS sets styling
  • JS informs your browser how to display content dynamically

D3: "A JavaScript Library"

What is a js library?
Extending what native js can do, makes developers lives easier
  • jQuery
  • Angular
  • React
  • Ember
  • Three.js
  • Node.js
  • D3.js

D3: "manipulating documents based on data"

Browser renders HTML, CSS, JS to create Document Object Model
...or DOM

The DOM

More than just a fast and furious character
API that lets you interact with rendered web pages

Where does D3 come in?

  • Bind data to elements in the DOM
  • Change existing elements based on bound data
  • Add new elements when more data added
  • Remove elements when data changes
  • Basically...

HTML Magic

D3 in Action

Finding elements, binding data, creating new elements
Using Scott Murray's Awesome Tutorial

An Example


							var dataset = [ 5, 10, 15, 20, 25 ];

							d3.select("body")
								.selectAll("p")
								.data(dataset)
								.enter()
								.append("p")
								.text("New paragraph!");
						

An Example


							var dataset = [ 5, 10, 15, 20, 25 ];

							d3.select("body")
								.selectAll("p")
								.data(dataset)
								.enter()
								.append("p")
								.text("New paragraph!");
						

An Example


							var dataset = [ 5, 10, 15, 20, 25 ];

							d3.select("body")
								.selectAll("p")
								.data(dataset)
								.enter()
								.append("p")
								.text("New paragraph!");
						

An Example


							var dataset = [ 5, 10, 15, 20, 25 ];

							d3.select("body")
								.selectAll("p")
								.data(dataset)
								.enter()
								.append("p")
								.text("New paragraph!");
						

An Example


							var dataset = [ 5, 10, 15, 20, 25 ];

							d3.select("body")
								.selectAll("p")
								.data(dataset)
								.enter()
								.append("p")
								.text("New paragraph!");
						

An Example


							var dataset = [ 5, 10, 15, 20, 25 ];

							d3.select("body")
								.selectAll("p")
								.data(dataset)
								.enter()
								.append("p")
								.text("New paragraph!");
						

An Example


							var dataset = [ 5, 10, 15, 20, 25 ];

							d3.select("body")
								.selectAll("p")
								.data(dataset)
								.enter()
								.append("p")
								.text("New paragraph!");
						

An Example - Results

console.log(d3.selectAll("p"))

An Example - Exploring the Elements

Modified Example - Using Data to Add to Elements


							var dataset = [ 5, 10, 15, 20, 25 ];

							d3.select("body")
								.selectAll("p")
								.data(dataset)
								.enter()
								.append("p")
								.text(function(d) { return d; });
						

Modified Example - Results

Modified Example - Changing the Data


							var dataset = [ 5, 200, 15, 20, 25, 50 ];

							d3.select("body")
								.selectAll("p")
								.data(dataset)
								.enter()
								.append("p")
								.text(function(d) { return d; });
						

Modified Example - Results

Cool chart but why do I care?

Dynamic data manipulation is really useful for data visualization

  • Data changes over time
  • User interactions
    • Clicks
    • Hover
    • Time-based delays

D3 looks hard, what about charting libraries?

  • Few chart options
  • Customization is difficult
  • Limited page interaction

D3 is more than a way to just change data on the page dynamically

  • Create interactive charts
  • Visualize hierarchical data
  • Leverage open source geo libraries
  • Make super slick transitions
  • Visualize relationship-base data
  • Integrate with the newest JS standards and libraries

D3 in the wild

The most basic (source)

Maps (source)

Chords (source)

Bubble (source)

Stream (source)

Network (source)

Why are we talking about this at Qonnections?

Other than to show off appropriate gif/memes

Benefits of Using D3 with Qlik Sense

Specifically how does D3 integrate with Qlik Sense

A couple different reasons

Mashups
  • Blend styles with the rest of your page
  • Stand on the shoulders of other developers
Extensions
  • Extend the capabilities of Qlik Sense
  • Get an appreciation for bar charts

Ok Qlik Sense needs D3 but why does D3 benefit from Qlik Sense?

  • Meta data
    • Min and Max
    • Glyph counts
    • Aggregations in D3 are a pain
    • Limits and methods on number of rows
    • Sorting and formatting
Branch blog post

Alright, let's integrate in Qlik Sense

Using D3 in Mashups

or how to use the capabilities APIs with D3.js

What are we building?

Create a new mashup

Create a new mashup

Connect to a Qlik Sense app

Add a hypercube

What in tarnation is a hypercube

  • Define dimensions and measures
  • Tell Qlik the max number of rows expected
  • Create a callback function to handle the data returned
  • User selects data, callback function is called again

So about that hypercube....

Configuring the hypercube

What did you do!?!

What did all that do?

Let's see the return values

The developer panel

Go grab an example (source)

Get HTML/CSS/JS from example

Alter HTML

Insert css into script

Load D3 library in

Get D3 from example

Copy D3 code into script

Before we connect to hypercube...

let's get the sample data

Drop the data file in the directory

Load an instance of require.js

Reference the tsv file in js

Eureka!

Link to source so far

Get data from your hypercube

But first prep data (source)

Minor edits

  • Put the D3 code inside the callback function
  • Clear the SVG before writing to it
  • Comment out the call to the tsv
  • Point the chart data to the hypercube variable
Source with these changes

Modified Example - Changing the Data


							function getStateData(reply, app){
							  //remove all d3 elements from svg
							  $('#QV01 svg').empty();
							  //store cleansed data
							  var data = senseD3.createJSONObj(reply);
							...
							  g.selectAll(".bar")
							  .data(data)
							  .enter().append("rect")
							    .attr("class", "bar")
							    .attr("x", function(d) { return x(d.dim_0); })
							    .attr("y", function(d) { return y(d.meas_0); })
							    .attr("width", x.bandwidth())
							    .attr("height", function(d) { return height - y(d.meas_0); });
							 
							}
						

Refresh and....

We're done right? Right!?

Link to source

Well kinda

Some other things we would want to handle
  • Window size changes
  • Smoothing data changes
  • Fix hard coded D3 selections
  • Add selection listeners to the chart
  • Leverage hypercube data

Selections (using the capability apis)


							.on("click", function(d) {
								app.field('addr_state').select([d.dim_0_id], true, true);
							});
						
Documentation

Capabilities API

What else can we do?
  • Make/clear selections
  • Forward/Backward through Selections
  • Navigate to an app page
  • Alternative States
Much More

Mashup source code

source

Using D3 in Extensions

Mostly the same as mashups, a few differences
  • No hypercube creation, controlled by properties
  • More error handling and data validation
  • Handle data changes in a different way

What's different?

How does our data look different

  • 'Element' is roughly equal to 'App' from Mashup (different contexts)
  • 'Layout' is roughly equal to 'Reply' from HC
  • Different data types could come in
  • Varying numbers of dimensions and measures
  • What happens when our data changes in an extension?

    • Redraw the full chart (cop out)
    • Use Angular to detect data changes (difficult to pull off)
      • Too heavy for this but...source

    What about using APIs with D3 extensions?

    • Extension APIs used to set extension properties
      • Color picker
      • SelectValues
    • Capability APIs from earlier still available

    So what's possible?

    An example!

    Where can we go from here?

    Where can we go from here?

    These slides at: https://mcgovey.github.io/qonnections-2017-d3

    Supporting repo: https://github.com/mcgovey/qonnections-2017-d3