Legend :
The first column represents the state.
The second column represents the winner margin in the last eleven elections, from 1976 to 2016.
It uses the Column Sparkline, red color represents GOP, and blue color represents DNC.
The third column represents the forecasted vote share for DNC.
It uses a formula rule, highlight color represents more than 50%.
The fourth column represents the forecasted vote share for GOP.
It uses a formula rule, highlight color represents more than 50%.
The fifth column represents the difference of the forecasted vote share between the two parties.
It uses the Vari Sparkline, red color represents GOP, and blue color represents DNC.
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 "@mescius/spread-sheets-tablesheet";
import { SpreadSheets } from '@mescius/spread-sheets-react';
export function AppFunc() {
const initSpread = (spread) => {
spread.suspendPaint();
spread.clearSheets();
spread.options.autoFitType = GC.Spread.Sheets.AutoFitType.cellWithHeader;
//init a data manager
var dataManager = spread.dataManager();
//add product table
var myTable = dataManager.addTable("myTable", {
remote: {
read: {
url: "$DEMOROOT$/spread/source/data/2020-election-results.json"
}
},
schema: {
dataPath: "2020-election-data"
}
});
//init a table sheet
var sheet = spread.addSheetTab(0, "TableSheet1", GC.Spread.Sheets.SheetType.tableSheet);
sheet.options.allowAddNew = false;
sheet.actionColumn.options({ visible: false }); //hide action column
sheet.setDefaultRowHeight(40, GC.Spread.Sheets.SheetArea.colHeader);
sheet.setDefaultRowHeight(35);
sheet.options.alternatingRowOptions = null;
//bind a view to the table sheet
var normalStyle = { vAlign: "center" };
var style = { vAlign: "center", wordWrap: true, hAlign:"center" };
var redRule = {
ruleType: "formulaRule",
formula: 'VALUE(LEFT(@,FIND("%",@)-1))>50',
style: { backColor: "#e45d5d", foreColor: "white", hAlign:"center" }
};
var blueRule = {
ruleType: "formulaRule",
formula: 'VALUE(LEFT(@,FIND("%",@)-1))>50',
style: { backColor: "#4f9bed", foreColor: "white" , hAlign:"center"}
};
var myView = myTable.addView("myView", [
{ value: "State", style: normalStyle, width: 130 },
{ value: '=COLUMNSPARKLINE([@past_elections],1,,,"{sc:#e45d5d,sn:true,nc:#4f9bed,dh:true,dxa:true}")', caption: "Winner margin in the last eleven elections", width: 200 },
{ value: '=CONCAT(TEXT([@[Forecast GOP %]], "00.0%"), "\n", TEXT([@[Forecast GOP Low]], "00.0%"), "-", TEXT([@[Forecast GOP High]], "00.0%"))', caption: "Forecasted vote share for GOP", width: 200, style: style, conditionalFormats: [redRule] },
{ value: '=CONCAT(TEXT([@[Forecast DNC]], "00.0%"), "\n", TEXT([@[Forecast DNC Low]], "00.0%"), "-", TEXT([@[Forecast DNC High]], "00.0%"))', caption: "Forecasted vote share for DNC", width: 200, style: style, conditionalFormats: [blueRule] },
{ value: '=VARISPARKLINE([@[Winner Margin]],0,,,,,TRUE,"#e45d5d","#4f9bed")', caption: "Difference", width: 200, style: normalStyle },
]);
myView.fetch().then(function () {
sheet.setDataView(myView);
});
spread.resumePaint();
};
return (
<div class="sample-tutorial">
<div class="sample-spreadsheets">
<SpreadSheets workbookInitialized={initSpread}>
</SpreadSheets>
</div>
</div>
);
}
import * as React from 'react';
import GC from '@mescius/spread-sheets';
import "@mescius/spread-sheets-tablesheet";
import { SpreadSheets } from '@mescius/spread-sheets-react';
const Component = React.Component;
export class App extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div class="sample-tutorial">
<div class="sample-spreadsheets">
<SpreadSheets workbookInitialized={spread => this.initSpread(spread)}>
</SpreadSheets>
</div>
</div>
);
}
initSpread(spread) {
spread.suspendPaint();
spread.clearSheets();
spread.options.autoFitType = GC.Spread.Sheets.AutoFitType.cellWithHeader;
//init a data manager
var dataManager = spread.dataManager();
//add product table
var myTable = dataManager.addTable("myTable", {
remote: {
read: {
url: "$DEMOROOT$/spread/source/data/2020-election-results.json"
}
},
schema: {
dataPath: "2020-election-data"
}
});
//init a table sheet
var sheet = spread.addSheetTab(0, "TableSheet1", GC.Spread.Sheets.SheetType.tableSheet);
sheet.options.allowAddNew = false;
sheet.actionColumn.options({ visible: false }); //hide action column
sheet.setDefaultRowHeight(40, GC.Spread.Sheets.SheetArea.colHeader);
sheet.setDefaultRowHeight(35);
sheet.options.alternatingRowOptions = null;
//bind a view to the table sheet
var normalStyle = { vAlign: "center" };
var style = { vAlign: "center", wordWrap: true, hAlign:"center" };
var redRule = {
ruleType: "formulaRule",
formula: 'VALUE(LEFT(@,FIND("%",@)-1))>50',
style: { backColor: "#e45d5d", foreColor: "white", hAlign:"center" }
};
var blueRule = {
ruleType: "formulaRule",
formula: 'VALUE(LEFT(@,FIND("%",@)-1))>50',
style: { backColor: "#4f9bed", foreColor: "white" , hAlign:"center"}
};
var myView = myTable.addView("myView", [
{ value: "State", style: normalStyle, width: 130 },
{ value: '=COLUMNSPARKLINE([@past_elections],1,,,"{sc:#e45d5d,sn:true,nc:#4f9bed,dh:true,dxa:true}")', caption: "Winner margin in the last eleven elections", width: 200 },
{ value: '=CONCAT(TEXT([@[Forecast GOP %]], "00.0%"), "\n", TEXT([@[Forecast GOP Low]], "00.0%"), "-", TEXT([@[Forecast GOP High]], "00.0%"))', caption: "Forecasted vote share for GOP", width: 200, style: style, conditionalFormats: [redRule] },
{ value: '=CONCAT(TEXT([@[Forecast DNC]], "00.0%"), "\n", TEXT([@[Forecast DNC Low]], "00.0%"), "-", TEXT([@[Forecast DNC High]], "00.0%"))', caption: "Forecasted vote share for DNC", width: 200, style: style, conditionalFormats: [blueRule] },
{ value: '=VARISPARKLINE([@[Winner Margin]],0,,,,,TRUE,"#e45d5d","#4f9bed")', caption: "Difference", width: 200, style: normalStyle },
]);
myView.fetch().then(function () {
sheet.setDataView(myView);
});
spread.resumePaint();
}
}
<!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" style="height: 100%;"></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;
}
(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': 'npm:@mescius/spread-sheets/index.js',
'@mescius/spread-sheets-tablesheet': 'npm:@mescius/spread-sheets-tablesheet/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);