Von Ihrer Seite aus filtern
Deklarierte Filter sind die Eingaben, die der Autor der Karte einer einbettenden Seite anbieten wollte. Sie sind die einzige Stelle, an der ein Wert von Ihrer Seite die Daten der Karte erreicht. Die Regel ist daher streng: Ein Name, den der Autor nicht deklariert hat, wird abgelehnt, bevor irgendetwas angewendet wird. Klicken Sie auf Try an undeclared filter, um es zu sehen.
Dieses Beispiel separat öffnen
Worauf Sie achten sollten
getFilterSchema()nennt Ihnen Namen, Typen und Operatoren. Bauen Sie Ihre Oberfläche daraus auf.- Ein Listenwert bedeutet „einer davon“; Zahlen nehmen
{ low, high }, Datumsangaben{ from, to }oder einen relativen Zeitraum wie{ operator: "inLast", count: 30, unit: "days" }. - Beim Veröffentlichen einer Karte wird automatisch ein Filter für jede Spalte deklariert, die einer ihrer Datenschnitte erreichen kann.
- Diese Seite blendet alle Kacheln aus und listet trotzdem die Werte jedes Filters auf:
getSlicerValuesantwortet auch für einen ausgeblendeten Datenschnitt. - Filter schränken ein, was die Karte zeigt; sie sind keine Sicherheitsgrenze zwischen Benutzern.
Der Code
Die vollständige Seite. Setzen Sie Ihre eigene Publish-ID ein und bitten Sie den Autor der Karte, Ihre Website zu ihren zulässigen Ursprüngen hinzuzufügen.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Filter from your page - Icon Map Embed API</title>
<link rel="stylesheet" href="https://www.icon-map.com/embed-examples/examples.css"> <!-- demo styling only -->
</head>
<body>
<div class="ex-main">
<div class="ex-side">
<div id="filters">loading...</div>
<h2>Applied</h2>
<pre class="ex-readout" id="applied">{}</pre>
<div class="ex-chips" style="margin-top:10px">
<button id="clear">Clear filters</button>
<button id="bad">Try an undeclared filter</button>
</div>
<pre class="ex-readout" id="error" style="margin-top:8px;color:#ff8a8a"></pre>
</div>
<div id="map"></div>
</div>
<script src="https://www.icon-map.com/js/iconmap-embed/2/iconmap-embed.umd.min.js"></script>
<script>
const el = document.getElementById("map");
const map = IconMapEmbed.embed(el, {
publishId: "pub_...",
// The map is a globe: let this page's own background show in the space around it.
background: "transparent",
chrome: { legend: false, layerControl: false, bookmarksBar: false, tourTransport: false },
// Every card hidden: this page owns the filter UI. (getSlicerValues still answers for a hidden slicer.)
visibility: { visuals: { "chart-continent": false, "slicer-continent": false, "slicer-size": false, "slicer-capital": false } },
events: ["filtersChanged"],
});
map.ready.catch((error) => console.error(error.code, error.message));
const values = {}; // filter name -> Set
(async () => {
// The filters the map's AUTHOR declared. A page can set these and nothing else.
const schema = await map.getFilterSchema();
const host = document.getElementById("filters");
host.textContent = schema.length ? "" : "This map declares no filters.";
// Value lists: from the schema when the author fixed them, else from the slicer on the same column.
const slicers = await map.getSlicers();
for (const filter of schema) {
values[filter.name] = new Set();
let options = filter.values;
const slicer = slicers.find((s) => s.field === filter.column);
if (!options && slicer) options = (await map.getSlicerValues({ slicerId: slicer.id })).values;
host.append(Object.assign(document.createElement("h2"), { textContent: filter.label ?? slicer?.name ?? filter.name }));
const chips = Object.assign(document.createElement("div"), { className: "ex-chips" });
for (const option of options ?? []) {
const chip = Object.assign(document.createElement("button"), { textContent: String(option).replace(/^\d\. /, "") });
chip.onclick = () => {
const set = values[filter.name];
set.has(option) ? set.delete(option) : set.add(option);
chip.classList.toggle("on", set.has(option));
apply();
};
chips.append(chip);
}
host.append(chips);
}
})();
// setFilters replaces every filter value at once; a list means "any of".
function apply() {
const filters = {};
for (const [name, set] of Object.entries(values)) if (set.size) filters[name] = [...set];
return map.setFilters(filters).catch(show);
}
document.getElementById("clear").onclick = () => {
for (const set of Object.values(values)) set.clear();
for (const chip of document.querySelectorAll(".ex-chips button.on")) chip.classList.remove("on");
map.clearFilters();
};
// A name the author did not declare is refused before anything is applied.
document.getElementById("bad").onclick = () => map.setFilters({ salary: [100000] }).catch(show);
function show(error) {
document.getElementById("error").textContent = `${error.code}\n${error.message}`;
}
map.on("filtersChanged", ({ filters, reason }) => {
document.getElementById("error").textContent = "";
document.getElementById("applied").textContent = `${JSON.stringify(filters, null, 1)}\n(${reason})`;
});
</script>
</body>
</html>