diff --git a/src/components/search_selector.ts b/src/components/search_selector.ts index c5b3a54e..b903e8ca 100644 --- a/src/components/search_selector.ts +++ b/src/components/search_selector.ts @@ -4,7 +4,7 @@ export class SearchSelector { searchResults: Set searchResultsElem: HTMLFieldSetElement - display: Set + selectedItems: Set displayElem: HTMLFieldSetElement convertToString: (a: A) => string @@ -28,7 +28,7 @@ export class SearchSelector { editLabel: (a: A, label: HTMLLabelElement) => HTMLLabelElement, redraw: () => void ) { - this.display = new Set() + this.selectedItems = new Set() this.searchResults = new Set() this.convertToString = convertToString this.editLabel = editLabel @@ -109,7 +109,7 @@ export class SearchSelector { candidates.forEach((a) => this.searchResults.add(a)) // remove anything currently displayed - this.display.forEach((a) => this.searchResults.delete(a)) + this.selectedItems.forEach((a) => this.searchResults.delete(a)) // Clear existing buttons while (this.searchResultsElem.firstChild) { @@ -129,14 +129,14 @@ export class SearchSelector { addSelected(a: A, redraw: boolean = true): void { this.addDiv(a); - this.display.add(a); + this.selectedItems.add(a); if(redraw) this.redraw(); this.updateSearchResults(); } removeSelected(a: A, redraw: boolean = true): void { this.displayElem.removeChild(document.getElementById(this.convertToString(a))!); - this.display.delete(a); + this.selectedItems.delete(a); if(redraw) this.redraw(); this.updateSearchResults(); }; @@ -171,14 +171,14 @@ export class SearchSelector { } clearSelection(redraw: boolean = true): void { - this.display.forEach((a) => this.removeSelected(a, false)); + this.selectedItems.forEach((a) => this.removeSelected(a, false)); if(redraw) this.redraw(); this.updateSearchResults() } selectAll(redraw: boolean = true): void { Array.from(this.allValues) - .filter(a => !this.display.has(a)) + .filter(a => !this.selectedItems.has(a)) .forEach(a => this.addSelected(a, false)); if(redraw) this.redraw(); diff --git a/src/components/table.ts b/src/components/table.ts new file mode 100644 index 00000000..10b4c5e2 --- /dev/null +++ b/src/components/table.ts @@ -0,0 +1,93 @@ +import { metricColor } from "../ui"; + +type RowContent = string | number | boolean +type Range = {min: number, max: number} + +export class Table { + tableElem: HTMLTableElement; + + headers: string[]; + rows: RowContent[][]; + ranges: Map; + + constructor(tableElemId: string, ranges: Map, headers: string[], rows: RowContent[][]) { + this.tableElem = document.getElementById(tableElemId) as HTMLTableElement; + this.headers = headers; + this.rows = rows; + this.ranges = ranges; + } + + setHeaders(headers: string[]) { + this.headers = headers; + } + + setRows(rows: RowContent[][]) { + this.rows = rows; + } + + addRow(row: RowContent[]) { + this.rows.push(row); + } + + redraw() { + this.tableElem.innerHTML = ""; + + const table = document.createElement("table"); + table.className = "table"; + + const head = document.createElement("thead"); + const headRow = document.createElement("tr"); + + let first = false; + + this.headers.forEach(header => { + let headerCol = document.createElement("th"); + let headerDiv = document.createElement("div"); + let headerSpan = document.createElement("span"); + + if(!first) headerCol.className = "rotated-text"; + + headerCol.scope = "col"; + + headerSpan.innerHTML = header; + headerSpan.className = "border-bottom"; + + + headerDiv.appendChild(headerSpan); + headerCol.appendChild(headerDiv); + headRow.appendChild(headerCol); + + first = false; + }); + head.appendChild(headRow); + table.appendChild(head); + + this.rows.forEach(rowData => { + let row = document.createElement("tr"); + + let firstCell = document.createElement("th"); + firstCell.innerHTML = rowData[0].toString(); + firstCell.scope = "row"; + firstCell.className = "border w-25"; + row.appendChild(firstCell); + + var i = 1; + this.headers.forEach(header => { + let range = this.ranges.get(header)!; + let data = rowData[i] as number; + let cellContent: string = Math.round(data).toString(); + + let cell = document.createElement("td"); + + cell.innerHTML = cellContent; + cell.className = "border"; + cell.style.backgroundColor = metricColor(data, unitStats.get(category)!); + + row.appendChild(cell); + i++; + }); + table.appendChild(row); + }); + tableElem.appendChild(table); + } +} \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index 58abe316..d1c8b922 100644 --- a/src/main.ts +++ b/src/main.ts @@ -81,7 +81,7 @@ function chartData( return { labels: [...sortedCategories], - datasets: [...weaponSelector.display].map((w) => { + datasets: [...weaponSelector.selectedItems].map((w) => { return { label: w.name, data: [...sortedCategories].map((c) => { @@ -130,7 +130,7 @@ const radar: Chart = new Chart( }, }, }, - data: chartData(stats, categorySelector.display, unitStats, false), + data: chartData(stats, categorySelector.selectedItems, unitStats, false), } ); @@ -167,7 +167,7 @@ function redrawBars() { bars.splice(0, bars.length); - categorySelector.display.forEach((c) => { + categorySelector.selectedItems.forEach((c) => { const outer = document.createElement("div"); outer.className = "col-md-4"; outer.id = c + "-bar"; @@ -178,8 +178,8 @@ function redrawBars() { }); } -function redrawTable(dataset: WeaponStats, unitStats: UnitStats) { - let sortedCategories = Array.from(categorySelector.display); +function redrawTable(dataset: WeaponStats, unitStats: UnitStats, ) { + let sortedCategories = Array.from(categorySelector.selectedItems); sortedCategories.sort((a,b) => { return Object.values(MetricLabel).indexOf(a) - Object.values(MetricLabel).indexOf(b); }); @@ -193,8 +193,6 @@ function redrawTable(dataset: WeaponStats, unitStats: UnitStats) { const head = document.createElement("thead"); const headRow = document.createElement("tr"); - - let headers = [""]; // Leave name column blank sortedCategories.forEach((c) => { headers.push(c); @@ -225,7 +223,7 @@ function redrawTable(dataset: WeaponStats, unitStats: UnitStats) { head.appendChild(headRow); table.appendChild(head); - weaponSelector.display.forEach(weapon => { + weaponSelector.selectedItems.forEach(weapon => { let weaponData = dataset.get(weapon.name)!; let row = document.createElement("tr"); @@ -260,9 +258,9 @@ function redraw() { stats = generateMetrics(ALL_WEAPONS, numberOfTargets, horsebackDamageMultiplier, selectedTarget) unitStats = unitGroupStats(stats); - let weaponArray = Array.from(weaponSelector.display) + let weaponArray = Array.from(weaponSelector.selectedItems) const INDEX_POSTITIONS: Map> = new Map() - const indexCategories = Array.from(categorySelector.display).filter(c => c.startsWith("Index")) + const indexCategories = Array.from(categorySelector.selectedItems).filter(c => c.startsWith("Index")) indexCategories.forEach((c) => { const sortedWeapons = weaponArray.sort((a,b) => { @@ -279,14 +277,14 @@ function redraw() { const value = stats.get(w.name)!.get(c)!.value const idx = INDEX_POSTITIONS.get(c)!.indexOf(w.name); value.rawResult = idx + 1; - value.result = weaponSelector.display.size - idx; + value.result = weaponSelector.selectedItems.size - idx; }); - unitStats.get(c)!.max = weaponSelector.display.size; + unitStats.get(c)!.max = weaponSelector.selectedItems.size; unitStats.get(c)!.min = 1; }); - radar.data = chartData(stats, categorySelector.display, unitStats, false); + radar.data = chartData(stats, categorySelector.selectedItems, unitStats, false); radar.update(); redrawBars(); @@ -297,8 +295,8 @@ function redraw() { params.set("target", selectedTarget); params.set("numberOfTargets", numberOfTargets.toString()); params.set("tab", selectedTab); - params.append("weapon", [...weaponSelector.display].map(x => x.id).join("-")); - [...categorySelector.display].map((c) => params.append("category", c)); + params.append("weapon", [...weaponSelector.selectedItems].map(x => x.id).join("-")); + [...categorySelector.selectedItems].map((c) => params.append("category", c)); window.history.replaceState(null, "", `?${params.toString()}`); } @@ -410,7 +408,7 @@ if (params.getAll("category").length) { compatCategories.forEach(c => categorySelector.addSelected(c as MetricLabel)) // Setting them failed, so just default - if (!categorySelector.display.size) + if (!categorySelector.selectedItems.size) reset(); } else { reset();