JSFiddle - React, Tailwind, and code Playground
by Flexmonster Pivot Table
HTML
<script src="https://cdn.flexmonster.com/flexmonster.js">
</script>
<div id="pivot-container"></div>
CSS
.hide-exclude-popup {
display: none !important;
}
body {
font-family: sans-serif;
}
#backdrop {
z-index: 199;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(255, 255, 255, 0.7);
}
#pivot-container .fm-grand-total-c{
background-color: #f7f7f7 !important;
}
#exclude-popup {
width: 60%;
left: 20%;
top: 20%;
}
#pivot-container #exclude-popup #fm-popup-title-text {
text-overflow: unset;
}
#pivot-container #exclude-popup .fm-popup-content {
display: flex !important;
flex-direction: column !important;
}
#pivot-container #exclude-popup #exclude-members-list {
margin-top: 30px;
overflow: auto;
max-height: 300px;
}
#pivot-container #exclude-popup #exclude-members-list h4 {
font-size: 18px;
padding: 20px 5px;
}
#pivot-container #exclude-popup #exclude-members-list .filter-item {
display: flex;
justify-content: space-between;
flex-direction: row;
align-items: center;
user-select: none;
border-bottom: 1px dashed #d5d5d5;
}
#pivot-container #exclude-popup #exclude-members-list .filter-item label {
cursor: pointer !important;
width: 100%;
padding-block: 12px;
padding-inline: 15px;
}
#pivot-container #exclude-popup #exclude-members-list .filter-item div {
display: flex;
justify-content: flex-start;
flex-direction: row;
align-items: center;
}
#pivot-container #exclude-popup #exclude-members-list .filter-name {
display: inline-block;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
font-size: 15px;
padding-block: 12px;
}
#pivot-container #exclude-popup #exclude-members-list .filter-checkbox {
float: right;
cursor: pointer;
-webkit-appearance: none;
appearance: none;
background-color: #fff;
margin: 0;
font: inherit;
color: #555;
width: 1.15em;
height: 1.15em;
border: 0.15em solid #555;
border-radius: 0.15em;
...
JavaScript
let sliceForGetData;
/*jshint esversion: 6 */
let pivot = new Flexmonster({
container: "pivot-container",
componentFolder: "https://cdn.flexmonster.com/",
licenseFilePath: "https://cdn.flexmonster.com/jsfiddle.charts.key",
height: 550,
toolbar: true,
reportcomplete: sliceChangeObserver,
reportchange: sliceChangeObserver,
report: {
dataSource: {
filename: "https://cdn.flexmonster.com/data/data.json",
},
slice: {
rows: [
{
uniqueName: "Category",
},
],
columns: [
{
uniqueName: "Country",
},
{
uniqueName: "[Measures]",
},
],
measures: [
{
uniqueName: "Price per unit",
formula: "sum('Price') / sum('Quantity')",
individual: false,
},
],
},
formats: [
{
name: "",
decimalPlaces: 2,
thousandsSeparator: ",",
},
],
},
});
//Observer slice changes, to keep filters up to date, but load a different measure
function sliceChangeObserver() {
const currentSlice = pivot.getReport().slice;
delete currentSlice["measures"];
sliceForGetData = {
...currentSlice,
measures: [{ uniqueName: "Price" }], // your hardcoded measure
};
console.log(sliceForGetData);
pivot.getData(
{
slice: sliceForGetData,
},
updateTotals,
updateTotals,
);
}
function updateTotals(chartData) {
let data = chartData.data;
//Grand totals from the bottom row per each column
let grandTotalRows = data
.filter((obj) => !("r0" in obj) && "c0" in obj && "v0" in obj)
.map((obj) => obj.v0);
//Total sum of price per each row
let grandTotalColumns = data
.filter((obj) => "r0" in obj && !("c0" in obj) && "v0" in obj)
.map((obj) => obj.v0);
//Grand total at bottom right cell
let grandTotal = data
.filter((obj) => !("r0" in obj) &&...