Pivot Conditional Rules

You can apply, get, and remove conditional formatting rules in a pivot area. The conditional rules work as expected irrespective of the changes to PivotTable layout.

The following demo applies different color formatting depending on the cell values, with green being the lowest and red the highest.

PivotTable offers the ability to set conditional rules to specific dimensions. No matter how the PivotTable layout changes, the conditional rules are only applied the specified dimensions. Add a conditionalRule with the setConditionalRule API Get a conditionalRule with the getConditionalRulee API Remove a conditionalRule with the removeConditionalRule API
<template> <div class="sample-tutorial"> <gc-spread-sheets class="sample-spreadsheets" @workbookInitialized="initSpread"> </gc-spread-sheets> <div id="container" class="options-container"> <div class="option-row"> <label><b>Settings:</b> </label> </div> <hr> <div class="option-row"> <label>Click the MoveNext or MovePrev buttons to apply the conditional rule to the Salesperson above or below the currently highlighted dimension. </label> </div> <input type="button" value="MovePrev" class="set-option" id="switch-region-up" @click="switchRegionUp()" /> <br /> <input type="button" value="MoveNext" class="set-option" id="switch-region-down" @click="switchRegionDown()" /> <br /> <hr> <div class="option-row"> <label>Change the dropdown menu below to see how changing pivot table layout affects the conditional rules. </label> </div> <br /> <div class="option-row"> <select id="layoutType" @change="switchLayoutType($event)"> <option value="0">Compact Form</option> <option value="1" selected>Outline Form</option> <option value="2">Tabular Form</option> </select> </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, pivotTable: null }; }, methods: { initSpread: function (spread) { this.spread = spread; this.scaleRule = new GC.Spread.Sheets.ConditionalFormatting.ScaleRule(11, 1 , 0, "#82bc00", 0 , 40000, "#f7ea00", 2 , 100000, "#e45d5d"); this.names = ['Alan', "Bob", "John", "Serena", "Tess"]; this.namesCount = this.names.length; this.currentIndex = 0; spread.suspendPaint(); spread.setSheetCount(2); let sheet1 = spread.getSheet(0); let sheet2 = spread.getSheet(1); let tableName = this.getDataSource(sheet2, pivotSales); let pivotTable = this.initPivotTable(sheet1, tableName); this.pivotTable = pivotTable; spread.resumePaint(); }, getCurrentPivotAreas () { return [ { dataOnly: true, references: [{ fieldName: "Salesperson", items: [this.names[this.currentIndex % this.namesCount]] }, { fieldName: "Cars" }] } ]; }, getNextPivotAreas () { this.currentIndex++; return this.getCurrentPivotAreas(); }, getPreviousPivotAreas () { if (this.currentIndex === 0) { this.currentIndex = this.namesCount * 10; } this.currentIndex--; return this.getCurrentPivotAreas(); }, switchRegionUp () { let pivotTable = this.pivotTable; this.spread.suspendPaint(); pivotTable.removeConditionalRule(this.scaleRule); pivotTable.addConditionalRule(this.getPreviousPivotAreas(), this.scaleRule); this.spread.resumePaint(); }, switchRegionDown () { let pivotTable = this.pivotTable; this.spread.suspendPaint(); pivotTable.removeConditionalRule(this.scaleRule); pivotTable.addConditionalRule(this.getNextPivotAreas(), this.scaleRule); this.spread.resumePaint(); }, 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("PivotTable"); sheet.setRowCount(1000); let pivotTableOptions = {bandRows:true,bandColumns:true}; let pivotTable = sheet.pivotTables.add("PivotTable", source, 1, 1, GC.Spread.Pivot.PivotTableLayoutType.outline, GC.Spread.Pivot.PivotTableThemes.light8, pivotTableOptions); 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); let pivotArea = { dataOnly: true, references: [{fieldName: "Salesperson", items:["Alan"]}, {fieldName: "Cars"}]}; pivotTable.addConditionalRule([pivotArea], this.scaleRule); let style = new GC.Spread.Sheets.Style(); style.formatter = "$ #,##0"; pivotTable.setStyle({dataOnly: true}, style); pivotTable.resumeLayout(); pivotTable.autoFitColumn(); return pivotTable; }, switchLayoutType: function (e) { let spread = this.spread; if (spread) { let type = parseInt(e.target.value, 10); this.pivotTable.layoutType(type); this.pivotTable.autoFitColumn(); } } }, computed: { dataSource() { return getData(); }, }, }); 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% - 300px); height: 100%; overflow: hidden; float: left; } .options-container { float: right; width: 300px; padding: 12px; height: 100%; box-sizing: border-box; background: #fbfbfb; overflow: auto; } body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; } .set-option { display: block; margin-top: 20px; width: 250px; } #reportFilterFieldsPerColumn { width: 28px; } .select-option-class{ display: block; margin-top: 20px; margin-bottom: 10px } .select-option-select{ width: 250px; display: block; margin-bottom: 20px; } .option-item{ height: 20px; margin-bottom: 10px; }
(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);