SpreadJS supports line, stacked line, 100% stacked line, line with markers, stacked line with markers, and 100% stacked line with markers charts. Use the GC.Spread.Sheets.Charts.ChartType.line property to get the chart type.
You can add a line chart to Spread and change its style(like smooth) using the chart API:
The line chart can be stacked normally or to add up to 100 percent, with or without markers.
You can customize the color, shape, border of marker at the series with markers..
Line and Line with markers: Line charts can be shown with or without markers to indicate individual data values. Line charts are useful for showing trends over time or over evenly-spaced categories, especially when you have many data points and the order in which they are presented is important. If there are many categories or the values are approximate, it’s best to use a line chart without markers.
Stacked line and Stacked line with markers: Stacked line charts can show the trend of the contribution of each value over time or over evenly-spaced categories.
100% stacked line and 100% stacked line with markers: One-hundred percent stacked line charts can show the trend of the percentage each value contributes over time or evenly-spaced categories. If there are many categories or the values are approximate, use a 100% stacked line chart without markers.
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 chartType = [{
type: GC.Spread.Sheets.Charts.ChartType.line,
desc: "line",
}, {
type: GC.Spread.Sheets.Charts.ChartType.lineStacked,
desc: "lineStacked",
}, {
type: GC.Spread.Sheets.Charts.ChartType.lineStacked100,
desc: "lineStacked100",
}, {
type: GC.Spread.Sheets.Charts.ChartType.lineMarkers,
desc: "lineMarkers",
withMarker: true,
}, {
type: GC.Spread.Sheets.Charts.ChartType.lineMarkersStacked,
desc: "lineMarkersStacked",
withMarker: true,
}, {
type: GC.Spread.Sheets.Charts.ChartType.lineMarkersStacked100,
desc: "lineMarkersStacked100",
withMarker: true,
}];
spread.suspendPaint();
let sheets = spread.sheets;
for (let i = 0; i < chartType.length; i++) {
let sheet = sheets[i];
this.initSheet(sheet, chartType[i].desc);
this.initChart(sheet, chartType[i].type, chartType[i].withMarker);//add chart
}
spread.options.tabStripRatio = 0.8;
spread.resumePaint();
}
initSheet(sheet: GC.Spread.Sheets.Worksheet, sheetName: string) {
sheet.name(sheetName);
//prepare data for chart
let dataArray = [
["", '2012', '2013', '2014', '2015', '2016', '2017'],
["Chrome", 0.3782, 0.5663, 0.4966, 0.6689, 0.4230, 0.6360],
["FireFox", 0.1284, 0.2030, 0.2801, 0.2560, 0.1531, 0.3304],
["IE", 0.3214, 0.2491, 0.2455, 0.1652, 0.2073, 0.0834],
];
sheet.setArray(0, 0, dataArray);
}
initChart(sheet: GC.Spread.Sheets.Worksheet, chartType: GC.Spread.Sheets.Charts.ChartType, marker: any) {
//add chart
let chart = sheet.charts.add((sheet.name() + 'Chart1'), chartType, 10, 85, 450, 350, "A1:G4", GC.Spread.Sheets.Charts.RowCol.rows);
this.changeChartLegend(chart);
this.changeChartArea(chart);
this.changChartDataLabels(chart);
this.changeGridLines(chart);
this.changeLineStyle(chart, false);
this.changeChartAxes(chart);
this.changeChartTitle(chart);
if (marker) {
this.changeMarker(chart);
}
chart = sheet.charts.add((sheet.name() + 'Chart2'), chartType, 470, 85, 450, 350, "A1:G4", GC.Spread.Sheets.Charts.RowCol.rows);
this.changeChartLegend(chart);
this.changeChartArea(chart);
this.changChartDataLabels(chart);
this.changeGridLines(chart);
this.changeLineStyle(chart, true);
this.changeChartAxes(chart);
this.changeChartTitle(chart);
if (marker) {
this.changeMarker(chart);
}
}
changeChartTitle(chart: GC.Spread.Sheets.Charts.Chart) {
let title = chart.title();
title.text = "Browser Market Share";
title.fontSize = 18;
chart.title(title);
}
//change legend position
changeChartLegend(chart: GC.Spread.Sheets.Charts.Chart) {
let legend = chart.legend();
legend.visible = true;
let legendPosition = GC.Spread.Sheets.Charts.LegendPosition;
legend.position = legendPosition.bottom;
chart.legend(legend);
}
//change backColor
changeChartArea(chart: GC.Spread.Sheets.Charts.Chart) {
let chartArea = chart.chartArea();
chartArea.fontSize = 14;
chart.chartArea(chartArea);
}
// show dataLabels
changChartDataLabels(chart: GC.Spread.Sheets.Charts.Chart) {
let dataLabels = chart.dataLabels();
dataLabels.showValue = true;
dataLabels.showSeriesName = false;
dataLabels.showCategoryName = false;
dataLabels.format = "0%";
let dataLabelPosition = GC.Spread.Sheets.Charts.DataLabelPosition;
dataLabels.position = dataLabelPosition.above;
chart.dataLabels(dataLabels);
}
// hide gridLines
changeGridLines(chart: GC.Spread.Sheets.Charts.Chart) {
let gridLinesAxes = chart.axes();
gridLinesAxes.primaryValue.min = null;
chart.axes(gridLinesAxes);
}
//change legend position
changeChartAxes(chart: GC.Spread.Sheets.Charts.Chart) {
chart.axes({primaryValue:{format:"0%"}});
}
// change line style
changeLineStyle(chart: GC.Spread.Sheets.Charts.Chart, smooth: boolean) {
let series = chart.series().get();
let seriesItem;
for (let i = 0; i < series.length; i++) {
seriesItem = series[i];
seriesItem.border.width = 2;
seriesItem.smooth = smooth;
chart.series().set(i, seriesItem);
}
}
// change Marker
changeMarker(chart: GC.Spread.Sheets.Charts.Chart) {
let preSet = [
{ fill: "", shape: 0 /** circle */, size: 7, border: { color: "blue", width: 1 } },
{ fill: "", shape: 8/** star */, size: 9, border: { color: "black", width: 1 } },
{ fill: "yellow", shape: 2 /** diamond */, size: 7, border: { color: "red", width: 2 } },
];
let series = chart.series().get();
let seriesItem;
for (let i = 0; i < series.length; i++) {
seriesItem = series[i];
seriesItem.symbol = preSet[i];
chart.series().set(i, seriesItem);
}
}
}
@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-worksheet></gc-worksheet>
<gc-worksheet></gc-worksheet>
<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);