Quick Start

DataCharts allow you to bind charts directly to the Data Manager data, eliminating the need to store data within the SpreadJS workbook. The below demo shows how to create a DataChart and edit all of the different options within the UI.

For our ReportSheets Add-On users, the DataCharts Add-On is included and seamlessly integrates with the same Data Manager, enabling you to enhance your reports with dynamic charts effortlessly. If you wish to utilize the DataCharts Add-On outside the ReportSheets Add-On within your spreadsheets, a separate DataCharts Add-On license is required.

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

To use the DataCharts feature, add the SpreadJS DataCharts JS file link into the document's head section:

<head>
   ...
   <script src='.../spreadjs/gc.spread.sheets.all.x.x.x.min.js' type='text/javascript'></script>
   <script src='.../spreadjs/plugins/gc.spread.sheets.shapes.x.x.x.min.js' type='text/javascript'></script>
   <script src='.../spreadjs/plugins/gc.spread.sheets.datacharts.x.x.x.min.js' type='text/javascript'></script>
</head>

You can create a DataChart with the sheet.dataCharts.add method, as shown below:

const dataManager = spread.dataManager();
const salesTable = createSalesTable(dataManager);
await salesTable.fetch();
const sheet = spread.getActiveSheet();
const dataChart = sheet.dataCharts.add('data-chart-1', 10, 10, 480, 300, GC.Spread.Sheets.DataCharts.DataChartType.column);
dataChart.setChartConfig({
    tableName: 'Sales',
    config: {
        bar: {
            // category width
            width: 0.6,
        },
        header: {
            // title settings
            title: 'Column Chart',
            padding: {
                left: 10,
                right: 10,
                top: 10,
                bottom: 10,
            },
            style: {
                fill: {
                    type: 'CssColor',
                    color: 'rgba(242, 242, 242, 1)',
                }
            },
            textStyle: {
                color: 'rgba(51, 51, 51, 1)',
                fontSize: 18,
                fontFamily: 'Calibri',
                fontStyle: GC.Spread.Sheets.DataCharts.FontStyle.italic,
                fontWeight: 'Bold',
                alignment: GC.Spread.Sheets.DataCharts.HAlign.left,
            }
        },
        // set padding for the chart
        plotAreas: [{
            padding: {
                left: 20,
                right: 20,
                top: 20,
                bottom: 20,
            }
        }]
    },
    plots: [
        {
            type: GC.Spread.Sheets.DataCharts.DataChartType.column,
            encodings: {
                values: [{ field: 'Sales', aggregate: GC.Spread.Sheets.DataCharts.Aggregate.sum }],
                category: { field: 'Product' },
                color: { field: 'Product' },
            }
        }
    ]
});

