UNPKG

@nebula.js/sn-funnel-chart

Version:

A sequential chart visualizing a linear process with connected stages, for example a sales process with potential revenue at each stage.

303 lines (251 loc) 7.77 kB
# @nebula.js/sn-funnel-chart The funnel chart lets you add a sequential chart showing the connected stages of a process. Each stage decreases and should contain a subset of the previous stage. The decrease is gradual, giving the chart an ever narrower funnel. ## Requirements Requires `@nebula.js/stardust` version `1.2.0` or later. ## Installing If you use npm: `npm install @nebula.js/sn-funnel-chart`. You can also load through the script tag directly from [https://unpkg.com](https://unpkg.com/@nebula.js/sn-funnel-chart). ## Usage The example below shows the number of candidates during sequential stages of a recruitment process. The chart is plotted in `width` mode, where the quantity at each stage is proportional to the upper edge of the segment. ```js import { embed } from '@nebula.js/stardust'; import funnel from '@nebula.js/sn-funnel-chart'; // 'app' is an enigma app model const nuked = embed(app, { types: [{ // register funnel chart name: 'funnel-chart', load: () => Promise.resolve(funnel); }] }); // Rendering a simple funnel chart nuked.render({ element: document.querySelector('.funnel'), type: 'funnel-chart', fields: ['Hiring Stage', '=Sum(NumberOfCandidates)'], properties: { title: 'Recruitment Process', }, }); ``` Funnel chart can represent anything that is decreasing in size, showing a process that starts at 100% and ends with a lower percentage. The funnel chart is the opposite to a pyramid graph, which has increasing stages instead of decreasing stages. The chart requires one dimension and one measure. Unlike bar charts, funnel chart segments are centered to create a funnel shape. ## More examples ### Area mode You can configure the funnel chart so that the area of each item is proportional to the measure. ```js // Rendering a funnel chart in area mode nuked.render({ element: document.querySelector('.funnel'), type: 'funnel-chart', fields: ['Hiring Stage', '=Sum(NumberOfCandidates)'], properties: { title: 'Recruitment Process', funnel: { mode: 'AREA', }, }, }); ``` ### Height mode The height of each item is proportional to the measure. ```js // Rendering a funnel chart in height mode nuked.render({ element: document.querySelector('.funnel'), type: 'funnel-chart', fields: ['Hiring Stage', '=Sum(NumberOfCandidates)'], properties: { title: 'Recruitment Process', funnel: { mode: 'HEIGHT', }, }, }); ``` ### Ordering mode Only order matters, the items have the same height, ordered from top to bottom. ```js // Rendering a funnel chart in order mode nuked.render({ element: document.querySelector('.funnel'), type: 'funnel-chart', fields: ['Hiring Stage', '=Sum(NumberOfCandidates)'], properties: { title: 'Recruitment Process', funnel: { mode: 'ORDER', }, }, }); ``` ### More configurations You can also remove the dimension title, show the actual number of candidates instead of the percentage, or color the stages by measure. ```js // Rendering a funnel chart with customized look nuked.render({ element: document.querySelector('.funnel'), type: 'funnel-chart', // Defines the fields in `properties` properties: { title: 'Recruitment Process', // Hide dimension title showDimensionTitle: false, qHyperCubeDef: { qDimensions: [ { qDef: { qFieldDefs: ['Hiring Stage'] }, // Color the dimension by `MedianRequestedSalary` qAttributeExpressions: [ { qExpression: 'Avg(MedianRequestedSalary)', id: 'colorByAlternative', }, ], }, ], qMeasures: [ { qDef: { qDef: 'Sum(NumberOfCandidates)' }, }, ], qInterColumnSortOrder: [1, 0], qInitialDataFetch: [ { qLeft: 0, qTop: 0, qWidth: 2, qHeight: 5000, }, ], }, // Show actual number of candidates instead of percentage dataPoint: { auto: false, labelMode: 'value', }, // Configure color color: { auto: false, byMeasureDef: { key: 'Avg(MedianRequestedSalary)', type: 'expression', }, measureScheme: 'dg', mode: 'byMeasure', reverseScheme: true, }, }, }); ``` ## Funnel chart plugins A plugin can be passed into a funnel chart to add or modify its capability or visual appearance. A plugin needs to be defined before it can be rendered together with the chart. ```js // Step 1: define the plugin // Modifying the look of the dimension title const dimensionTitlePlugin = { info: { name: 'dimension-title-plugin', type: 'component-definition', }, fn: ({ keys, layout }) => { const componentDefinition = { type: 'text', // Provide the same name as the exisiting component to override it key: keys.COMPONENT.DIMENSION_TITLE, text: 'The percentage of candidates remain after each hiring stage', layout: { dock: 'bottom', }, }; return componentDefinition; }, }; // Step 2: passing the plugin definition into the render function // Render a funnel chart with plugins nuked.render({ element: document.querySelector('#object'), type: 'sn-funnel-chart', plugins: [dimensionTitlePlugin], fields: ['Hiring Stage', '=Sum(NumberOfCandidates)'], properties: { title: 'Recruitment Process', }, }); ``` The plugin definition is an object, with two properties `info` and `fn`. The `fn` returns a `picasso.js` component. To build this component, some important chart internals are passed into the argument object of `fn`. ```js // Structure of the argument object of fn const pluginArgs = { layout, keys: { SCALE: { FILL }, COMPONENT: { FUNNEL, FUNNEL_LABELS, DIMENSION_TITLE }, }, }; ``` With plugins, you can either add new components or modify existing components of the funnel chart. ### Modify existing components As an example, the positions and the appearance of the funnel labels can be modified by plugins. To overide an existing component, `fn` should returns a `picasso.js` component that has the same `key` as the existing component (`keys.COMPONENT.FUNNEL_LABELS` in this example) ```js // Modifying the look of the funnel labels const funnelLabelsPlugin = { info: { name: 'funnel-labels-plugin', type: 'component-definition', }, fn: ({ keys, layout }) => { const componentDefinition = { type: 'labels', // Provide the same name as the exisiting component to override it key: keys.COMPONENT.FUNNEL_LABELS, layout: { displayOrder: 2 }, settings: { sources: [ { component: keys.COMPONENT.FUNNEL, selector: '.labelLeft', strategy: { type: 'rows', settings: { align: 0, fill: 'gray', fontSize: '15px' }, }, }, { component: keys.COMPONENT.FUNNEL, selector: '.labelCenter', strategy: { type: 'rows', settings: { align: 0.5, fill: 'darkred', fontSize: '15px' }, }, }, ], }, }; return componentDefinition; }, }; ``` ### Add new components The new component can be a standard Picasso component or a custom Picasso component. The code for adding a new component is similar to that for modifying an existing component, the only difference is that the `key` should be different from that of any of the existing components. ### Plugins disclaimer - The plugins API is still experimental. - We can not guarantee our charts to be compatible with all different settings, especially when modifying existing components.