SpreadJS supports High-Low-Close, Open-High-Low-Close, Volume-High-Low-Close, and Volume-Open-High-Low-Close chart types. Use the GC.Spread.Sheets.Charts.ChartType.stockHLC to get the chart type.
A High-Low-Close chart can be added to Spread, and the chart style can be changed using the chart API. The stockHLC chart requires that the data be organized as high, low, and close, with the close value in between the high and low values.
The Open-High-Low-Close chart adds the Open data to the stockHLC data. The values are organized as: open, high, low, and then close.
The Volume-High-Low-Close chart can be added to Spread, and the chart style can be changed using the chart API. The stockVHLC adds the volume data to the stockVHLC data. The values are organized in the following order: volume, high, low, and then close. The volume series' chart type is columnStacked, and you can change that series' style.
The Volume-Open-High-Low-Close chart adds all the data. The values are organized in the following the order: column, open, high, low, and then close.
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 { getData } from './app.data';
import './styles.css';
@Component({
selector: 'app-component',
templateUrl: 'src/app.component.html'
})
export class AppComponent {
spread: GC.Spread.Sheets.Workbook;
dataSource: any[];
hostStyle = {
width: '100%',
height: '100%',
overflow: 'hidden',
float: 'left'
};
constructor() {
this.dataSource = getData();
}
initSpread($event: any) {
this.spread = $event.spread;
let spread = this.spread;
spread.suspendPaint();
spread.options.tabStripRatio = 0.7;
var chartTypeStr = ['stockHLC', 'stockOHLC', 'stockVHLC', 'stockVOHLC'];
var chartType = [{
type: GC.Spread.Sheets.Charts.ChartType.stockHLC,
desc: chartTypeStr[0],
}, {
type: GC.Spread.Sheets.Charts.ChartType.stockOHLC,
desc: chartTypeStr[1],
}, {
type: GC.Spread.Sheets.Charts.ChartType.stockVHLC,
desc: chartTypeStr[2],
}, {
type: GC.Spread.Sheets.Charts.ChartType.stockVOHLC,
desc: chartTypeStr[3],
}];
var sheets = spread.sheets;
var sheet = sheets[sheets.length - 1];
sheet.suspendPaint();
sheet.name(chartTypeStr[chartTypeStr.length - 1]);
sheet.setArray(0, 0, this.dataSource);
sheet.getRange(0, 0, 61, 1).formatter('dd/mm/yyyy');
sheet.setColumnWidth(0, 80);
sheet.resumePaint();
this.initStockHLCChartSheetData(sheets[0], chartTypeStr[0]);
this.initStockOHLCChartSheetData(sheets[1], chartTypeStr[1]);
this.initStockVHLCChartSheetData(sheets[2], chartTypeStr[2]);
for (var i = 0; i < chartType.length; i++) {
sheet = sheets[i];
this.initChart(sheet, chartType[i].type, i);//add chart
}
spread.resumePaint();
}
initStockHLCChartSheetData(sheet: GC.Spread.Sheets.Worksheet, sheetName: string) {
sheet.name(sheetName);
sheet.suspendPaint();
var formula = "='stockVOHLC'!";
for (var i = 0; i < this.dataSource.length - 1; i++) {
var formula1 = formula + 'A' + (i + 1);
sheet.setFormula(i, 0, formula1);
formula1 = formula + 'D' + (i + 1);
sheet.setFormula(i, 1, formula1);
formula1 = formula + 'E' + (i + 1);
sheet.setFormula(i, 2, formula1);
formula1 = formula + 'F' + (i + 1);
sheet.setFormula(i, 3, formula1);
}
sheet.getRange(0, 0, 61, 1).formatter('dd/mm/yyyy');
sheet.setColumnWidth(0, 80);
sheet.resumePaint();
}
initStockOHLCChartSheetData(sheet: GC.Spread.Sheets.Worksheet, sheetName: string) {
sheet.name(sheetName);
sheet.suspendPaint();
var formula = "='stockVOHLC'!";
for (var i = 0; i < this.dataSource.length - 1; i++) {
var formula1 = formula + 'A' + (i + 1);
sheet.setFormula(i, 0, formula1);
formula1 = formula + 'C' + (i + 1);
sheet.setFormula(i, 1, formula1);
formula1 = formula + 'D' + (i + 1);
sheet.setFormula(i, 2, formula1);
formula1 = formula + 'E' + (i + 1);
sheet.setFormula(i, 3, formula1);
formula1 = formula + 'F' + (i + 1);
sheet.setFormula(i, 4, formula1);
}
sheet.getRange(0, 0, 61, 1).formatter('dd/mm/yyyy');
sheet.setColumnWidth(0, 80);
sheet.resumePaint();
}
initStockVHLCChartSheetData(sheet: GC.Spread.Sheets.Worksheet, sheetName: string) {
sheet.name(sheetName);
sheet.suspendPaint();
var formula = "='stockVOHLC'!";
for (var i = 0; i < this.dataSource.length - 1; i++) {
var formula1 = formula + 'A' + (i + 1);
sheet.setFormula(i, 0, formula1);
formula1 = formula + 'B' + (i + 1);
sheet.setFormula(i, 1, formula1);
formula1 = formula + 'D' + (i + 1);
sheet.setFormula(i, 2, formula1);
formula1 = formula + 'E' + (i + 1);
sheet.setFormula(i, 3, formula1);
formula1 = formula + 'f' + (i + 1);
sheet.setFormula(i, 4, formula1);
}
sheet.getRange(0, 0, 61, 1).formatter('dd/mm/yyyy');
sheet.setColumnWidth(0, 80);
sheet.resumePaint();
}
initChart(sheet: GC.Spread.Sheets.Worksheet, chartType: GC.Spread.Sheets.Charts.ChartType, index: number) {
sheet.suspendPaint();
var rangeIndex = ['A1:D61', 'A1:E61', 'A1:E61', 'A1:F61'];
//add chart
sheet.charts.add('Chart1', chartType, 270, 60, 615, 270, rangeIndex[index]);
sheet.resumePaint();
}
}
@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-spread-sheets>
</div>
export function getData() {
return [["Date", "Volume", "Open", "High", "Low", "Close"],
[new Date("2008-08-31"), 46085, 17587.94, 17592.76, 17482.76, 17577.94],
[new Date("2008-09-01"), 40314, 17508.94, 17538.76, 17400.76, 17518.94],
[new Date("2008-09-02"), 45308, 17551.94, 17584.76, 17517.76, 17554.94],
[new Date("2008-09-03"), 53401, 17600.94, 17698.76, 17428.76, 17618.94],
[new Date("2008-09-04"), 57500, 17748.94, 17786.76, 17623.76, 17718.94],
[new Date("2008-09-05"), 43756, 17712.94, 17754.71, 17600.76, 17718.94],
[new Date("2008-09-06"), 55737, 17686.94, 17797.76, 17647.76, 17718.94],
[new Date("2008-09-07"), 61668, 17858.94, 17867.76, 17657.76, 17818.94],
[new Date("2008-09-08"), 47815, 17748.94, 17832.76, 17721.76, 17778.94],
[new Date("2008-09-09"), 45085, 17748.94, 17795.76, 17639.76, 17688.94],
[new Date("2008-09-10"), 42314, 17661.94, 17768.76, 17530.76, 17638.94],
[new Date("2008-09-11"), 35308, 17545.94, 17798.76, 17511.76, 17518.94],
[new Date("2008-09-12"), 51401, 17698.94, 17722.76, 17541.76, 17598.94],
[new Date("2008-09-13"), 55500, 17699.94, 17788.76, 17591.76, 17668.94],
[new Date("2008-09-14"), 43756, 17576.94, 17662.76, 17455.76, 17566.94],
[new Date("2008-09-15"), 47737, 17655.94, 17692.76, 17493.76, 17608.94],
[new Date("2008-09-16"), 45668, 17512.94, 17588.76, 17494.76, 17518.94],
[new Date("2008-09-17"), 47815, 17548.94, 17584.76, 17482.76, 17555.94],
[new Date("2008-09-18"), 57232, 17671.94, 17698.76, 17389.76, 17658.94],
[new Date("2008-09-19"), 46085, 17600.94, 17608.76, 17419.76, 17558.94],
[new Date("2008-09-20"), 42314, 17698.94, 17722.76, 17555.76, 17598.94],
[new Date("2008-09-21"), 45308, 17690.94, 17727.76, 17649.76, 17681.94],
[new Date("2008-09-22"), 53401, 17838.94, 17954.76, 17619.76, 17758.94],
[new Date("2008-09-23"), 60500, 17938.94, 17982.76, 17773.76, 17888.94],
[new Date("2008-09-24"), 53756, 17780.94, 17965.76, 17737.76, 17818.94],
[new Date("2008-09-25"), 55737, 17818.94, 17862.76, 17701.76, 17778.94],
[new Date("2008-09-26"), 45668, 17748.94, 17916.76, 17656.76, 17778.94],
[new Date("2008-09-27"), 49815, 17698.94, 17928.76, 17601.76, 17778.94],
[new Date("2008-09-28"), 46085, 17690.94, 17798.76, 17569.76, 17688.94],
[new Date("2008-09-29"), 42314, 17681.94, 17662.76, 17488.76, 17638.94],
[new Date("2008-09-30"), 45308, 17454.94, 17499.76, 17411.76, 17444.94],
[new Date("2008-10-01"), 43401, 17428.94, 17538.76, 17362.76, 17458.94],
[new Date("2008-10-02"), 47500, 17500.94, 17592.76, 17476.76, 17518.94],
[new Date("2008-10-03"), 51756, 17608.94, 17711.76, 17576.76, 17618.94],
[new Date("2008-10-04"), 55737, 17676.94, 17832.76, 17566.76, 17666.94],
[new Date("2008-10-05"), 45668, 17677.94, 17772.76, 17567.76, 17678.94],
[new Date("2008-10-06"), 47815, 17545.94, 17867.76, 17508.76, 17570.94],
[new Date("2008-10-07"), 46085, 17556.94, 17674.76, 17467.76, 17518.94],
[new Date("2008-10-08"), 42314, 17554.94, 17692.76, 17410.76, 17554.94],
[new Date("2008-10-09"), 45308, 17611.94, 17644.76, 17300.76, 17568.94],
[new Date("2008-10-10"), 53401, 17328.94, 17424.76, 17261.76, 17368.94],
[new Date("2008-10-11"), 57500, 17423.94, 17488.76, 17292.76, 17444.94],
[new Date("2008-10-12"), 43756, 17538.94, 17572.76, 17412.76, 17438.94],
[new Date("2008-10-13"), 55737, 17428.94, 17429.76, 17308.76, 17368.94],
[new Date("2008-10-14"), 45668, 17461.94, 17481.76, 17374.76, 17401.94],
[new Date("2008-10-15"), 47815, 17500.94, 17672.76, 17367.76, 17518.94],
[new Date("2008-10-16"), 46085, 17530.94, 17744.76, 17487.76, 17570.94],
[new Date("2008-10-17"), 42314, 17468.94, 17524.76, 17341.76, 17368.94],
[new Date("2008-10-18"), 45308, 17434.94, 17488.76, 17292.76, 17444.94],
[new Date("2008-10-19"), 61401, 17578.94, 17592.76, 17442.76, 17478.94],
[new Date("2008-10-20"), 53500, 17418.94, 17429.76, 17358.76, 17378.94],
[new Date("2008-10-21"), 36756, 17456.94, 17481.76, 17314.76, 17401.94],
[new Date("2008-10-22"), 55737, 17330.94, 17512.76, 17227.76, 17300.94],
[new Date("2008-10-23"), 45668, 17262.94, 17380.76, 17237.76, 17270.94],
[new Date("2008-10-24"), 47815, 17448.94, 17479.76, 17312.76, 17438.94],
[new Date("2008-10-25"), 40085, 17345.94, 17429.76, 17205.76, 17398.94],
[new Date("2008-10-26"), 34314, 17321.94, 17421.76, 17277.76, 17371.94],
[new Date("2008-10-27"), 45308, 17411.94, 17422.76, 17357.76, 17400.94],
[new Date("2008-10-28"), 53401, 17250.94, 17454.76, 17227.76, 17270.94],
[new Date("2008-10-29"), 57500, 17468.94, 17654.76, 17251.76, 17368.94],
[new Date("2008-10-30"), 33756, 17544.94, 17548.76, 17232.76, 17444.94]]
};
.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);