On top of the series style, you can set special styles for some special meaningful data points. The data point styles can make data presentation more focused and charts more intuitive and efficient.
For different chart types, the data point style supports the following customizations
backColor - The solid or pattern background color of the data point or point marker.
backColorTransparency - The background color transparency of the data point or point marker.
border.color - The border color of the data point.
border.transparency - The border color transparency of the data point.
border.width - The border width of the data point.
border.lineType - The border line type of the data point.
You can customize the chart's data point style with the below code:
import * as React from 'react';
import { createRoot } from 'react-dom/client';
import './styles.css';
import { AppFunc } from './app-func';
// import { App } from './app-class';
// 1. Functional Component sample
createRoot(document.getElementById('app')).render(<AppFunc />);
// 2. Class Component sample
// createRoot(document.getElementById('app')).render(<App />);
import * as React from 'react';
import GC from '@mescius/spread-sheets';
import { SpreadSheets, Worksheet } from '@mescius/spread-sheets-react';
import '@mescius/spread-sheets-shapes';
import '@mescius/spread-sheets-charts';
export function AppFunc() {
let spread = null;
const initSpread = (spread) => {
let chartType = [{
type: GC.Spread.Sheets.Charts.ChartType.columnClustered,
desc: "columnClustered",
position: [15, 100, 1300, 400],
dataArray: [
["", 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov',
'Dec'
],
["Tokyo", 49.9, 71.5, 106.4, 129.2, 144.0, 146.0, 135.6, 148.5, 256.4, 155.1,
95.6, 54.4
],
["New York", 83.6, 78.8, 98.5, 93.4, 106.0, 199.5, 105.0, 104.3, 91.2, 83.5, 106.6,
92.3
],
["London", 48.9, 38.8, 39.3, 41.4, 47.0, 48.3, 59.0, 59.6, 52.4, 186.2, 59.3,
51.2
],
["Berlin", 42.4, 33.2, 34.5, 39.7, 52.6, 75.5, 57.4, 60.4, 178.6, 39.1, 46.8, 51.1]
],
dataFormula: "A1:M5",
dataPoinsStyle: [{
8: {
backColor: "red",
backColorTransparency: 0.1,
border: {
color: 'rgb(120, 180, 240)',
width: 5,
}
},
},
{
5: {
backColor: "black",
backColorTransparency: 0.1,
border: {
color: 'rgb(240, 160, 80)',
width: 5,
}
}
},
{
9: {
backColor: "black",
backColorTransparency: 0.1,
border: {
color: 'rgb(140, 240, 120)',
width: 5,
}
},
},
{
8: {
backColor: "black",
backColorTransparency: 0.1,
border: {
color: 'rgb(120, 150, 190)',
width: 5,
}
}
}
],
changeStyle: function (chart, dataPoinsStyle) {
changeChartTitle(chart, "The Average Monthly Rainfall");
changChartDataLabels(chart);
chart.axes({
primaryValue: {
title: {
text: "Rainfall(mm)"
}
}
});
changeChartSeriesColor(chart);
changeChartSeriesDataPointStyle(chart, dataPoinsStyle);
changeChartSeriesGapWidthAndOverLap(chart);
}
},
{
type: GC.Spread.Sheets.Charts.ChartType.barClustered,
desc: "barClustered",
position: [15, 100, 1300, 400],
dataArray: [
["", 'Tokyo', 'New York', 'London', 'Berlin'],
["The First Quarter", 227.8, 260.9, 127, 110.1],
["The Second Quarter", 449.2, 283.9, 136.7, 167.8],
["The Third Quarter", 500.5, 300.5, 171, 165.4],
["The Fourth Quarter", 344.1, 282.4, 175.7, 137]
],
dataFormula: "A1:E5",
dataPoinsStyle: [, ,
{
0: {
backColor: "red",
backColorTransparency: 0.1,
border: {
color: 'gray',
width: 5,
}
}
}
],
changeStyle: function (chart, dataPoinsStyle) {
changeChartTitle(chart, "The Average Quarterly Rainfall");
changChartDataLabels(chart);
changeChartSeriesColor(chart);
changeChartSeriesDataPointStyle(chart, dataPoinsStyle);
changeChartSeriesGapWidthAndOverLap(chart);
}
},
{
type: GC.Spread.Sheets.Charts.ChartType.pie,
desc: "pie",
position: [15, 100, 700, 400],
dataArray: [
["", 'Chrome', 'Firefox', 'IE', 'Safari', 'Edge', 'Opera', 'Other'],
["2017", 0.6360, 0.1304, 0.0834, 0.0589, 0.0443, 0.0223, 0.0246]
],
dataFormula: "A1:H2",
dataPoinsStyle: [{
0: {
backColor: {
type: GC.Spread.Sheets.Charts.PatternType.wideUpwardDiagonal,
foregroundColor: "white",
backgroundColor: "LightBlue",
},
backColorTransparency: 0.1,
},
},],
changeStyle: function (chart, dataPoinsStyle) {
changeChartTitle(chart, "Browser Market Share");
changChartDataLabels(chart);
changeChartSeriesDataPointStyle(chart, dataPoinsStyle);
}
},
{
type: GC.Spread.Sheets.Charts.ChartType.sunburst,
desc: "sunburst",
position: [300, 50, 700, 400],
dataArray: [
['Region', 'Subregion', 'Country', 'Population'],
['Asia', 'Southern', 'India', 1354051854],
[, , 'Pakistan', 200813818],
[, , 'Bangladesh', 166368149],
[, , 'Others', 170220300],
[, 'Eastern', 'China', 1415045928],
[, , 'Japan', 127185332],
[, , 'Others', 111652273],
[, 'South-Eastern', , 655636576],
[, 'Western', , 272298399],
[, 'Central', , 71860465],
['Africa', 'Eastern', , 433643132],
[, 'Western', , 381980688],
[, 'Northern', , 237784677],
[, 'Others', , 234512021],
['Europe', , , 742648010],
['Others', , , 1057117703]
],
dataFormula: "A1:D17",
dataPoinsStyle: [{
6: {
backColor: "limegreen ",
border: {
color: 'lightcyan ',
width: 9,
}
}
},],
changeStyle: function (chart, dataPoinsStyle) {
changeChartTitle(chart, "World Population");
changeChartSeriesDataPointStyle(chart, dataPoinsStyle);
}
}
];
let sheets = spread.sheets;
spread.suspendPaint();
for (let i = 0; i < chartType.length; i++) {
let sheet = sheets[i];
initSheet(sheet, chartType[i].desc, chartType[i].dataArray);
let chart = addChart(sheet, chartType[i].type, chartType[i].dataFormula, chartType[i].position); //add chart
chartType[i].changeStyle(chart, chartType[i].dataPoinsStyle);
}
spread.resumePaint();
}
const initSheet = (sheet, sheetName, dataArray) => {
sheet.name(sheetName);
//prepare data for chart
sheet.setArray(0, 0, dataArray);
sheet.setColumnCount(100);
}
const addChart = (sheet, chartType, dataFormula, position) => {
//add chart
return sheet.charts.add((sheet.name() + 'Chart1'), chartType, position[0], position[1], position[2], position[3], dataFormula, GC
.Spread.Sheets.Charts.RowCol.rows);
}
const changeChartTitle = (chart, title) => {
chart.title({
text: title
});
}
// show dataLabels
const changChartDataLabels = (chart) => {
let dataLabels = chart.dataLabels();
dataLabels.showValue = true;
dataLabels.showSeriesName = false;
dataLabels.showCategoryName = false;
let dataLabelPosition = GC.Spread.Sheets.Charts.DataLabelPosition;
dataLabels.position = dataLabelPosition.outsideEnd;
chart.dataLabels(dataLabels);
}
//change point style
const changeChartSeriesDataPointStyle = (chart, dataPoinsStyle) => {
let series = chart.series().get();
for (let i = 0; i < series.length; i++) {
if (dataPoinsStyle[i]) {
chart.series().set(i, {
dataPoints: dataPoinsStyle[i]
});
}
}
}
//change color
const changeChartSeriesColor = (chart) => {
let series = chart.series().get();
let colorArray = ['rgb(120, 180, 240)', 'rgb(240, 160, 80)', 'rgb(140, 240, 120)', 'rgb(120, 150, 190)'];
for (let i = 0; i < series.length; i++) {
chart.series().set(i, {
backColor: colorArray[i]
});
}
}
const changeChartSeriesGapWidthAndOverLap = (chart) => {
let seriesItem = chart.series().get(0);
seriesItem.gapWidth = 2;
seriesItem.overlap = -0.5;
chart.series().set(0, seriesItem);
}
return (<div class="sample-tutorial">
<div class="sample-spreadsheets">
<SpreadSheets workbookInitialized={spread => initSpread(spread)}>
<Worksheet />
<Worksheet />
<Worksheet />
<Worksheet />
</SpreadSheets>
</div>
</div>);
}
import * as React from 'react';
import GC from '@mescius/spread-sheets';
import { SpreadSheets, Worksheet } from '@mescius/spread-sheets-react';
import '@mescius/spread-sheets-shapes';
import '@mescius/spread-sheets-charts';
const Component = React.Component;
export class App extends Component {
constructor(props) {
super(props);
this.spread = null;
}
render() {
return (<div class="sample-tutorial">
<div class="sample-spreadsheets">
<SpreadSheets workbookInitialized={spread => this.initSpread(spread)}>
<Worksheet />
<Worksheet />
<Worksheet />
<Worksheet />
</SpreadSheets>
</div>
</div>);
}
initSpread(spread) {
let self = this;
let chartType = [{
type: GC.Spread.Sheets.Charts.ChartType.columnClustered,
desc: "columnClustered",
position: [15, 100, 1300, 400],
dataArray: [
["", 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov',
'Dec'
],
["Tokyo", 49.9, 71.5, 106.4, 129.2, 144.0, 146.0, 135.6, 148.5, 256.4, 155.1,
95.6, 54.4
],
["New York", 83.6, 78.8, 98.5, 93.4, 106.0, 199.5, 105.0, 104.3, 91.2, 83.5, 106.6,
92.3
],
["London", 48.9, 38.8, 39.3, 41.4, 47.0, 48.3, 59.0, 59.6, 52.4, 186.2, 59.3,
51.2
],
["Berlin", 42.4, 33.2, 34.5, 39.7, 52.6, 75.5, 57.4, 60.4, 178.6, 39.1, 46.8, 51.1]
],
dataFormula: "A1:M5",
dataPoinsStyle: [{
8: {
backColor: "red",
backColorTransparency: 0.1,
border: {
color: 'rgb(120, 180, 240)',
width: 5,
}
},
},
{
5: {
backColor: "black",
backColorTransparency: 0.1,
border: {
color: 'rgb(240, 160, 80)',
width: 5,
}
}
},
{
9: {
backColor: "black",
backColorTransparency: 0.1,
border: {
color: 'rgb(140, 240, 120)',
width: 5,
}
},
},
{
8: {
backColor: "black",
backColorTransparency: 0.1,
border: {
color: 'rgb(120, 150, 190)',
width: 5,
}
}
}
],
changeStyle: function (chart, dataPoinsStyle) {
self.changeChartTitle(chart, "The Average Monthly Rainfall");
self.changChartDataLabels(chart);
chart.axes({
primaryValue: {
title: {
text: "Rainfall(mm)"
}
}
});
self.changeChartSeriesColor(chart);
self.changeChartSeriesDataPointStyle(chart, dataPoinsStyle);
self.changeChartSeriesGapWidthAndOverLap(chart);
}
},
{
type: GC.Spread.Sheets.Charts.ChartType.barClustered,
desc: "barClustered",
position: [15, 100, 1300, 400],
dataArray: [
["", 'Tokyo', 'New York', 'London', 'Berlin'],
["The First Quarter", 227.8, 260.9, 127, 110.1],
["The Second Quarter", 449.2, 283.9, 136.7, 167.8],
["The Third Quarter", 500.5, 300.5, 171, 165.4],
["The Fourth Quarter", 344.1, 282.4, 175.7, 137]
],
dataFormula: "A1:E5",
dataPoinsStyle: [, ,
{
0: {
backColor: "red",
backColorTransparency: 0.1,
border: {
color: 'gray',
width: 5,
}
}
}
],
changeStyle: function (chart, dataPoinsStyle) {
self.changeChartTitle(chart, "The Average Quarterly Rainfall");
self.changChartDataLabels(chart);
self.changeChartSeriesColor(chart);
self.changeChartSeriesDataPointStyle(chart, dataPoinsStyle);
self.changeChartSeriesGapWidthAndOverLap(chart);
}
},
{
type: GC.Spread.Sheets.Charts.ChartType.pie,
desc: "pie",
position: [15, 100, 700, 400],
dataArray: [
["", 'Chrome', 'Firefox', 'IE', 'Safari', 'Edge', 'Opera', 'Other'],
["2017", 0.6360, 0.1304, 0.0834, 0.0589, 0.0443, 0.0223, 0.0246]
],
dataFormula: "A1:H2",
dataPoinsStyle: [{
0: {
backColor: {
type: GC.Spread.Sheets.Charts.PatternType.wideUpwardDiagonal,
foregroundColor: "white",
backgroundColor: "LightBlue",
},
backColorTransparency: 0.1,
},
},],
changeStyle: function (chart, dataPoinsStyle) {
self.changeChartTitle(chart, "Browser Market Share");
self.changChartDataLabels(chart);
self.changeChartSeriesDataPointStyle(chart, dataPoinsStyle);
}
},
{
type: GC.Spread.Sheets.Charts.ChartType.sunburst,
desc: "sunburst",
position: [300, 50, 700, 400],
dataArray: [
['Region', 'Subregion', 'Country', 'Population'],
['Asia', 'Southern', 'India', 1354051854],
[, , 'Pakistan', 200813818],
[, , 'Bangladesh', 166368149],
[, , 'Others', 170220300],
[, 'Eastern', 'China', 1415045928],
[, , 'Japan', 127185332],
[, , 'Others', 111652273],
[, 'South-Eastern', , 655636576],
[, 'Western', , 272298399],
[, 'Central', , 71860465],
['Africa', 'Eastern', , 433643132],
[, 'Western', , 381980688],
[, 'Northern', , 237784677],
[, 'Others', , 234512021],
['Europe', , , 742648010],
['Others', , , 1057117703]
],
dataFormula: "A1:D17",
dataPoinsStyle: [{
6: {
backColor: "limegreen ",
border: {
color: 'lightcyan ',
width: 9,
}
}
},],
changeStyle: function (chart, dataPoinsStyle) {
self.changeChartTitle(chart, "World Population");
self.changeChartSeriesDataPointStyle(chart, dataPoinsStyle);
}
}
];
let sheets = spread.sheets;
spread.suspendPaint();
for (let i = 0; i < chartType.length; i++) {
let sheet = sheets[i];
this.initSheet(sheet, chartType[i].desc, chartType[i].dataArray);
let chart = this.addChart(sheet, chartType[i].type, chartType[i].dataFormula, chartType[i].position); //add chart
chartType[i].changeStyle(chart, chartType[i].dataPoinsStyle);
}
spread.resumePaint();
}
initSheet(sheet, sheetName, dataArray) {
sheet.name(sheetName);
//prepare data for chart
sheet.setArray(0, 0, dataArray);
sheet.setColumnCount(100);
}
addChart(sheet, chartType, dataFormula, position) {
//add chart
return sheet.charts.add((sheet.name() + 'Chart1'), chartType, position[0], position[1], position[2], position[3], dataFormula, GC
.Spread.Sheets.Charts.RowCol.rows);
}
changeChartTitle(chart, title) {
chart.title({
text: title
});
}
// show dataLabels
changChartDataLabels(chart) {
let dataLabels = chart.dataLabels();
dataLabels.showValue = true;
dataLabels.showSeriesName = false;
dataLabels.showCategoryName = false;
let dataLabelPosition = GC.Spread.Sheets.Charts.DataLabelPosition;
dataLabels.position = dataLabelPosition.outsideEnd;
chart.dataLabels(dataLabels);
}
//change point style
changeChartSeriesDataPointStyle(chart, dataPoinsStyle) {
let series = chart.series().get();
for (let i = 0; i < series.length; i++) {
if (dataPoinsStyle[i]) {
chart.series().set(i, {
dataPoints: dataPoinsStyle[i]
});
}
}
}
//change color
changeChartSeriesColor(chart) {
let series = chart.series().get();
let colorArray = ['rgb(120, 180, 240)', 'rgb(240, 160, 80)', 'rgb(140, 240, 120)', 'rgb(120, 150, 190)'];
for (let i = 0; i < series.length; i++) {
chart.series().set(i, {
backColor: colorArray[i]
});
}
}
changeChartSeriesGapWidthAndOverLap(chart) {
let seriesItem = chart.series().get(0);
seriesItem.gapWidth = 2;
seriesItem.overlap = -0.5;
chart.series().set(0, seriesItem);
}
}
<!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/react/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css">
<!-- SystemJS -->
<script src="$DEMOROOT$/en/react/node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.js"></script>
<script>
System.import('$DEMOROOT$/en/lib/react/license.js').then(function () {
System.import('./src/app');
});
</script>
</head>
<body>
<div id="app"></div>
</body>
</html>
.sample-tutorial {
position: relative;
height: 100%;
overflow: hidden;
}
.sample-spreadsheets {
width: 100%;
height:100%;
overflow: hidden;
float: left;
}
body {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
#app {
height: 100%;
}
(function (global) {
System.config({
transpiler: 'plugin-babel',
babelOptions: {
es2015: true,
react: true
},
meta: {
'*.css': { loader: 'css' }
},
paths: {
// paths serve as alias
'npm:': 'node_modules/'
},
// map tells the System loader where to look for things
map: {
'@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-react': 'npm:@mescius/spread-sheets-react/index.js',
'@grapecity/jsob-test-dependency-package/react-components': 'npm:@grapecity/jsob-test-dependency-package/react-components/index.js',
'react': 'npm:react/cjs/react.production.js',
'react-dom': 'npm:react-dom/cjs/react-dom.production.js',
'react-dom/client': 'npm:react-dom/cjs/react-dom-client.production.js',
'scheduler': 'npm:scheduler/cjs/scheduler.production.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'
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
src: {
defaultExtension: 'jsx'
},
"node_modules": {
defaultExtension: 'js'
},
}
});
})(this);