function createSalesTable (dataManager) {
    const records = [
        ['2021', 'East', 'SunLin', 'Drinks', 'Apple Juice', 140, 9],
        ['2021', 'East', 'JinShiPeng', 'Drinks', 'Apple Juice', 290, 17],
        ['2021', 'East', 'ZhangShang', 'Drinks', 'Apple Juice', 300, 28],
        ['2021', 'East', 'SunYang', 'Drinks', 'Apple Juice', 120, 10],
        ['2021', 'East', 'YuanChengJie', 'Drinks', 'Apple Juice', 220, 15],
        ['2021', 'North', 'ZhangYing', 'Drinks', 'Apple Juice', 250.0, 23],
        ['2021', 'North', 'WangWei', 'Drinks', 'Apple Juice', 180.0, 17],
        ['2021', 'North', 'ZhangWu', 'Drinks', 'Apple Juice', 233.0, 23],
        ['2021', 'North', 'HanWen', 'Drinks', 'Apple Juice', 123.0, 12],
        ['2021', 'East', 'SunLin', 'Drinks', 'Milk', 431.0, 38],
        ['2021', 'East', 'JinShiPeng', 'Drinks', 'Milk', 635.0, 56],
        ['2021', 'East', 'ZhangShang', 'Drinks', 'Milk', 324.0, 33],
        ['2021', 'East', 'SunYang', 'Drinks', 'Milk', 644.0, 68],
        ['2021', 'East', 'YuanChengJie', 'Drinks', 'Milk', 343.0, 19],
        ['2021', 'North', 'ZhangYing', 'Drinks', 'Milk', 234.0, 13],
        ['2021', 'North', 'WangWei', 'Drinks', 'Milk', 666.0, 39],
        ['2021', 'North', 'ZhangWu', 'Drinks', 'Milk', 700.0, 77],
        ['2021', 'North', 'HanWen', 'Drinks', 'Milk', 111.0, 8],
        ['2021', 'East', 'SunLin', 'Drinks', 'Orange Juice', 176.0, 18],
        ['2021', 'East', 'JinShiPeng', 'Drinks', 'Orange Juice', 500.0, 20],
        ['2021', 'East', 'ZhangShang', 'Drinks', 'Orange Juice', 340.0, 19],
        ['2021', 'East', 'SunYang', 'Drinks', 'Orange Juice', 540.0, 45],
        ['2021', 'East', 'YuanChengJie', 'Drinks', 'Orange Juice', 563.0, 56],
        ['2021', 'North', 'ZhangYing', 'Drinks', 'Orange Juice', 300.0, 19],
        ['2021', 'North', 'WangWei', 'Drinks', 'Orange Juice', 490.0, 44],
        ['2021', 'North', 'ZhangWu', 'Drinks', 'Orange Juice', 233.0, 25],
        ['2021', 'North', 'HanWen', 'Drinks', 'Orange Juice', 760.0, 78],
        ['2021', 'East', 'SunLin', 'Dessert', 'Chocolate', 333.0, 32],
        ['2021', 'East', 'JinShiPeng', 'Dessert', 'Chocolate', 420.0, 46],
        ['2021', 'East', 'ZhangShang', 'Dessert', 'Chocolate', 318.0, 37],
        ['2021', 'East', 'SunYang', 'Dessert', 'Chocolate', 256.0, 21],
        ['2021', 'East', 'YuanChengJie', 'Dessert', 'Chocolate', 583.0, 54],
        ['2021', 'North', 'ZhangYing', 'Dessert', 'Chocolate', 352.0, 33],
        ['2021', 'North', 'WangWei', 'Dessert', 'Chocolate', 384.0, 39],
        ['2021', 'North', 'ZhangWu', 'Dessert', 'Chocolate', 435.0, 42],
        ['2021', 'North', 'HanWen', 'Dessert', 'Chocolate', 356.0, 36],
        ['2021', 'East', 'SunLin', 'Dessert', 'Beef Jerky', 789.0, 73],
        ['2021', 'East', 'JinShiPeng', 'Dessert', 'Beef Jerky', 156.0, 14],
        ['2021', 'East', 'ZhangShang', 'Dessert', 'Beef Jerky', 289.0, 23],
        ['2021', 'East', 'SunYang', 'Dessert', 'Beef Jerky', 562.0, 45],
        ['2021', 'East', 'YuanChengJie', 'Dessert', 'Beef Jerky', 546.0, 56],
        ['2021', 'North', 'ZhangYing', 'Dessert', 'Beef Jerky', 218.0, 17],
        ['2021', 'North', 'WangWei', 'Dessert', 'Beef Jerky', 541.0, 56],
        ['2021', 'North', 'ZhangWu', 'Dessert', 'Beef Jerky', 219.0, 21],
        ['2021', 'North', 'HanWen', 'Dessert', 'Beef Jerky', 345.0, 21],
    ];

    const columns = ['Year', 'Region', 'Salesman', 'ProductCategory', 'Product', 'Sales', 'Return'];
    return dataManager.addTable('Sales', {
        data: records.map((x) => {
            const record = {};
            columns.forEach((c, i) => record[c] = x[i]);
            return record;
        })
    });
}
To use the DataCharts feature, add the SpreadJS DataCharts JS file link into the document's head section: You can create a DataChart with the sheet.dataCharts.add method, as shown below:
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-print'; import '@mescius/spread-sheets-shapes'; import '@mescius/spread-sheets-charts'; import '@mescius/spread-sheets-reportsheet-addon'; import '@mescius/spread-sheets-datacharts-addon'; import '@mescius/spread-sheets-tablesheet'; import '@mescius/spread-sheets-ganttsheet'; import '@mescius/spread-sheets-formula-panel'; import '@mescius/spread-sheets-designer-resources-en'; import '@mescius/spread-sheets-designer'; import { DesignerModule } from "@mescius/spread-sheets-designer-angular"; import './styles.css'; import '$DEMOROOT$/spread/source/js/angular/license.ts'; import { registerlic } from '$DEMOROOT$/spread/source/js/designer/react_vue/license.js'; registerlic(GC); @Component({ selector: 'app-component', templateUrl: 'src/app.component.html' }) export class AppComponent { showDesigner = top === window; props = {}; hostStyle: any; constructor() { if (!this.showDesigner) { this.hostStyle = { width: '100%', height: '100%', overflow: 'hidden', float: 'left' }; } } initDesigner($event) { initDesigner($event.designer); } initSpread($event) { initSpread($event.spread); } } async function initDesigner(designer) { await initSpread(designer.getWorkbook()); designer.refresh(); } async function initSpread(spread) { spread.suspendPaint(); spread.setSheetCount(1); const loadingTip = addLoadingTip(); const res = await fetch('$DEMOROOT$/en/sample/features/data-charts/quick-start/spread.json'); await spread.fromJSON(await res.json()); new GC.Spread.Sheets.DataCharts.DataChartConfigPanel('panel-host', spread); spread.getActiveSheet().dataCharts.all()[0].isSelected(true); loadingTip.remove(); spread.resumePaint(); } function addLoadingTip() { const div = document.createElement('div'); div.style.position = 'absolute'; div.style.inset = '0'; div.style.display = 'flex'; div.style.alignItems = 'center'; div.style.justifyContent = 'center'; div.style.background = 'white'; div.style.zIndex = '100'; div.textContent = 'Loading data from server ...'; document.body.appendChild(div); return div; } @NgModule({ imports: [BrowserModule, SpreadSheetsModule, DesignerModule], 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"> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/en/angular/node_modules/@mescius/spread-sheets-designer/styles/gc.spread.sheets.designer.min.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('./src/app.component'); }); </script> </head> <body> <app-component></app-component> </body> </html>
<div class="sample-tutorial"> <designer *ngIf="showDesigner" [props]="props" (designerInitialized)="initDesigner($event)"></designer> <div id="spread-host" *ngIf="!showDesigner" > <gc-spread-sheets [hostStyle]="hostStyle" (workbookInitialized)="initSpread($event)"></gc-spread-sheets> </div> <div id="panel-host" *ngIf="!showDesigner" ></div> </div>
body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; } .sample-tutorial { position: relative; height: 100%; overflow: hidden; } .gc-designer-container { height: 100%; width: 100%; } #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%; }
(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-designer-resources-en': 'npm:@mescius/spread-sheets-designer-resources-en/index.js', '@mescius/spread-sheets-designer': 'npm:@mescius/spread-sheets-designer/index.js', '@mescius/spread-sheets-designer-angular': 'npm:@mescius/spread-sheets-designer-angular/fesm2020/mescius-spread-sheets-designer-angular.mjs', '@mescius/spread-excelio': 'npm:@mescius/spread-excelio/index.js', '@mescius/spread-sheets-barcode': 'npm:@mescius/spread-sheets-barcode/index.js', '@mescius/spread-sheets-charts': 'npm:@mescius/spread-sheets-charts/index.js', '@mescius/spread-sheets-languagepackages': 'npm:@mescius/spread-sheets-languagepackages/index.js', '@mescius/spread-sheets-print': 'npm:@mescius/spread-sheets-print/index.js', '@mescius/spread-sheets-pdf': 'npm:@mescius/spread-sheets-pdf/index.js', '@mescius/spread-sheets-shapes': 'npm:@mescius/spread-sheets-shapes/index.js', '@mescius/spread-sheets-io': 'npm:@mescius/spread-sheets-io/index.js', '@mescius/spread-sheets-reportsheet-addon': 'npm:@mescius/spread-sheets-reportsheet-addon/index.js', '@mescius/spread-sheets-datacharts-addon': 'npm:@mescius/spread-sheets-datacharts-addon/index.js', '@mescius/spread-sheets-tablesheet': 'npm:@mescius/spread-sheets-tablesheet/index.js', '@mescius/spread-sheets-ganttsheet': 'npm:@mescius/spread-sheets-ganttsheet/index.js', '@mescius/spread-sheets-formula-panel': 'npm:@mescius/spread-sheets-formula-panel/index.js', '@mescius/spread-sheets-angular': 'npm:@mescius/spread-sheets-angular/fesm2020/mescius-spread-sheets-angular.mjs', '@mescius/spread-sheets': 'npm:@mescius/spread-sheets/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' }, "@mescius/spread-sheets-designer-angular": { defaultExtension: 'mjs' }, '@angular/core': { defaultExtension: 'mjs', main: 'core.mjs' } } }); })(this);