A brief tutorial introducing Qdt-Components 3.0.
Introduction
Qdt-Components has grown over time to include more charts, better Picasso integration, and better documentation. As the project has progressed, we've received some great feedback from the developer community for our 3.0 update. Although not officially launched yet, Qdt-Components 3.0 will give developers more freedom and is more modularized, allowing developers to use only what they want. This mini-tutorial will show off a few of the simple changes and show developers how to get up and running fast.
Setting Up the Repo
Clone this repo (https://github.com/qlik-demo-team/qdt-components-tutorial-001) to get started.
git clone https://github.com/qlik-demo-team/qdt-components-tutorial-001cd qdt-components-tutorial-001npm igit checkout startnpm run dev
Configure the App
One of the benefits of Qdt-components 3.0 is that developers can connect to Qlik Sense however they want. For the developers on the Qlik Demo Team, we frequently use Enigma.js so the configuration below will not be foreign to readers of this blog. What is new is the line import { qdtEnigma} from 'qdt-components'. Qdt-components now includes QdtEnigma which allows you to use Enigma without installing it yourself as a separate dependency. If you want to connect to Qlik Sense another way, you can use whatever library or methods you want. In the config folder, update the app.js file like this:
import { qdtEnigma } from 'qdt-components';const config = { host: 'sense-demo.qlik.com', secure: true, port: 443, prefix: '', appId: '372cbc85-f7fb-4db6-a620-9a5367845dce', // Consumer Sales};const appPromise = qdtEnigma(config);appPromise.then((app) => { app.clearAll(); });export default appPromise;
Notice how the configuration isn't much different than using Enigma. Besides abstracting a few lines of code, the setup is largely pretty similar to previous mashups we've created on this blog.
MyChart Component
Now that the configuration is complete, let's create the chart. Notice that we've already setup the MyChart component. It is a pretty bare-bones, React component with the hypercube that we'll be using for this tutorial. In this section, we're going to go through the basic steps to rendering a Picasso Barchart. We'll show the completed code and then walk through it.
// MyChart.jsimport { qdtCompose, QdtPicasso, useBarChartSettings } from 'qdt-components';import appPromise from './config/app';// hypercube defintionconst MyChart = () => { const barChart = useRef(null); useEffect(() => { (async () => { const settings = useBarChartSettings(); const app = await appPromise; qdtCompose({ app, element: barChart.current, component: QdtPicasso, options: { settings, }, properties: hypercube, loading: () => null, }) })() }, []) return ( <div> <h2>My Charts</h2> <div ref={barChart} style={{ height: 400, paddingTop: 50 }} /> </div> )}export default MyChart;
At the top of page, notice the import statements. We are importing three functions from qdt-components: qdtCompose, QdtPicasso, and useBarChartSettings. qdtCompose is a new function we've created to render the element. This function is more flexible and allows developers the option to provide the Qlik app promise however they want (again, in this tutorial, we are using Enigma.js as seen from the last section). QdtPicasso is exactly the same as before but instead of <QdtPicasso />, the developer can just pass QdtPicasso in. Lastly, we are using a function called useBarChartSettings. This function was created to allow developers to add custom Picasso settings. In Qdt-Components version 2.X, it was too onerous to add custom settings. Now, any developer can use the default settings for the typical bar chart and then add whatever custom settings they want.
In the useEffect function, there are three general steps: 1) get the settings for your barchart (useBarChartSettings); 2) get the Qlik app object (appPromise); 3) use QdtCompose to render the element. For Step #1, getting the settings is just a matter of calling the useBarChartSettings function. Unless a setting object is passed into the function, it simply returns the default settings for a bar chart (try logging the settings object to see the different chart components that make up a bar chart). For Step #2, we simply use async-await to get the app object we setup in the Config section. For Step #3, we'll use QdtCompose to render the chart. In this example, QdtCompose takes a number of props like the Qlik app, the reference to the DOM where you are placing the chart, the component you want to show (QdtPicasso), settings relevant for that particular component, and the hypercube.
Take a look at the chart. This is what you should have:
A Pie Chart
Now that we have a working chart, we wanted to show how easily we could add another chart. To keep things super simple, we'll use the same hypercube but this chart will be a pie chart. We'll show the code and then walk through it:
import { qdtCompose, QdtPicasso, useBarChartSettings, usePieChartSettings } from 'qdt-components'; import appPromise from './config/app'; // hypercube const MyChart = () => { const barChart = useRef(null); const pieChart = useRef(null); // NEW: pie chart ref object useEffect(() => { (async () => { // old code const pieSettings = usePieChartSettings(); qdtCompose({ app, element: pieChart.current, component: QdtPicasso, options: { settings: pieSettings, }, properties: hypercube, loading: () => null, }) })() }, []) return ( <div> <h2>My Charts</h2> <div ref={barChart} style={{ height: 400, paddingTop: 50 }} /> <div ref={pieChart} style={{ height: 400, paddingTop: 50 }} /> </div> ) }
Notice how we simply need to import the usePieChartSettings function, create a DOM ref, and then use QdtCompose again to render the pie chart. Same data, yes, but super simple and very easy to replicate. Let's add one more component: a clear selections button.
import { qdtCompose, QdtPicasso, useBarChartSettings, usePieChartSettings, QdtButton } from 'qdt-components'; // OLD CODE const MyChart = () => { const barChart = useRef(null); const pieChart = useRef(null); const clearButton = useRef(null); useEffect(() => { (async () => { // OLD CODE qdtCompose({ app, element: clearButton.current, component: QdtButton, options: { type: 'clearSelections', label: 'Clear Selections' } }) })() }, []) return ( <div> <h2>My Charts</h2> <div ref={clearButton} style={{ margin: '10px auto', width: 250 }} /> <div ref={barChart} style={{ height: 400, paddingTop: 50 }} /> <div ref={pieChart} style={{ height: 400, paddingTop: 50 }} /> </div> ) }
And just like that, we have two charts and clear selections button. Following the same process, we import the component we want (QdtButton), create a ref object on the DOM, and then use QdtCompose to render it. All component-specific options go into the "options" property in the QdtCompose object. For QdtButton, instead of a "settings" object, we just needed to pass in its type and the label.
Conclusion
And there we have it - a very basic mashup with two charts and a clear button. This was a short introduction to version 3.0 of Qdt-Components but a good example of the new functionality: modularity. Many of the components and most useful functions can be destructured right from your import statement, allowing you to use the parts of library in a more precise and deliberate manner. We'll be posting again for our launch with updated documentation and templates so stay tuned. To see working versions of all of our 3.0 components, see https://observablehq.com/collection/@yianni-ververis/qdt-components.