Funnel Chart

Funnel chart is a visualization that represents the progressive reduction of data as it passes through stages of a process. The shape of the chart is like a funnel, typically wider at the top and narrower at the bottom.

Data Charts support funnel type. To use the Funnel Chart, you can set the data chart type to GC.Spread.Sheets.DataCharts.DataChartType.funnel. There are two kinds of funnel charts. One kind of funnel chart uses category and value data binding, while another one uses detail and value data binding. For example, you can insert a funnel data chart and configure the data chart by method setChartConfig. Notes: before using the data chart, tables in data manager should be initialized.
window.onload = async () => { const { spread, designer } = createSpreadAndDesigner(); await initDataManager(spread); const sheet1 = spread.getSheet(0); sheet1.name('Funnel'); const dataChart1 = sheet1.dataCharts.add('chart11', 20, 20, 450, 300, GC.Spread.Sheets.DataCharts.DataChartType.funnel); dataChart1.setChartConfig({ tableName: 'Conversion', plots: [{ type: GC.Spread.Sheets.DataCharts.DataChartType.funnel, encodings: { values: [{ field: 'Count', aggregate: GC.Spread.Sheets.DataCharts.Aggregate.sum }], category: { field: 'Stage' }, color: { field: 'Stage' }, }, }], config: { header: { title: 'Funnel Chart', padding: { left: 16, right: 16, top: 5, bottom: 0, }, textStyle: { fontSize: 19, fontStyle: GC.Spread.Sheets.DataCharts.FontStyle.italic, alignment: GC.Spread.Sheets.DataCharts.HAlign.left, }, }, plotAreas: [{ legends: [{ type: GC.Spread.Sheets.DataCharts.LegendType.color, textStyle: { color: 'rgba(51,51,51,1)', fontFamily: 'Calibri', fontSize: 12, }, }], }], }, }); const dataChart2 = sheet1.dataCharts.add('chart12', 490, 20, 450, 300, GC.Spread.Sheets.DataCharts.DataChartType.funnel); dataChart2.setChartConfig({ tableName: 'Conversion', plots: [{ type: GC.Spread.Sheets.DataCharts.DataChartType.funnel, encodings: { values: [{ field: 'Count', aggregate: GC.Spread.Sheets.DataCharts.Aggregate.sum }], category: { field: 'Stage' }, color: { field: 'Stage' }, }, config: { funnel: { orientation: GC.Spread.Sheets.DataCharts.Orientation.horizontal, }, }, }], config: { header: { title: 'Horizontal Funnel Chart', padding: { left: 16, right: 16, top: 5, bottom: 0, }, textStyle: { fontSize: 19, fontStyle: GC.Spread.Sheets.DataCharts.FontStyle.italic, alignment: GC.Spread.Sheets.DataCharts.HAlign.left, }, }, plotAreas: [{ legends: [{ type: GC.Spread.Sheets.DataCharts.LegendType.color, textStyle: { color: 'rgba(51,51,51,1)', fontFamily: 'Calibri', fontSize: 12, }, }], }], }, }); const dataChart3 = sheet1.dataCharts.add('chart13', 20, 340, 450, 300, GC.Spread.Sheets.DataCharts.DataChartType.funnel); dataChart3.setChartConfig({ tableName: 'Conversion', plots: [{ type: GC.Spread.Sheets.DataCharts.DataChartType.funnel, encodings: { values: [{ field: 'Count', aggregate: GC.Spread.Sheets.DataCharts.Aggregate.sum }], category: { field: 'Stage' }, color: { field: 'Stage' }, }, config: { funnel: { funnelType: GC.Spread.Sheets.DataCharts.FunnelType.bar, }, }, }], config: { header: { title: 'Bar Funnel Chart', padding: { left: 16, right: 16, top: 5, bottom: 0, }, textStyle: { fontSize: 19, fontStyle: GC.Spread.Sheets.DataCharts.FontStyle.italic, alignment: GC.Spread.Sheets.DataCharts.HAlign.left, }, }, plotAreas: [{ legends: [{ type: GC.Spread.Sheets.DataCharts.LegendType.color, textStyle: { color: 'rgba(51,51,51,1)', fontFamily: 'Calibri', fontSize: 12, }, }], }], }, }); const dataChart4 = sheet1.dataCharts.add('chart14', 490, 340, 450, 300, GC.Spread.Sheets.DataCharts.DataChartType.funnel); dataChart4.setChartConfig({ tableName: 'Conversion', plots: [{ type: GC.Spread.Sheets.DataCharts.DataChartType.funnel, encodings: { values: [{ field: 'Count', aggregate: GC.Spread.Sheets.DataCharts.Aggregate.sum }], category: { field: 'Stage' }, color: { field: 'Stage' }, }, config: { funnel: { funnelType: GC.Spread.Sheets.DataCharts.FunnelType.pyramid, }, }, }], config: { header: { title: 'Pyramid Funnel Chart', padding: { left: 16, right: 16, top: 5, bottom: 0, }, textStyle: { fontSize: 19, fontStyle: GC.Spread.Sheets.DataCharts.FontStyle.italic, alignment: GC.Spread.Sheets.DataCharts.HAlign.left, }, }, plotAreas: [{ legends: [{ type: GC.Spread.Sheets.DataCharts.LegendType.color, textStyle: { color: 'rgba(51,51,51,1)', fontFamily: 'Calibri', fontSize: 12, }, }], }], }, }); const legendSheet = new GC.Spread.Sheets.Worksheet('Legend MaxSize'); spread.addSheet(spread.getSheetCount(), legendSheet); const legendCases = [ { key: 'maxWidth', value: 0.3, title: 'Funnel Chart(Legend MaxWidth 30%)' }, { key: 'maxWidth', value: 0.1, title: 'Funnel Chart(Legend MaxWidth 10%)' }, { key: 'maxHeight', value: 0.3, title: 'Funnel Chart(Legend MaxHeight 30%)' }, { key: 'maxHeight', value: 0.1, title: 'Funnel Chart(Legend MaxHeight 10%)' }, ]; legendCases.forEach((item, index) => { const col = index % 2; const row = Math.floor(index / 2); const chart = legendSheet.dataCharts.add( `legendChart${index + 1}`, 20 + col * 470, 20 + row * 320, 450, 300, GC.Spread.Sheets.DataCharts.DataChartType.funnel ); const legend = { type: GC.Spread.Sheets.DataCharts.LegendType.color, textStyle: { color: 'rgba(51,51,51,1)', fontFamily: 'Calibri', fontSize: 12, }, [item.key]: item.value, }; if (item.key === 'maxHeight') { legend.position = GC.Spread.Sheets.DataCharts.LegendPosition.top; } chart.setChartConfig({ tableName: 'Conversion', plots: [{ type: GC.Spread.Sheets.DataCharts.DataChartType.funnel, encodings: { values: [{ field: 'Count', aggregate: GC.Spread.Sheets.DataCharts.Aggregate.sum }], category: { field: 'Stage' }, color: { field: 'Stage' }, }, }], config: { header: { title: item.title, padding: { left: 16, right: 16, top: 5, bottom: 0, }, textStyle: { fontSize: 19, fontStyle: GC.Spread.Sheets.DataCharts.FontStyle.italic, alignment: GC.Spread.Sheets.DataCharts.HAlign.left, }, }, plotAreas: [{ legends: [legend], }], }, }); }); spread.getActiveSheet().dataCharts.all()[0].isSelected(true); if (designer) { designer.refresh(); } } function createSpreadAndDesigner() { const demoHost = document.getElementById('demo-host'); if (window !== top) { const spread = new GC.Spread.Sheets.Workbook('spread-host', { sheetCount: 1 }); new GC.Spread.Sheets.DataCharts.DataChartConfigPanel('panel-host', spread); return { spread } } else { const designer = new GC.Spread.Sheets.Designer.Designer(demoHost, undefined, undefined, { sheetCount: 1 }); return { designer, spread: designer.getWorkbook(), } } } async function initDataManager(spread) { const records = [ ['Website Visits', 10000], ['User Registration', 6900], ['Activation', 5000], ['First Purchase', 2200], ['Month 2 Retention', 1000], ]; const columns = ['Stage', 'Count']; await spread.dataManager().addTable('Conversion', { data: records.map(record => { const item = {}; columns.forEach((column, index) => { item[column] = record[index]; }); return item; }), }).fetch(); }
<!doctype html> <html style="height:100%;font-size:14px;"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-designer/styles/gc.spread.sheets.designer.light.min.css"> <link rel="stylesheet" type="text/css" href="styles.css"> <script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets/dist/gc.spread.sheets.all.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-print/dist/gc.spread.sheets.print.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-shapes/dist/gc.spread.sheets.shapes.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-datacharts-addon/dist/gc.spread.sheets.datacharts.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-tablesheet/dist/gc.spread.sheets.tablesheet.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/spread/source/js/license.js" type="text/javascript"></script> <script> const designerDependencyScripts = [ '$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-charts/dist/gc.spread.sheets.charts.min.js', '$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-barcode/dist/gc.spread.sheets.barcode.min.js', '$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-pdf/dist/gc.spread.sheets.pdf.min.js', '$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-pivot-addon/dist/gc.spread.pivot.pivottables.min.js', '$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-slicers/dist/gc.spread.sheets.slicers.min.js', '$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-reportsheet-addon/dist/gc.spread.report.reportsheet.min.js', '$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-ganttsheet/dist/gc.spread.sheets.ganttsheet.min.js', '$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-formula-panel/dist/gc.spread.sheets.formulapanel.min.js', '$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-io/dist/gc.spread.sheets.io.min.js', '$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-designer-resources-en/dist/gc.spread.sheets.designer.resource.en.min.js', '$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-designer/dist/gc.spread.sheets.designer.all.min.js', '$DEMOROOT$/spread/source/js/designer/license.js', ] function appendScriptNode (src) { const script = document.createElement('script'); script.src = src; script.async = false; script.type = 'text/javascript'; document.head.appendChild(script); } if (top === window) { // not in iframe designerDependencyScripts.forEach(appendScriptNode); } </script> <script src="app.js" type="text/javascript"></script> </head> <body> <div class="sample-tutorial"> <div id="demo-host"> <div id="spread-host"></div> <div id="panel-host"></div> </div> </div> </body> </html>
body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; } .sample-tutorial { position: relative; height: 100%; overflow: hidden; } #demo-host { width: 100%; height: 100%; overflow: hidden; float: left; } #spread-host { position: absolute; top: 0; left: 0; width: calc(100% - 380px); height: 100%; } #panel-host { position: absolute; top: 0; right: 0; width: 380px; height: 100%; }