SpreadJS PivotTables provide the ShowDataAs API to quickly present values in different ways.
There are 14 kinds of ShowDataAs options are available.
Show Data As name
Enum Value
Show Data As Info Required Properties
No Calculation
normal
showDataAs
% of Grand Total
percentOfTotal
showDataAs
% of Column Total
percentOfRow
showDataAs
% of Row Total
percentOfCol
showDataAs
% Of
percent
showDataAs, baseFieldName, baseFieldItemType, baseFieldItem?
% of Parent Row Total
percentOfParentRow
showDataAs
% of Parent Column Total
percentOfParentCol
showDataAs
% of Parent Total
percentOfParent
showDataAs, baseFieldName
Difference From
difference
showDataAs, baseFieldName, baseFieldItemType, baseFieldItem?
% Difference From
percentDiff
showDataAs, baseFieldName, baseFieldItemType, baseFieldItem?
Running Total in
runTotal
showDataAs, baseFieldName
% Running Total in
percentOfRunningTotal
showDataAs, baseFieldName
Rank Smallest to Largest
rankAscending
showDataAs, baseFieldName
Rank Largest to Smallest
rankDescending
showDataAs, baseFieldName
Index
index
showDataAs
Sample:
<template>
<div class='sample-tutorial'>
<gc-spread-sheets class="sample-spreadsheets" @workbookInitialized="initSpread">
<gc-worksheet>
</gc-worksheet>
<gc-worksheet>
</gc-worksheet>
</gc-spread-sheets>
<div class="options-container">
<div class="option-row">
<label>ShowValueAs:</label>
<select id="showValueAs" v-model="showValueAsValue" @change="showValueAsHandle">
<option value='0'>No Calculation</option>
<option value='1'>% of Grand Total</option>
<option value='2'>% of Column Total</option>
<option value='3'>% of Row Total</option>
<option value='4'>% Of ...</option>
<option value='5'>% of Parent Row Total</option>
<option value='6'>% of Parent Column Total</option>
<option value='7'>% of Parent Total ...</option>
<option value='8'>Difference From ...</option>
<option value='9'>% Of Difference From ...</option>
<option value='10'>Running Total In ...</option>
<option value='11'>% Running Total In ...</option>
<option value='12'>Rank Smallest to Largest ...</option>
<option value='13'>Rank Largest to Smallest ...</option>
<option value='14'>Index</option>
</select>
</div>
<div class="option-row" v-if="showBaseField">
<label style="padding: 5px, marginTop: 10px" id="showValueAsDialogLabel" v-bind:value="baseFieldLabel">{{baseFieldLabel}}</label>
<select v-model="showValueAsBaseFieldValue" @change="baseFieldListHandle">
<option v-for="(item, index) in baseFieldList" v-bind:key="item.fieldName" v-bind:value="index">{{item.fieldName}}</option>
</select>
</div>
<div class="option-row" v-if="showBaseItem">
<label id="showValueAsBaseItemLabel">Base Item:</label>
<select v-model="showValueAsBaseItemValue">
<option v-for="(item, index) in baseItemList" v-bind:key="item" v-bind:value="index">{{item}}</option>
</select>
</div>
<div class="option-row">
<input type="button" value="Apply Setting" id="applySetting" @click="applySettingHandle" />
</div>
</div>
</div>
</template>
<script>
import Vue from "vue";
import "@mescius/spread-sheets-vue";
import GC from "@mescius/spread-sheets";
import "@mescius/spread-sheets-shapes";
import "@mescius/spread-sheets-pivot-addon";
import "./styles.css";
let App = Vue.extend({
name: "app",
data: function () {
return {
spread: null,
pt: null,
showValueAsBaseFieldValue: "0",
baseFieldList: [],
showBaseField: false,
showBaseItem: false,
baseItemList: [],
baseFieldLabel: "Calculation: ",
showValueAsValue: "0",
showValueAsBaseItemValue: "0"
}
},
methods: {
initSpread: function (spread) {
spread.suspendPaint();
this.spread = spread;
let sheet1 = spread.getSheet(0);
let sheet2 = spread.getSheet(1);
let tableName = this.getDataSource(sheet2, pivotSales);
let pivotTable = this.initPivotTable(sheet1, tableName);
this.pt = pivotTable;
spread.resumePaint();
return pivotTable;
},
getDataSource: function (sheet, tableSource) {
sheet.name("DataSource");
sheet.setRowCount(117);
sheet.setColumnWidth(0, 120);
sheet.getCell(-1, 0).formatter("YYYY-mm-DD");
sheet.getRange(-1,4,0,2).formatter("$ #,##0");
let table = sheet.tables.add('table', 0, 0, 117, 6);
for(let i=2;i<=117;i++)
{
sheet.setFormula(i-1,5,'=D'+i+'*E'+i)
}
table.style(GC.Spread.Sheets.Tables.TableThemes["none"]);
sheet.setArray(0, 0, tableSource);
return table.name();
},
initPivotTable: function (sheet, source) {
sheet.name("ShowDataAs");
sheet.setRowCount(1000);
let option = {
showRowHeader:true,
showColumnHeader:true,
bandRows:true,
bandColumns:true
};
let pivotTable = sheet.pivotTables.add("pivotTable", source, 1, 1, GC.Spread.Pivot.PivotTableLayoutType.outline, GC.Spread.Pivot.PivotTableThemes.medium8,option);
pivotTable.suspendLayout();
pivotTable.add("salesperson", "Salesperson", GC.Spread.Pivot.PivotTableFieldType.rowField);
pivotTable.add("car", "Cars", GC.Spread.Pivot.PivotTableFieldType.rowField);
let groupInfo = { originFieldName: "date", dateGroups: [{ by: GC.Pivot.DateGroupType.quarters }] };
pivotTable.group(groupInfo);
pivotTable.add("Quarters (date)", "Quarters (date)", GC.Spread.Pivot.PivotTableFieldType.columnField);
pivotTable.add("total", "Totals", GC.Spread.Pivot.PivotTableFieldType.valueField, GC.Pivot.SubtotalType.sum);
pivotTable.resumeLayout();
pivotTable.autoFitColumn();
return pivotTable;
},
showValueAsHandle: function (e) {
this.showBaseField = false;
this.showBaseItem = false;
this.baseFieldLabel = "Calculation: ";
let selectIndex = e.target.value;
this.showValueAsValue = selectIndex;
if (["4", "7", "8", "9", "10", "11", "12", "13"].indexOf(selectIndex) > -1) {
this.showBaseField = true;
let baseField = [...this.pt.getFieldsByArea(1), ...this.pt.getFieldsByArea(2)];
this.baseFieldLabel = ("Calculation: " + e.target.selectedOptions[0].text);
this.baseFieldList = baseField;
if (["4", "8", "9"].indexOf(selectIndex) > -1) {
this.showBaseItem = true;
let text = baseField[parseInt(this.showValueAsBaseFieldValue)].fieldName;
let baseItems = [...this.pt.getItemsByField(text)];
baseItems.unshift("next");
baseItems.unshift("previous");
this.baseItemList = baseItems;
}
}
},
applyShowDataAsStyle(pivotTable, fieldName, showValueAsType) {
let style, valueFieldArea = {
dataOnly: true,
references: [{
fieldName: "Values",
items: [fieldName]
}]
};
style = pivotTable.getStyle(valueFieldArea);
if (!style) {
style = new GC.Spread.Sheets.Style();
}
let needApplyStyle = [GC.Pivot.PivotShowDataAs.percentOfTotal, GC.Pivot.PivotShowDataAs.percentOfRow, GC.Pivot.PivotShowDataAs.percentOfCol, GC.Pivot.PivotShowDataAs.percent, GC.Pivot.PivotShowDataAs.percentOfParentRow,
GC.Pivot.PivotShowDataAs.percentOfParentCol, GC.Pivot.PivotShowDataAs.percentOfParent, GC.Pivot.PivotShowDataAs.percentDiff, GC.Pivot.PivotShowDataAs.percentOfRunningTotal
].indexOf(showValueAsType) > -1;
if (needApplyStyle) {
style.formatter = "0.00%";
} else {
style = null;
}
pivotTable.setStyle(valueFieldArea, style);
},
applySettingHandle: function () {
let showValueAsValue = parseInt(this.showValueAsValue, 10);
let valueFieldName = this.pt.getFieldsByArea(3)[0].fieldName;
if (this.showBaseField && this.showBaseItem) {
let fileName = this.baseFieldList[parseInt(this.showValueAsBaseFieldValue)].fieldName;
let baseFieldItem = this.baseItemList[parseInt(this.showValueAsBaseItemValue)];
if (this.showValueAsBaseItemValue === "0") {
this.pt.showDataAs(valueFieldName, {
showDataAs: showValueAsValue,
baseFieldName: fileName,
baseFieldItemType: 2
});
} else if (this.showValueAsBaseItemValue === "1") {
this.pt.showDataAs(valueFieldName, {
showDataAs: showValueAsValue,
baseFieldName: fileName,
baseFieldItemType: 1
});
} else {
this.pt.showDataAs(valueFieldName, {
showDataAs: showValueAsValue,
baseFieldName: fileName,
baseFieldItemType: 0,
baseFieldItem: baseFieldItem
});
}
} else if (this.showBaseField) {
let fileName = this.baseFieldList[parseInt(this.showValueAsBaseFieldValue)].fieldName;
this.pt.showDataAs(valueFieldName, {
showDataAs: showValueAsValue,
baseFieldName: fileName
});
} else {
this.pt.showDataAs(valueFieldName, {
showDataAs: showValueAsValue
});
}
this.applyShowDataAsStyle(this.pt, valueFieldName, showValueAsValue);
},
baseFieldListHandle: function (e) {
let text = this.baseFieldList[parseInt(this.showValueAsBaseFieldValue)].fieldName;
let baseItems = [...this.pt.getItemsByField(text)];
baseItems.unshift("next");
baseItems.unshift("previous");
this.baseItemList = baseItems;
}
}
});
new Vue({
render: (h) => h(App)
}).$mount("#app");
</script>
<!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/vue/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css">
<script src="$DEMOROOT$/spread/source/data/pivot-data.js" type="text/javascript"></script>
<!-- SystemJS -->
<script src="$DEMOROOT$/en/vue/node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.js"></script>
<script>
System.import('./src/app.vue');
System.import('$DEMOROOT$/en/lib/vue/license.js');
</script>
</head>
<body>
<div id="app"></div>
</body>
</html>
.sample-tutorial {
position: relative;
height: 100%;
overflow: hidden;
}
.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;
}
p{
padding:2px 10px;
background-color:#F4F8EB;
}
input, select {
width: 100%;
padding: 4px 6px;
box-sizing: border-box;
}
label {
display:block;
margin-bottom: 6px;
}
input[type="checkbox"], input[type="radio"] {
display: inline-block;
width: auto;
}
input[type="checkbox"]+label, input[type="radio"]+label {
display: inline-block;
}
input[type="button"] {
display: block;
margin: 0 0 6px;
}
body {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
(function (global) {
System.config({
transpiler: 'plugin-babel',
babelOptions: {
es2015: true
},
meta: {
'*.css': { loader: 'css' },
'*.vue': { loader: 'vue-loader' }
},
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-shapes': 'npm:@mescius/spread-sheets-shapes/index.js',
'@mescius/spread-sheets-pivot-addon': 'npm:@mescius/spread-sheets-pivot-addon/index.js',
'@mescius/spread-sheets-vue': 'npm:@mescius/spread-sheets-vue/index.js',
'@grapecity/jsob-test-dependency-package/react-components': 'npm:@grapecity/jsob-test-dependency-package/react-components/index.js',
'jszip': 'npm:jszip/dist/jszip.js',
'css': 'npm:systemjs-plugin-css/css.js',
'vue': 'npm:vue/dist/vue.min.js',
'vue-loader': 'npm:systemjs-vue-browser/index.js',
'tiny-emitter': 'npm:tiny-emitter/index.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: 'js'
},
rxjs: {
defaultExtension: 'js'
},
"node_modules": {
defaultExtension: 'js'
}
}
});
})(this);