Skip to content

Commit

Permalink
Add sorting-data demo
Browse files Browse the repository at this point in the history
  • Loading branch information
sequba committed Oct 8, 2024
1 parent dfad1b0 commit 41d1ae7
Show file tree
Hide file tree
Showing 5 changed files with 441 additions and 4 deletions.
100 changes: 100 additions & 0 deletions docs/examples/sorting-data/example1.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
.example {
color: #606c76;
font-family: 'Roboto', 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;
font-size: 14px;
font-weight: 300;
letter-spacing: .01em;
line-height: 1.6;
}

.example button {
border: 0.1em solid #1c49e4;
border-radius: .3em;
color: #fff;
cursor: pointer;
display: inline-block;
font-size: .85em;
font-weight: 700;
height: 3em;
letter-spacing: .1em;
line-height: 3em;
padding: 0 3em;
text-align: center;
text-decoration: none;
text-transform: uppercase;
white-space: nowrap;
margin-bottom: 20px;
background-color: #1c49e4;
}

.example button:hover {
background-color: #2350ea;
}

.example button.outline {
background-color: transparent;
color: #1c49e4;
}

.example label {
display: inline-block;
margin-left: 5px;
}

.example table tbody tr {
counter-increment: row-counter;
}

.example table thead tr th span {
counter-increment: col-counter;
}


.example table tbody tr td:first-child {
text-align: center;
padding: 0;
}

.example table {
table-layout: fixed;
}

.example table tbody tr td,
.example table tbody tr th {
overflow: hidden;
text-overflow: ellipsis;
}

.example table thead tr th:first-child {
padding-left: 40px;
}

.example table tbody tr td:first-child span {
width: 100%;
display: inline-block;
text-align: left;
padding-left: 15px;
margin-left: 0;
}

.example table tbody tr td:first-child span::before {
content: counter(row-counter);
display: inline-block;
width: 20px;
position: relative;
left: -10px;
}

.example table tbody tr td.updated-cell span {
animation-name: cell-appear;
animation-duration: 0.6s;
}

@keyframes cell-appear {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
18 changes: 18 additions & 0 deletions docs/examples/sorting-data/example1.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<div class="example">
<table>
<colgroup>
<col style="width:50%" />
<col style="width:50%" />
</colgroup>
<thead>
<tr>
<th>Name</th>
<th>
Score <button id="asc" class="button arrow">&uarr;</button>
<button id="desc" class="button arrow">&darr;</button>
</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
155 changes: 155 additions & 0 deletions docs/examples/sorting-data/example1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
/* start:skip-in-compilation */
import HyperFormula from 'hyperformula';

/* end:skip-in-compilation */
console.log(
`%c Using HyperFormula ${HyperFormula.version}`,
'color: blue; font-weight: bold'
);

/**
* Initial table data.
*/
const tableData = [
['Greg Black', '100'],
['Anne Carpenter', '=SUM(100,100)'],
['Natalie Dem', '500'],
['John Sieg', '50'],
['Chris Aklips', '20'],
['Bart Hoopoe', '700'],
['Chris Site', '80'],
['Agnes Whitey', '90'],
];

// Create an empty HyperFormula instance.
const hf = HyperFormula.buildEmpty({
licenseKey: 'gpl-v3',
});

// Add a new sheet and get its id.
const sheetName = hf.addSheet('main');
const sheetId = hf.getSheetId(sheetName);

// Fill the HyperFormula sheet with data.
hf.setCellContents(
{
row: 0,
col: 0,
sheet: sheetId,
},
tableData
);

/**
* Sort the HF's dataset.
*
* @param {boolean} ascending `true` if sorting in ascending order, `false` otherwise.
* @param {Function} callback The callback function.
*/
function sort(ascending, callback) {
const rowCount = hf.getSheetDimensions(sheetId).height;
const colValues = [];
let newOrder = null;
let newOrderMapping = [];

for (let rowIndex = 0; rowIndex < rowCount; rowIndex++) {
colValues.push({
rowIndex,
value: hf.getCellValue({
sheet: sheetId,
col: 1,
row: rowIndex,
}),
});
}

colValues.sort((objA, objB) => {
const delta = objA.value - objB.value;

return ascending ? delta : -delta;
});
newOrder = colValues.map((el) => el.rowIndex);
newOrder.forEach((orderIndex, arrIndex) => {
newOrderMapping[orderIndex] = arrIndex;
});
hf.setRowOrder(sheetId, newOrderMapping);
callback();
}

/**
* Fill the HTML table with data.
*
* @param {boolean} calculated `true` if it should render calculated values, `false` otherwise.
*/
function renderTable(calculated = false) {
const tbodyDOM = document.querySelector('.example tbody');
const updatedCellClass = ANIMATION_ENABLED ? 'updated-cell' : '';
const { height, width } = hf.getSheetDimensions(sheetId);
let newTbodyHTML = '';

for (let row = 0; row < height; row++) {
for (let col = 0; col < width; col++) {
const cellAddress = { sheet: sheetId, col, row };
const cellHasFormula = hf.doesCellHaveFormula(cellAddress);
const showFormula = calculated || !cellHasFormula;
let cellValue = '';

if (!hf.isCellEmpty(cellAddress) && showFormula) {
cellValue = hf.getCellValue(cellAddress);
} else {
cellValue = hf.getCellFormula(cellAddress);
}

newTbodyHTML += `<td class="${
cellHasFormula ? updatedCellClass : ''
}"><span>
${cellValue}
</span></td>`;
}

newTbodyHTML += '</tr>';
}

tbodyDOM.innerHTML = newTbodyHTML;
}

/**
* Replace the values in the table with initial data.
*/
function resetTable() {
renderTable();
}

const doSortASC = () => {
sort(true, () => {
renderTable(true);
});
};

const doSortDESC = () => {
sort(false, () => {
renderTable(true);
});
};

/**
* Bind the events to the buttons.
*/
function bindEvents() {
const ascSort = document.querySelector('#asc');
const descSort = document.querySelector('#desc');

ascSort.addEventListener('click', () => {
doSortASC();
});
descSort.addEventListener('click', () => {
doSortDESC();
});
}

const ANIMATION_ENABLED = true;

// Bind the button events.
bindEvents();
// Render the table.
renderTable();
Loading

0 comments on commit 41d1ae7

Please sign in to comment.