working filter system
This commit is contained in:
parent
5930fe90a1
commit
eb3d17884a
|
@ -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.
|
||||
|
||||
<br/>
|
||||
{{< 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)
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{{ partial "chart.html" }}
|
||||
<section class = 'chart-container'>
|
||||
<div class = "chart" id='{{ .Get "id" }}--chart'>
|
||||
<div class = "chart" id='{{ .Get "id" }}'>
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
createChart(id={{ .Get "id" }}, endpoint={{ .Get "endpoint" }}, chartType={{ .Get "chartType" }}, xAxisField={{ .Get "xAxisField" }}, yAxisField={{ .Get "yAxisField" }}, sortField={{ .Get "sortField" }}, scaleChart={{ .Get "scaleChart" }})
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
{{ $options_split := split $options "," }}
|
||||
|
||||
<div class="dropdown-filter-container">
|
||||
<select class="filter dropdown-filter" id="{{ $id }}" onchange="dispatchDropdownEvent(this)">
|
||||
<select class="filter dropdown-filter" id="{{ $id }}" idFilter='{{ .Get "id_filter" }}' onchange="dispatchDropdownEvent(this)">
|
||||
{{ range $options_split }}
|
||||
{{ $parts := split . ":" }}
|
||||
{{ $key := index $parts 0 }}
|
||||
|
@ -17,8 +17,10 @@
|
|||
function dispatchDropdownEvent(selectElement) {
|
||||
const event = new CustomEvent('filterChange', {
|
||||
detail: {
|
||||
filterId: selectElement.id,
|
||||
filterId: '{{ .Get "id_filter" }}',
|
||||
filterValue: selectElement.value,
|
||||
filterActions: ["refresh"],
|
||||
filterTargets: '{{ .Get "targets" }}'.split(" ")
|
||||
}
|
||||
});
|
||||
document.dispatchEvent(event);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
{{ partial "table.html" }}
|
||||
<div id = '{{ .Get "id" }}--table-container'>
|
||||
<div id = '{{ .Get "id" }}--container'>
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
createTable({{ .Get "endpoint" }}, {{ .Get "id" }}, {{ .Get "headers" | safeJS }}, {{ .Get "maxHeight" }}, {{ .Get "sortable" }}, {{ .Get "valueId" }}, {{ .Get "selectableRows" }})
|
||||
createTable({{ .Get "endpoint" }}, {{ .Get "id" }}, {{ .Get "headers" | safeJS }}, {{ .Get "maxHeight" }}, {{ .Get "sortable" }}, {{ .Get "valueId" }}, {{ .Get "selectableRows" }}, '{{ .Get "targets" }}'.split(" "))
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
|
|
@ -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;
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue