你可以使用 setSparkline 方法来给某个单元格设置迷你图。 并使用 getSparkline 方法来获取迷你图。例如:
SpreadJS 支持 3 种迷你图. SparklineType 枚举表示了各种迷你图的类型:
line
column
winloss
您可以在Excel中使用上面的所有三个sparklines。但是对于其他的sparklines,比如Compatible sparkline, Excel中不支持,除非您得到一个提供这种支持的外接程序扩展。
你可以使用 removeSparkline 方法来移除指定单元格的迷你图。例如:
你也可以使用公式来创建迷你图, 参见 Compatible.
迷你图 data 和 dateAxis 也支持自定义名称。例如:
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import './styles.css';
import { AppFunc } from './app-func';
import { App } from './app-class';
// 1. Functional Component sample
ReactDOM.render(<AppFunc />, document.getElementById('app'));
// 2. Class Component sample
// ReactDOM.render(<App />, document.getElementById('app'));
import * as React from 'react';
import { useState } from 'react';
import GC from '@grapecity-software/spread-sheets';
import '@grapecity-software/spread-sheets-resources-zh';
GC.Spread.Common.CultureManager.culture("zh-cn");
import { SpreadSheets, Worksheet, Column } from '@grapecity-software/spread-sheets-react';
import './styles.css';
const Component = React.Component;
export function AppFunc() {
const [spread, setSpread] = useState(null);
const [row, setRow] = useState(0);
const [col, setCol] = useState(0);
const [rowCol, setRowCol] = useState('0,0');
const [type, setMyType] = useState(0);
const [orientation, setMyOrientation] = useState(0);
let clearSprikline = function () {
let sheet = spread.getActiveSheet();
let range = getActualCellRange(sheet.getSelections()[0], sheet.getRowCount(), sheet.getColumnCount());
for (let r = 0; r < range.rowCount; r++) {
for (let c = 0; c < range.colCount; c++) {
sheet.removeSparkline(r + range.row, c + range.col);
}
}
}
let addSprikline = function () {
let sheet = spread.getActiveSheet();
let range = getActualCellRange(sheet.getSelections()[0], sheet.getRowCount(), sheet.getColumnCount());
let r = row;
let c = col;
let myOrientation = orientation;
let myType = type;
//sparkline settings
var setting = new GC.Spread.Sheets.Sparklines.SparklineSetting();
setting.options.showMarkers = true;
setting.options.lineWeight = 3;
setting.options.displayXAxis = true;
setting.options.showFirst = true;
setting.options.showLast = true;
setting.options.showLow = true;
setting.options.showHigh = true;
setting.options.showNegative = true;
if (!isNaN(r) && !isNaN(c)) {
sheet.setSparkline(r, c, range, myOrientation, myType, setting);
}
}
let setOrientation = function (e) {
let value = parseInt(e.target.value);
setMyOrientation(value);
}
let setType = function (e) {
let value = parseInt(e.target.value);
setMyType(value);
}
let setPosition = function (e) {
let value = e.target.value, arr = value.split(',');
let row = parseInt(arr[0]), col = parseInt(arr[1]);
setRow(row);
setCol(col);
setRowCol(value);
}
let _selectOption = function (select, value) {
if (select === 'line_type') {
setMyType(value);
} else {
setMyOrientation(value);
}
}
let getActualCellRange = function (cellRange, rowCount, columnCount) {
if (cellRange.row == -1 && cellRange.col == -1) {
return new GC.Spread.Sheets.Range(0, 0, rowCount, columnCount);
}
else if (cellRange.row == -1) {
return new GC.Spread.Sheets.Range(0, cellRange.col, rowCount, cellRange.colCount);
}
else if (cellRange.col == -1) {
return new GC.Spread.Sheets.Range(cellRange.row, 0, cellRange.rowCount, columnCount);
}
return cellRange;
};
let initSpread = function (value) {
setSpread(value);
let sheet = value.getSheet(0);
sheet.suspendPaint();
var data = [1, -2, -1, 6, 4, -4, 3, 8];
var dateAxis = [new Date(2011, 0, 5), new Date(2011, 0, 1), new Date(2011, 1, 11), new Date(2011, 2, 1),
new Date(2011, 1, 1), new Date(2011, 1, 3), new Date(2011, 2, 6), new Date(2011, 1, 19)];
sheet.setValue(0, 0, "Series 1");
sheet.setValue(0, 1, "Series 2");
for (let i = 0; i < 8; i++) {
sheet.setValue(i + 1, 0, data[i]);
sheet.getCell(i + 1, 1).value(dateAxis[i]).formatter("yyyy-mm-dd");
}
sheet.setColumnWidth(1, 100);
sheet.setValue(11, 0, "*Data Range is A2-A9");
sheet.setValue(12, 0, "*Date axis range is B2-B9");
var dataRange = new GC.Spread.Sheets.Range(1, 0, 8, 1);
var dateAxisRange = new GC.Spread.Sheets.Range(1, 1, 8, 1);
sheet.getCell(0, 5).text("Sparkline without dateAxis:");
sheet.getCell(1, 5).text("(1) Line");
sheet.getCell(1, 8).text("(2) Column");
sheet.getCell(1, 11).text("(3) Winloss");
sheet.getCell(7, 5).text("Sparkline with dateAxis:");
sheet.getCell(8, 5).text("(1) Line");
sheet.getCell(8, 8).text("(2) Column");
sheet.getCell(8, 11).text("(3) Winloss");
//sparkline settings
var setting = new GC.Spread.Sheets.Sparklines.SparklineSetting();
setting.options.showMarkers = true;
setting.options.lineWeight = 3;
setting.options.displayXAxis = true;
setting.options.showFirst = true;
setting.options.showLast = true;
setting.options.showLow = true;
setting.options.showHigh = true;
setting.options.showNegative = true;
//line
sheet.addSpan(2, 5, 4, 3);
sheet.setSparkline(2, 5, dataRange
, GC.Spread.Sheets.Sparklines.DataOrientation.vertical
, GC.Spread.Sheets.Sparklines.SparklineType.line
, setting
);
sheet.addSpan(9, 5, 4, 3);
sheet.setSparkline(9, 5, dataRange
, GC.Spread.Sheets.Sparklines.DataOrientation.vertical
, GC.Spread.Sheets.Sparklines.SparklineType.line
, setting
, dateAxisRange
, GC.Spread.Sheets.Sparklines.DataOrientation.vertical
);
//column
sheet.addSpan(2, 8, 4, 3);
sheet.setSparkline(2, 8, dataRange
, GC.Spread.Sheets.Sparklines.DataOrientation.vertical
, GC.Spread.Sheets.Sparklines.SparklineType.column
, setting
);
sheet.addSpan(9, 8, 4, 3);
sheet.setSparkline(9, 8, dataRange
, GC.Spread.Sheets.Sparklines.DataOrientation.vertical
, GC.Spread.Sheets.Sparklines.SparklineType.column
, setting
, dateAxisRange
, GC.Spread.Sheets.Sparklines.DataOrientation.vertical
);
//winloss
sheet.addSpan(2, 11, 4, 3);
sheet.setSparkline(2, 11, dataRange
, GC.Spread.Sheets.Sparklines.DataOrientation.vertical
, GC.Spread.Sheets.Sparklines.SparklineType.winloss
, setting
);
sheet.addSpan(9, 11, 4, 3);
sheet.setSparkline(9, 11, dataRange
, GC.Spread.Sheets.Sparklines.DataOrientation.vertical
, GC.Spread.Sheets.Sparklines.SparklineType.winloss
, setting
, dateAxisRange
, GC.Spread.Sheets.Sparklines.DataOrientation.vertical
);
sheet.bind(GC.Spread.Sheets.Events.SelectionChanged, selectionChangedCallback);
sheet.resumePaint();
function selectionChangedCallback() {
let sheet = value.getActiveSheet();
let sparkline = sheet.getSparkline(sheet.getActiveRowIndex(), sheet.getActiveColumnIndex());
if (sparkline) {
updateSetting(sparkline);
} else {
initSetting();
}
}
function updateSetting(sparkline) {
let type = sparkline.sparklineType(), orientation = sparkline.dataOrientation(),
row = sparkline.row, column = sparkline.column;
setRow(row);
setCol(col);
setRowCol(row + ',' + column);
_selectOption('line_type', type);
_selectOption('line_orientation', orientation);
}
function initSetting() {
setRow("");
setCol("");
setRowCol("");
_selectOption('line_type', 0);
_selectOption('line_orientation', 0);
}
}
return (
<div class="sample-tutorial">
<div class="sample-spreadsheets">
<SpreadSheets workbookInitialized={spread => initSpread(spread)}>
<Worksheet allowCellOverflow={true}></Worksheet>
</SpreadSheets>
</div>
<Panel
rowCol={rowCol}
type={type}
orientation={orientation}
setPosition={setPosition}
clearSprikline={clearSprikline}
addSprikline={addSprikline}
setType={setType}
setOrientation={setOrientation}
/>
</div>
)
}
class Panel extends Component {
constructor(props) {
super(props);
}
render() {
const { rowCol, type, orientation, setPosition, setOrientation, setType, addSprikline, clearSprikline } = this.props;
return (
<React.Fragment>
<div class="options-container">
<div class="option-group">
<label><b>Add SparkLine:</b></label>
</div>
<hr />
<div class="option-group">
<label>1. Select the data range in the sheet</label>
</div>
<div class="option-group">
<label for="line_position">2. Enter destination cell (row,column index)</label>
<input id="line_position" value={rowCol} onChange={(e) => { setPosition(e) }} />
</div>
<div class="option-group">
<label for="line_position">3. Change the type and orientation</label>
</div>
<div class="option-group">
<label for="line_type">Type:</label>
<select id="line_type" class="position" onChange={(e) => { setType(e) }}>
<option value="0" selected={type === 0 ? "selected" : null}>line</option>
<option value="1" selected={type === 1 ? "selected" : null}>column</option>
<option value="2" selected={type === 2 ? "selected" : null}>winloss</option>
</select>
</div>
<div class="option-group">
<label for="line_orientation">Orientation:</label>
<select id="line_orientation" class="position" onChange={(e) => { setOrientation(e) }}>
<option value="0" selected={orientation === 0 ? "selected" : null}>Vertical</option>
<option value="1" selected={orientation === 1 ? "selected" : null}>Horizontal</option>
</select>
</div>
<div class="option-group">
<label for="line_position">4. Click "Add Sparkline" button</label>
</div>
<div class="option-group">
<input type="button" onClick={() => { addSprikline() }} value="Add Sparkline" id="btnAddSparkline" />
</div>
<br />
<div>
<label><b>Remove SparkLine:</b></label>
</div>
<hr />
<div class="option-group">
<label>1. Select Sparkline</label>
</div>
<div class="option-group">
<input type="button" onClick={() => { clearSprikline() }} value="Clear Sparkline" id="btnClearSparkline" />
</div>
</div>
</React.Fragment>
)
}
}
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import GC from '@grapecity-software/spread-sheets';
import '@grapecity-software/spread-sheets-resources-zh';
GC.Spread.Common.CultureManager.culture("zh-cn");
import { SpreadSheets, Worksheet, Column } from '@grapecity-software/spread-sheets-react';
import './styles.css';
const Component = React.Component;
export class App extends Component {
constructor(props) {
super(props);
this.spread = null;
this.state = {
position: {
row: 0,
col: 0,
rowCol: '0,0'
},
type: 0,
orientation: 0
};
this.setPosition = this.setPosition.bind(this);
this.clearSprikline = this.clearSprikline.bind(this);
this.addSprikline = this.addSprikline.bind(this);
this.setType = this.setType.bind(this);
this.setOrientation = this.setOrientation.bind(this);
}
render() {
return (
<div class="sample-tutorial">
<div class="sample-spreadsheets">
<SpreadSheets workbookInitialized={spread => this.initSpread(spread)}>
<Worksheet allowCellOverflow = {true}></Worksheet>
</SpreadSheets>
</div>
<Panel panelInfo={this.state} setPosition={(e) => { this.setPosition(e) }}
clearSprikline={() => { this.clearSprikline() }} addSprikline={() => (this.addSprikline())}
setType={(e) => { this.setType(e) }} setOrientation={(e) => { this.setOrientation(e) }}
/>
</div>
)
}
clearSprikline() {
let sheet = this.spread.getActiveSheet();
let range = this.getActualCellRange(sheet.getSelections()[0], sheet.getRowCount(), sheet.getColumnCount());
for (let r = 0; r < range.rowCount; r++) {
for (let c = 0; c < range.colCount; c++) {
sheet.removeSparkline(r + range.row, c + range.col);
}
}
}
addSprikline() {
let sheet = this.spread.getActiveSheet();
let range = this.getActualCellRange(sheet.getSelections()[0], sheet.getRowCount(), sheet.getColumnCount());
let r = this.state.position.row;
let c = this.state.position.col;
let orientation = this.state.orientation;
let type = this.state.type;
//sparkline settings
var setting = new GC.Spread.Sheets.Sparklines.SparklineSetting();
setting.options.showMarkers = true;
setting.options.lineWeight = 3;
setting.options.displayXAxis = true;
setting.options.showFirst = true;
setting.options.showLast = true;
setting.options.showLow = true;
setting.options.showHigh = true;
setting.options.showNegative = true;
if (!isNaN(r) && !isNaN(c)) {
sheet.setSparkline(r, c, range, orientation, type, setting);
}
}
setOrientation(e) {
let value = parseInt(e.target.value);
this.setState(() => {
return {
orientation: value
}
});
}
setType(e) {
let value = parseInt(e.target.value);
this.setState(() => ({
type: value
}));
}
setPosition(e) {
let value = e.target.value, arr = value.split(',');
let row = parseInt(arr[0]), col = parseInt(arr[1]);
this.setState(() => ({
position: {
row: row,
col: col,
rowCol: value
}
}))
}
_selectOption(select, value) {
if (select === 'line_type') {
this.setState(() => ({
type: value
}));
} else {
this.setState(() => ({
orientation: value
}));
}
}
getActualCellRange(cellRange, rowCount, columnCount) {
if (cellRange.row == -1 && cellRange.col == -1) {
return new GC.Spread.Sheets.Range(0, 0, rowCount, columnCount);
}
else if (cellRange.row == -1) {
return new GC.Spread.Sheets.Range(0, cellRange.col, rowCount, cellRange.colCount);
}
else if (cellRange.col == -1) {
return new GC.Spread.Sheets.Range(cellRange.row, 0, cellRange.rowCount, columnCount);
}
return cellRange;
};
initSpread(spread) {
this.spread = spread;
let sheet = this.spread.getSheet(0);
let self = this;
sheet.suspendPaint();
var data = [1,-2,-1,6,4,-4,3,8];
var dateAxis = [new Date(2011, 0, 5),new Date(2011, 0, 1),new Date(2011, 1, 11),new Date(2011, 2, 1),
new Date(2011, 1, 1),new Date(2011, 1, 3),new Date(2011, 2, 6),new Date(2011, 1, 19)];
sheet.setValue(0, 0, "Series 1");
sheet.setValue(0, 1, "Series 2");
for(let i=0;i<8;i++)
{
sheet.setValue(i+1, 0,data[i]);
sheet.getCell(i+1, 1).value(dateAxis[i]).formatter("yyyy-mm-dd");
}
sheet.setColumnWidth(1,100);
sheet.setValue(11, 0, "*Data Range is A2-A9");
sheet.setValue(12, 0, "*Date axis range is B2-B9");
var dataRange = new GC.Spread.Sheets.Range(1, 0, 8, 1);
var dateAxisRange = new GC.Spread.Sheets.Range(1, 1, 8, 1);
sheet.getCell(0, 5).text("Sparkline without dateAxis:");
sheet.getCell(1, 5).text("(1) Line");
sheet.getCell(1, 8).text("(2) Column");
sheet.getCell(1, 11).text("(3) Winloss");
sheet.getCell(7, 5).text("Sparkline with dateAxis:");
sheet.getCell(8, 5).text("(1) Line");
sheet.getCell(8, 8).text("(2) Column");
sheet.getCell(8, 11).text("(3) Winloss");
//sparkline settings
var setting = new GC.Spread.Sheets.Sparklines.SparklineSetting();
setting.options.showMarkers = true;
setting.options.lineWeight = 3;
setting.options.displayXAxis = true;
setting.options.showFirst = true;
setting.options.showLast = true;
setting.options.showLow = true;
setting.options.showHigh = true;
setting.options.showNegative = true;
//line
sheet.addSpan(2, 5, 4, 3);
sheet.setSparkline(2, 5, dataRange
, GC.Spread.Sheets.Sparklines.DataOrientation.vertical
, GC.Spread.Sheets.Sparklines.SparklineType.line
, setting
);
sheet.addSpan(9, 5, 4, 3);
sheet.setSparkline(9, 5, dataRange
, GC.Spread.Sheets.Sparklines.DataOrientation.vertical
, GC.Spread.Sheets.Sparklines.SparklineType.line
, setting
, dateAxisRange
, GC.Spread.Sheets.Sparklines.DataOrientation.vertical
);
//column
sheet.addSpan(2, 8, 4, 3);
sheet.setSparkline(2, 8, dataRange
, GC.Spread.Sheets.Sparklines.DataOrientation.vertical
, GC.Spread.Sheets.Sparklines.SparklineType.column
, setting
);
sheet.addSpan(9, 8, 4, 3);
sheet.setSparkline(9, 8, dataRange
, GC.Spread.Sheets.Sparklines.DataOrientation.vertical
, GC.Spread.Sheets.Sparklines.SparklineType.column
, setting
, dateAxisRange
, GC.Spread.Sheets.Sparklines.DataOrientation.vertical
);
//winloss
sheet.addSpan(2, 11, 4, 3);
sheet.setSparkline(2, 11, dataRange
, GC.Spread.Sheets.Sparklines.DataOrientation.vertical
, GC.Spread.Sheets.Sparklines.SparklineType.winloss
, setting
);
sheet.addSpan(9, 11, 4, 3);
sheet.setSparkline(9, 11, dataRange
, GC.Spread.Sheets.Sparklines.DataOrientation.vertical
, GC.Spread.Sheets.Sparklines.SparklineType.winloss
, setting
, dateAxisRange
, GC.Spread.Sheets.Sparklines.DataOrientation.vertical
);
sheet.bind(GC.Spread.Sheets.Events.SelectionChanged, selectionChangedCallback);
sheet.resumePaint();
function selectionChangedCallback() {
let sheet = spread.getActiveSheet();
let sparkline = sheet.getSparkline(sheet.getActiveRowIndex(), sheet.getActiveColumnIndex());
if (sparkline) {
updateSetting(sparkline);
} else {
initSetting();
}
}
function updateSetting(sparkline) {
let type = sparkline.sparklineType(), orientation = sparkline.dataOrientation(),
row = sparkline.row, column = sparkline.column;
self.setState(() => ({
position: {
row: row,
col: column,
rowCol: row + ',' + column
}
}));
self._selectOption('line_type', type);
self._selectOption('line_orientation', orientation);
}
function initSetting() {
self.setState(() => ({
position: {
row: '',
col: '',
rowCol: ''
}
}));
self._selectOption('line_type', 0);
self._selectOption('line_orientation', 0);
}
}
}
class Panel extends Component {
constructor(props) {
super(props);
}
render() {
const {panelInfo, setPosition, setOrientation, setType, addSprikline, clearSprikline} = this.props;
return (
<React.Fragment>
<div class="options-container">
<div class="option-group">
<label><b>Add SparkLine:</b></label>
</div>
<hr />
<div class="option-group">
<label>1. Select the data range in the sheet</label>
</div>
<div class="option-group">
<label for="line_position">2. Enter destination cell (row,column index)</label>
<input id="line_position" value={panelInfo.position.rowCol} onChange={(e) => { setPosition(e) }} />
</div>
<div class="option-group">
<label for="line_position">3. Change the type and orientation</label>
</div>
<div class="option-group">
<label for="line_type">Type:</label>
<select id="line_type" class="position" onChange={(e) => { setType(e) }}>
<option value="0" selected = {panelInfo.type === 0 ? "selected" : null}>line</option>
<option value="1" selected = {panelInfo.type === 1 ? "selected" : null}>column</option>
<option value="2" selected = {panelInfo.type === 2 ? "selected" : null}>winloss</option>
</select>
</div>
<div class="option-group">
<label for="line_orientation">Orientation:</label>
<select id="line_orientation" class="position" onChange={(e) => { setOrientation(e) }}>
<option value="0" selected = {panelInfo.orientation === 0 ? "selected" : null}>Vertical</option>
<option value="1" selected = {panelInfo.orientation === 1 ? "selected" : null}>Horizontal</option>
</select>
</div>
<div class="option-group">
<label for="line_position">4. Click "Add Sparkline" button</label>
</div>
<div class="option-group">
<input type="button" onClick={() => { addSprikline() }} value="Add Sparkline" id="btnAddSparkline" />
</div>
<br />
<div>
<label><b>Remove SparkLine:</b></label>
</div>
<hr />
<div class="option-group">
<label>1. Select Sparkline</label>
</div>
<div class="option-group">
<input type="button" onClick={() => { clearSprikline() }} value="Clear Sparkline" id="btnClearSparkline" />
</div>
</div>
</React.Fragment>
)
}
}
<!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$/zh/react/node_modules/@grapecity-software/spread-sheets/styles/gc.spread.sheets.excel2013white.css">
<!-- SystemJS -->
<script src="$DEMOROOT$/zh/react/node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.js"></script>
<script>
System.import('$DEMOROOT$/zh/lib/react/license.js').then(function() {
System.import('./src/app');
});
</script>
</head>
<body>
<div id="app" style="height: 100%;"></div>
</body>
</html>
.sample {
position: relative;
height: 100%;
overflow: auto;
}
.sample::after {
display: block;
content: "";
clear: both;
}
.sample-tutorial {
position: relative;
height: 100%;
overflow: hidden;
}
p{
padding:2px 10px;
background-color:#F4F8EB;
}
.sample-spreadsheets {
width: calc(100% - 280px);
height: 100%;
overflow: hidden;
float: left;
}
.options-container {
float: right;
width: 280px;
padding: 12px;
height: 100%;
box-sizing: border-box;
background: #fbfbfb;
overflow: auto;
}
.option-row {
font-size: 14px;
padding: 5px;
margin-top: 10px;
}
.option-group {
margin-bottom: 8px;
}
input,
select {
margin-top: 6px;
padding: 4px 4px;
width: 100%;
box-sizing: border-box;
}
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: {
'@grapecity-software/spread-sheets': 'npm:@grapecity-software/spread-sheets/index.js',
'@grapecity-software/spread-sheets-resources-zh': 'npm:@grapecity-software/spread-sheets-resources-zh/index.js',
'@grapecity-software/spread-sheets-react': 'npm:@grapecity-software/spread-sheets-react/index.js',
'@grapecity-software/jsob-test-dependency-package/react-components': 'npm:@grapecity-software/jsob-test-dependency-package/react-components/index.js',
'react': 'npm:react/umd/react.production.min.js',
'react-dom': 'npm:react-dom/umd/react-dom.production.min.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);