Created
April 4, 2024 20:49
-
-
Save JosiahParry/cbcbed4964438ab69ab284826a72fffd to your computer and use it in GitHub Desktop.
Install the development version of {calcite} with `pak::pak("r-arcgis/calcite")`.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
library(shiny) | |
library(calcite) | |
# Custom script and style ------------------------------------------------ | |
custom_style <- " | |
.card-container { | |
margin: 0.75rem; | |
display: grid; | |
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); | |
grid-gap: 1rem; | |
justify-content: space-evenly; | |
} | |
calcite-chip { | |
color: var(--calcite-color-status-danger); | |
} | |
calcite-notice { | |
position: relative; | |
margin: 0.75rem; | |
} | |
" | |
style_tag <- htmltools::tag("style", custom_style) | |
ui <- div( | |
tags$script( | |
src = "https://js.arcgis.com/calcite-components/2.7.1/calcite.esm.js", | |
type = "module" | |
), | |
tags$link( | |
rel = "stylesheet", | |
type = "text/css", | |
href = "https://js.arcgis.com/calcite-components/2.7.1/calcite.css" | |
), | |
style_tag, | |
calcite_shell( | |
calcite_panel( | |
heading = "Earthquake results", | |
"heading-level" = 1, | |
description = "Search by location to display results", | |
calcite_filter(placeholder = "Try searching Alaska"), | |
calcite_notice( | |
id = "initial-note", icon = "information", | |
open = NA, | |
div(slot = "title", "Try searching a place of interest"), | |
div(slot = "message", "Results will display when text is entered.") | |
), | |
calcite_notice( | |
id = "note", | |
div(id = "number-records", slot = "title") | |
), | |
div(class = "card-container"), | |
calcite_pagination(slot = "footer", "page-size" = 12, style = "visibility:hidden") | |
) | |
), | |
htmltools::includeScript("dev/helper.js"), | |
) | |
server <- function(input, output) { | |
} | |
shiny::shinyApp(ui, server) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const filterElement = document.querySelector("calcite-filter"); | |
const paginationElement = document.querySelector("calcite-pagination"); | |
const initialNoticeElement = document.getElementById("initial-note"); | |
const noticeElement = document.getElementById("note"); | |
const cardContainer = document.querySelector(".card-container"); | |
/* Fetch the earthquakes feature service */ | |
fetch("https://services9.arcgis.com/RHVPKKiFTONKtxq3/ArcGIS/rest/services/USGS_Seismic_Data_v1/FeatureServer/0/query?where=1%3D1&outFields=*&f=json") | |
.then((response) => response.json()) | |
.then(({ features }) => features.map(({ attributes }) => attributes)) | |
.then((attributes) => initFilter(attributes)); | |
/* Filter the results to display */ | |
const initFilter = (items) => { | |
filterElement.items = items; | |
document.addEventListener("calciteFilterChange", () => { | |
paginationElement.startItem = 1; | |
paginationElement.totalItems = 0; | |
// Prevent display if no Filter value is present | |
noticeElement.open = false; | |
paginationElement.style.visibility = "hidden"; | |
cardContainer.innerHTML = ""; | |
// When a Filter value is present | |
// Create Cards, update Pagination, and number of responses | |
if (filterElement.value) { | |
filterElement.filteredItems.forEach((item) => createCard(item)); | |
paginationElement.totalItems = filterElement.filteredItems.length; | |
showNumberOfResponses(filterElement.filteredItems.length); | |
// If additional pages are populated, display Pagination | |
if (paginationElement.totalItems > paginationElement.pageSize) { | |
paginationElement.style.visibility = "visible"; | |
} | |
} else { | |
// If no text is present in the Filter, display the initial notice | |
initialNoticeElement.open = true; | |
} | |
}); | |
}; | |
/* Create Cards and their content */ | |
const createCard = (item) => { | |
const titleName = item.place.replace(/[;']/g, ""); | |
// Populate Card content | |
if (cardContainer.childElementCount < paginationElement.pageSize) { | |
const cardString = | |
`<calcite-card id="card-${item.OBJECTID}"> | |
<span slot="title"> | |
<b>${item.place}</b> | |
</span> | |
<span slot="subtitle"> | |
Occurred on: ${new Date(item.eventTime)} | |
</span> | |
<calcite-chip | |
appearance="outline-fill" | |
scale="s" | |
kind="inverse" | |
icon="graph-time-series" | |
> | |
Magnitude: ${item.mag} | |
</calcite-chip> | |
<calcite-button | |
label="Open ${titleName} in map" | |
icon-end="launch" | |
slot="footer-end" | |
target="_blank" | |
width="full" | |
href="https://www.arcgis.com/apps/mapviewer/index.html?` + | |
`marker=${item.longitude};${item.latitude};` + // Marker (lng, lat) | |
`4326;` + // Coordinate system | |
titleName + `;` + | |
`;` + // Marker image | |
`Magnitude: ${item.mag}&` + | |
`center=${item.longitude};${item.latitude}&` + | |
`level=6" | |
> | |
Open in map | |
</calcite-button> | |
</calcite-card>`; | |
const cardElement = document | |
.createRange() | |
.createContextualFragment(cardString); | |
cardContainer.appendChild(cardElement); | |
} | |
}; | |
/* Display the number of responses in a Notice */ | |
function showNumberOfResponses(responseNumber) { | |
const note = document.getElementById("note"); | |
const numberRecordsNote = document.getElementById("number-records"); | |
// If 0 responses, add "Sorry" to the Notice text | |
// Add the Notice color and icon | |
if (responseNumber === 0) { | |
responseNumber = `Sorry, ${responseNumber}` | |
note.kind = "danger"; | |
note.icon = "exclamation-mark-triangle"; | |
} else { | |
note.kind = "brand"; | |
note.icon = "information"; | |
} | |
// Hide the initial notice | |
initialNoticeElement.removeAttribute("open"); | |
// Notice text | |
numberRecordsNote.innerHTML = `${responseNumber} records found.`; | |
noticeElement.open = true; | |
} | |
/* Update Cards when interacting with Pagination */ | |
document.addEventListener("calcitePaginationChange", ({ target }) => { | |
cardContainer.innerHTML = ""; | |
const displayItems = filterElement.filteredItems.slice( | |
target.startItem - 1, | |
target.startItem - 1 + target.pageSize | |
); | |
displayItems.forEach((item) => createCard(item)); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment