From eb3d17884a393f9e12e76054018ac6fb9b6149ac Mon Sep 17 00:00:00 2001 From: Sam Date: Mon, 23 Sep 2024 20:11:25 +0100 Subject: [PATCH] working filter system --- content/data-lab/global-business-growth.md | 6 +- layouts/partials/chart.html | 49 ++++++------ layouts/partials/table.html | 87 +++++++++++----------- layouts/shortcodes/chart.html | 2 +- layouts/shortcodes/dropdown_filter.html | 6 +- layouts/shortcodes/table.html | 4 +- static/js/lib/helper-functions.js | 2 +- 7 files changed, 77 insertions(+), 79 deletions(-) diff --git a/content/data-lab/global-business-growth.md b/content/data-lab/global-business-growth.md index 94b9d19..e24e758 100644 --- a/content/data-lab/global-business-growth.md +++ b/content/data-lab/global-business-growth.md @@ -15,10 +15,10 @@ You can select the growth period of interest from the drop-down, which updates t The chart always reflects the countries selected in the table.
-{{< dropdown_filter id="days_ago" options="1 day:1,7 day:7,28 day:28,1 year:365,5 year:1826,10 year:3652,all time:10000" default_selection="7 day" >}} -{{< table id="bitcoin_business_growth" endpoint="bitcoin_business_growth_percent_diff" headers="{'country_name': 'Country', 'date_range': 'Date Range', 'last_value': 'Previous #', 'first_value': 'Current #', 'difference': 'Diff', 'percent_difference': '% Diff'}" maxHeight="400px" sortable="true" valueId="country_name" selectableRows="multi" >}} +{{< dropdown_filter id="days_ago_dropdown_filter" id_filter="days_ago" options="1 day:1,7 day:7,28 day:28,1 year:365,5 year:1826,10 year:3652,all time:10000" default_selection="7 day" targets="bitcoin-business-growth-chart bitcoin-business-growth-table" >}} +{{< table id="bitcoin-business-growth-table" endpoint="bitcoin_business_growth_percent_diff" headers="{'country_name': 'Country', 'date_range': 'Date Range', 'last_value': 'Previous #', 'first_value': 'Current #', 'difference': 'Diff', 'percent_difference': '% Diff'}" maxHeight="400px" sortable="true" valueId="country_name" selectableRows="multi" targets="bitcoin-business-growth-chart" >}} -{{< chart id="bitcoin_business_growth" endpoint="bitcoin_business_growth_timeseries" chartType="line" xAxisField="date" yAxisField="cumulative_value" scaleChart=true >}} +{{< chart id="bitcoin-business-growth-chart" endpoint="bitcoin_business_growth_timeseries" chartType="line" xAxisField="date" yAxisField="cumulative_value" scaleChart=true >}} #### Attribution and License Data obtained from © [OpenStreetMap](https://www.openstreetmap.org/copyright) diff --git a/layouts/partials/chart.html b/layouts/partials/chart.html index 6f9e5bb..92a8ef9 100644 --- a/layouts/partials/chart.html +++ b/layouts/partials/chart.html @@ -39,7 +39,7 @@ for (let objectId in chartData) { chartDataMap.set(objectId, chartData[objectId]); } - var chartDom = document.getElementById(`${id}--chart`); + var chartDom = document.getElementById(`${id}`); var myChart = echarts.init(chartDom); var option = { @@ -67,30 +67,29 @@ myChart.setOption(option, true); } - document.addEventListener("rowSelected", (event) => { - console.log( - "Row selected:", - event.detail.row.offsetParent.id, - event.detail.row.value, - event.detail.valueId, - event.detail.selectableRows, - ); - valueId = event.detail.valueId - let selectedRow = { - [valueId]: event.detail.row.value, - }; - query = queryConstructor(selectedRow); - fetchDataForChart(query, valueId); - }); - - document.addEventListener("rowDeselected", (event) => { - console.log( - "Row deselected:", - event.detail.row.offsetParent.id, - event.detail.row.value, - ); - delete chartData[event.detail.row.value]; - updateChart(); + // listen for filter events for this target + document.addEventListener("filterChange", function (event) { + tableId = document.getElementById(id).id; + console.log(event.detail); + eventDetail = event.detail; + if (eventDetail.filterActions.includes("refresh")) { + chartData = []; + updateChart(); + } else { + if (eventDetail.filterTargets.includes(tableId)) { + if (eventDetail.filterActions.includes("selected")) { + valueId = eventDetail.filterId; + let selectedRow = { + [valueId]: eventDetail.filterValue, + }; + query = queryConstructor(selectedRow); + fetchDataForChart(query, valueId); + } else { + delete chartData[eventDetail.filterValue]; + updateChart(); + } + } + } }); } diff --git a/layouts/partials/table.html b/layouts/partials/table.html index 39c2ad6..10695e5 100644 --- a/layouts/partials/table.html +++ b/layouts/partials/table.html @@ -7,6 +7,7 @@ sortable, valueId, selectableRows, + filterTargets ) { async function fetchDataForTable(query) { try { @@ -25,7 +26,7 @@ function generateTable(data) { const jsonTableContainer = document.getElementById( - `${id}--table-container`, + `${id}--container`, ); jsonTableContainer.className = "jsonTableContainer"; jsonTableContainer.innerHTML = ""; @@ -35,7 +36,7 @@ tableHeaderKeys = Object.keys(headers); const table = document.createElement("table"); - table.id = `${id}--table`; + table.id = `${id}`; const thead = document.createElement("thead"); const tbody = document.createElement("tbody"); const headerRow = document.createElement("tr"); @@ -63,51 +64,43 @@ table.appendChild(thead); table.appendChild(tbody); - // selectable rows - let currentlySelectedRow = null; - if (selectableRows === "multi" || selectableRows === "single") { const rows = table.getElementsByTagName("tr"); - for (let i = 1; i < rows.length; i++) { - // Skip the header row rows[i].addEventListener("click", function () { - if (selectableRows === "single") { - // Deselect the currently selected row, if any - if (currentlySelectedRow && currentlySelectedRow !== this) { - currentlySelectedRow.classList.remove("selected"); - const deselectEvent = new CustomEvent("rowDeselected", { - detail: { row: currentlySelectedRow }, + if (selectableRows === "multi") { + this.classList.toggle("selected"); + if (this.classList.contains("selected")) { + const event = new CustomEvent("filterChange", { + detail: { + filterId: valueId, + filterValue: this.value, + filterActions: ["selected"], + filterTargets: filterTargets + }, }); - document.dispatchEvent(deselectEvent); + document.dispatchEvent(event); + } else { + const event = new CustomEvent("filterChange", { + detail: { + filterId: valueId, + filterValue: this.value, + filterActions: ["deselected"], + filterTargets: filterTargets + }, + }); + document.dispatchEvent(event); + } + } else if (selectableRows === "single") { + if (this.classList.contains("selected")) { + this.classList.remove("selected"); + } else { + for (let j = 1; j < rows.length; j++) { + rows[j].classList.remove("selected"); + } + this.classList.add("selected"); } - - // Toggle the selected class on the clicked row - this.classList.toggle("selected"); - - // Update the currently selected row - currentlySelectedRow = this.classList.contains("selected") - ? this - : null; - } else { - // Multi-select behavior - this.classList.toggle("selected"); } - - const event = new CustomEvent( - this.classList.contains("selected") - ? "rowSelected" - : "rowDeselected", - { - detail: { - row: this, - selectableRows: selectableRows, - valueId: valueId, - }, - }, - ); - - document.dispatchEvent(event); }); } } @@ -116,16 +109,20 @@ // sortable if (sortable == "true") { table.className = "sortable"; - sorttable.makeSortable(document.getElementById(`${id}--table`)); + sorttable.makeSortable(document.getElementById(`${id}`)); } } - + + // listen for filter events for this target document.addEventListener("filterChange", function (event) { - query = queryConstructor() - fetchDataForTable(query); + tableId = document.getElementById(id).id + if (event.detail.filterTargets.includes(tableId)) { + query = queryConstructor(); + fetchDataForTable(query); + } }); - query = queryConstructor() + query = queryConstructor(); fetchDataForTable(query); } diff --git a/layouts/shortcodes/chart.html b/layouts/shortcodes/chart.html index ce478ee..b030efa 100644 --- a/layouts/shortcodes/chart.html +++ b/layouts/shortcodes/chart.html @@ -1,6 +1,6 @@ {{ partial "chart.html" }}
-
+
diff --git a/static/js/lib/helper-functions.js b/static/js/lib/helper-functions.js index 015a731..0472106 100644 --- a/static/js/lib/helper-functions.js +++ b/static/js/lib/helper-functions.js @@ -5,7 +5,7 @@ function queryConstructor(customFilters = {}) { Object.assign(queryObject, customFilters); filters.forEach((filter) => { - const filterId = filter.id; + const filterId = filter.getAttribute("idFilter"); const filterValue = filter.value; queryObject[filterId] = filterValue; });