Unlock a world of possibilities! Login now and discover the exclusive benefits awaiting you.
picasso.js is an awesome open source charting library from Qlik for building beautiful data visualizations quickly and easily. It’s super flexible, easy to use with hypercube data, renders in svg or canvas, and includes a lot of other great features already. But one thing it doesn’t have built in (yet) which I need when building visualizations is transitions so I developed a method for adding transitions to any picasso.js visualization (which is built into the upcoming new version of qdt-components). Let me take you through it.
Check out an example at https://webapps.qlik.com/picasso-transitions/index.html
Step 1: Create hypercube and chart
The first step is to create a hypercube, get the layout, and create a picasso.js chart.
/* Create a hypercube */
const object = await doc.createSessionObject({
qInfo: { qType: 'data' },
qHyperCubeDef: {
qDimensions: [{
qDef: { qFieldDefs: ['[Product Group Desc]'] },
qOtherTotalSpec: {
qOtherMode: "OTHER_COUNTED",
qOtherCounted: { qv: "10" },
qSuppressOther: true,
},
}],
qMeasures: [{
qDef: { qDef: 'Sum([Sales Amount])' },
}],
qInitialDataFetch: [{
qWidth: 2,
qHeight: 10,
}],
},
});
/* Get hypercube layout */
let layout = await object.getLayout();
/* Create chart */
const chart = picasso({
renderer: {
prio: ['canvas'],
},
}).chart({
element: document.querySelector('#chart'),
data: [
{
type: 'q',
key: 'qHyperCube',
data: layout.qHyperCube,
},
],
settings: {
scales: {
y: {
data: { field: 'qMeasureInfo/0' },
include: [0],
invert: true,
},
x: { data: { extract: { field: 'qDimensionInfo/0' } } },
},
components: [
{
type: 'axis',
dock: 'left',
scale: 'y',
},
{
type: 'axis',
dock: 'bottom',
scale: 'x',
},
{
type: 'box',
key: 'bars',
data: {
extract: {
field: 'qDimensionInfo/0',
props: {
start: 0,
end: { field: 'qMeasureInfo/0' },
},
},
},
settings: {
minor: { scale: 'y' },
major: { scale: 'x' },
box: {
fill: 'steelblue',
},
},
},
],
},
});
Step 2: Animate changes to layout
Now that there's a hypercube and a chart, the next step is to animate the chart when the hypercube changes. To do this, subscribe to changes in the hypercube, and in the callback get the new layout, setup a timer, and interpolate between the previous layout and the new layout and pass the tween hypercubes to the chart's update function. It looks like this.
object.on('changed', async () => { // subscribe to changes on the object
const nextLayout = await object.getLayout(); // get the next layout
const duration = 1500;
const ease = easeCubic; // easeCubic is d3-ease easeCubic function
const transitionTimer = timer((elapsed) => { // create a timer using d3-timer
// compute how far through the animation we are (0 to 1)
const t = Math.min(1, ease(elapsed / duration));
// calculate the tween layout at time t
const tweenLayout = interpolate(layout, nextLayout)(t); // interpolate function is from d3-interpolate
// update chart
chart.update({
data: [{
type: 'q',
key: 'qHyperCube',
data: tweenLayout.qHyperCube,
}],
});
// if this animation is over
if (t === 1) {
// stop this timer since we are done animating.
transitionTimer.stop();
layout = nextLayout;
}
});
});
Step 3: Animate size changes
Now the picasso.js chart will animate when the layout of the object changes, but it should also animate in response to CSS animations on it's parent container. A ResizeObserver can be used for that. ResizeObservers are relatively new, and should be polyfilled using the resize-observer-polyfill library. It's as simple as this.
const ro = new ResizeObserver(() => {
chart.update();
});
ro.observe(document.querySelector('#chart'));
Don't forget to check out the example at https://webapps.qlik.com/picasso-transitions/index.html. The code for this example is attached.
This is a rudimentary example of this approach, and does not handle things such as canceling transitions if another transition is started before the previous transition is finished. If you go through this example and want to check out my work to date on this, check out the QdtPicasso component on the working branch for the next version of qdt-components at https://github.com/qlik-demo-team/qdt-components/blob/3.0/src/components/QdtPicasso/QdtPicasso.jsx.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.