Funnel Chart

The funnel chart takes its name from its shape, which starts from a broad head and ends in a narrow neck. You could use a funnel chart to show the number of sales prospects at each stage in a sales pipeline or sales from a product email campaign.

Description
app.component.ts
index.html
app.component.html
styles.css
Copy to CodeMine

SpreadJS supports funnel charts. Use the GC.Spread.Sheets.Charts.ChartType.funnel property to get the chart type. Funnel chart show values across multiple stages in a process.

You can add a funnel chart to Spread and change its style using the chart API.

     var chart = sheet.charts.add('funnel', GC.Spread.Sheets.Charts.ChartType.funnel, 0, 100, 400, 300, 'A1:D4');
     var legend = chart.legend();
     legend.visible = true;
     chart.legend(legend);
     var series = chart.series().get(index);
     series.backColor = 'red';
     series.gapWidth = 2;
     chart.series().set(index, series);
SpreadJS supports funnel charts. Use the GC.Spread.Sheets.Charts.ChartType.funnel property to get the chart type. Funnel chart show values across multiple stages in a process. You can add a funnel chart to Spread and change its style using the chart API.
import { Component, NgModule, enableProdMode } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { SpreadSheetsModule } from '@mescius/spread-sheets-angular'; import GC from '@mescius/spread-sheets'; import "@mescius/spread-sheets-shapes"; import '@mescius/spread-sheets-charts'; import './styles.css'; @Component({ selector: 'app-component', templateUrl: 'src/app.component.html' }) export class AppComponent { spread: GC.Spread.Sheets.Workbook; hostStyle = { width: '100%', height: '100%', overflow: 'hidden', float: 'left' }; initSpread($event: any) { this.spread = $event.spread; let spread = this.spread; let sheets = spread.sheets; spread.suspendPaint(); // custom sheet style this.setSheet(sheets); this.setData(sheets[0], 'funnelChart'); this.initFunnel(sheets[0], GC.Spread.Sheets.Charts.ChartType.funnel); this.setData(sheets[1], 'customStyle'); let customFunnelChart = this.initFunnel(sheets[1], GC.Spread.Sheets.Charts.ChartType.funnel); this.setCustomStyle(customFunnelChart); spread.resumePaint(); } setSheet(sheets: GC.Spread.Sheets) { let columnWidths = [20, 100, 100]; for (let i = 0; i < sheets.length; i++) { sheets[i].options.gridline.showHorizontalGridline = false; sheets[i].options.gridline.showVerticalGridline = false; sheets[i].getRange(1, 1, 6, 2) .hAlign(GC.Spread.Sheets.HorizontalAlign.center) .setBorder(new GC.Spread.Sheets.LineBorder('black', GC.Spread.Sheets.LineStyle.thin), { all: true }); sheets[i].getRange(1, 1, 1, 2).font('bold normal 10pt Arial'); for (let j = 0; j < columnWidths.length; j++) { sheets[i].setColumnWidth(j, columnWidths[j]); } } } initFunnel(sheet: GC.Spread.Sheets.Worksheet, chartType: GC.Spread.Sheets.Charts.ChartType) { sheet.resumePaint(); return sheet.charts.add((sheet.name() + chartType), chartType, 400, 0, 500, 400, "B2:C7"); } setCustomStyle(chart: GC.Spread.Sheets.Charts.Chart) { let chartArea = chart.chartArea(); chartArea.backColor = { type: GC.Spread.Sheets.Charts.PatternType.dottedPercent20, foregroundColor: "rgb(0,176,80)", backgroundColor: "background 1 0", }; chart.chartArea(chartArea); let dataLabels = chart.dataLabels(); dataLabels.showValue = true; dataLabels.color = 'white'; chart.dataLabels(dataLabels); let seriesCollection = chart.series(); let series1 = seriesCollection.get(0); series1.backColor = "green" seriesCollection.set(0, series1); let title = chart.title(); title.text = "Product Email Campaign"; title.fontSize = 16; chart.title(title); } setData(sheet: GC.Spread.Sheets.Worksheet, sheetName: string) { sheet.name(sheetName); sheet.suspendPaint(); let dataArray = [ ['Stage', 'Users'], ['Sent', 5676], ['Viewed', 3872], ['Clicked', 1668], ['Add to Cart', 640], ['Purchased', 565], ]; sheet.setArray(1, 1, dataArray); } } @NgModule({ imports: [BrowserModule, SpreadSheetsModule], declarations: [AppComponent], exports: [AppComponent], bootstrap: [AppComponent] }) export class AppModule { } enableProdMode(); // Bootstrap application with hash style navigation and global services. platformBrowserDynamic().bootstrapModule(AppModule);
<!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/angular/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <!-- Polyfills --> <script src="$DEMOROOT$/en/angular/node_modules/core-js/client/shim.min.js"></script> <script src="$DEMOROOT$/en/angular/node_modules/zone.js/fesm2015/zone.min.js"></script> <!-- SystemJS --> <script src="$DEMOROOT$/en/angular/node_modules/systemjs/dist/system.js"></script> <script src="systemjs.config.js"></script> <script> // workaround to load 'rxjs/operators' from the rxjs bundle System.import('rxjs').then(function (m) { System.import('@angular/compiler'); System.set(SystemJS.resolveSync('rxjs/operators'), System.newModule(m.operators)); System.import('$DEMOROOT$/en/lib/angular/license.ts'); System.import('./src/app.component'); }); </script> </head> <body> <app-component></app-component> </body> </html>
<div class="sample-tutorial"> <gc-spread-sheets [hostStyle]="hostStyle" (workbookInitialized)="initSpread($event)"> <gc-worksheet></gc-worksheet> <gc-worksheet></gc-worksheet> </gc-spread-sheets> </div>
.sample-tutorial { position: relative; height: 100%; overflow: hidden; } body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; }
(function (global) { System.config({ transpiler: 'ts', typescriptOptions: { tsconfig: true }, meta: { 'typescript': { "exports": "ts" }, '*.css': { loader: 'css' } }, paths: { // paths serve as alias 'npm:': 'node_modules/' }, // map tells the System loader where to look for things map: { 'core-js': 'npm:core-js/client/shim.min.js', 'zone': 'npm:zone.js/fesm2015/zone.min.js', 'rxjs': 'npm:rxjs/dist/bundles/rxjs.umd.min.js', '@angular/core': 'npm:@angular/core/fesm2022', '@angular/common': 'npm:@angular/common/fesm2022/common.mjs', '@angular/compiler': 'npm:@angular/compiler/fesm2022/compiler.mjs', '@angular/platform-browser': 'npm:@angular/platform-browser/fesm2022/platform-browser.mjs', '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/fesm2022/platform-browser-dynamic.mjs', '@angular/common/http': 'npm:@angular/common/fesm2022/http.mjs', '@angular/router': 'npm:@angular/router/fesm2022/router.mjs', '@angular/forms': 'npm:@angular/forms/fesm2022/forms.mjs', 'jszip': 'npm:jszip/dist/jszip.min.js', 'typescript': 'npm:typescript/lib/typescript.js', 'ts': './plugin.js', 'tslib':'npm:tslib/tslib.js', 'css': 'npm:systemjs-plugin-css/css.js', 'plugin-babel': 'npm:systemjs-plugin-babel/plugin-babel.js', 'systemjs-babel-build':'npm:systemjs-plugin-babel/systemjs-babel-browser.js', '@mescius/spread-sheets-shapes': 'npm:@mescius/spread-sheets-shapes/index.js', '@mescius/spread-sheets-charts': 'npm:@mescius/spread-sheets-charts/index.js', '@mescius/spread-sheets': 'npm:@mescius/spread-sheets/index.js', '@mescius/spread-sheets-angular': 'npm:@mescius/spread-sheets-angular/fesm2020/mescius-spread-sheets-angular.mjs', '@grapecity/jsob-test-dependency-package/react-components': 'npm:@grapecity/jsob-test-dependency-package/react-components/index.js' }, // packages tells the System loader how to load when no filename and/or no extension packages: { src: { defaultExtension: 'ts' }, rxjs: { defaultExtension: 'js' }, "node_modules": { defaultExtension: 'js' }, "node_modules/@angular": { defaultExtension: 'mjs' }, "@mescius/spread-sheets-angular": { defaultExtension: 'mjs' }, '@angular/core': { defaultExtension: 'mjs', main: 'core.mjs' } } }); })(this);