This sample demonstrates how to use AttributeBinsQuery API to calculate the total number of hurricanes per year between 1925 and 2024 in the PST time zone using a date binning with a yearly interval.
Data binning is a technique that groups data into bins or categories based on specific intervals or ranges, making it easier to analyze trends, visualize patterns, and simplify the interpretation of large datasets.
How it works
When the application starts, the total number of hurricanes per year between 1925 and 2024 is calculated by calling queryAttributeBins() method on the hurricane tracks feature layer. The results of this query are then displayed as a histogram in the calcite-slider.
// get total hurricanes by year between 1925 and 2024 in the PST time zone
// using a date bin query with a yearly interval
const hurricanesQuery = new AttributeBinsQuery({
binParameters: new DateBinParameters({
field: "Hurricane_Date",
start: new Date(1925, 0, 1),
end: new Date(2024, 11, 31),
interval: {
value: 1,
unit: "years"
}
}),
outTimeZone: "America/Los_Angeles",
cacheHint: true
});
// query the layer for the total hurricanes by year
const hurricanesQueryResult = await layer.queryAttributeBins(hurricanesQuery);
const histogramData = hurricanesQueryResult.features.map((feature) => {
const year = new Date(feature.attributes.lowerBoundary).getFullYear()
const count = feature.attributes.frequency;
return [year, count];
});
// get the histogram element and set the histogram data
const hurricanesHistogram = document.getElementById("hurricanes-histogram");
hurricanesHistogram.histogram = histogramData;
hurricanesHistogram.histogramStops = [{
offset: 0,
color: "#52aeb7"
}];
Users can filter the hurricane tracks by adjusting the slider thumbs to display the hurricane tracks for the selected years. The total hurricanes by month ArcGIS bar chart is updated to show the total number of hurricanes between the selected years.
// update the map time extent and bar chart when the slider value changes
hurricanesHistogram.addEventListener("calciteSliderChange", () => {
updateMapTimeExtent(hurricanesHistogram.value[0], hurricanesHistogram.value[1]);
updateChartTimeExtent(hurricanesHistogram.value[0], hurricanesHistogram.value[1]);
});
// this function updates the time extent of the map and is called when the slider value changes
function updateMapTimeExtent(startYear, endYear) {
const start = new Date(startYear, 0, 1);
const end = new Date(endYear, 11, 31);
arcgisMap.timeExtent = {start, end};
const histogramBlock = document.getElementById("histogram-block");
histogramBlock.description = `${startYear} - ${endYear}`;
}
// update the bar chart time extent when the slider value changes
// to show the total hurricanes by month for the selected years
// update the bar chart's time extent
function updateChartTimeExtent(startYear, endYear) {
const start = new Date(startYear, 0, 1);
const end = new Date(endYear, 11, 31);
barChartElement.runtimeDataFilters = {
...barChartElement.runtimeDataFilters,
timeExtent: [start, end]
};
// update the title base on time extent
barChartModel.setTitleText(`Total hurricanes by month ${startYear} - ${endYear}`);
barChartElement.refresh();
}
// create the bar chart model and set the x-axis field to month
// this function is called when the slider value changes
// to show the total hurricanes by month for the selected years
// initialize the bar chart with bar chart model
async function initBarChart(startYear, endYear) {
barChartModel = new BarChartModel();
await barChartModel.setup({
layer
});
await barChartModel.setXAxisField("month");
barChartModel.setTitleSymbol({
type: "esriTS",
font: {
family: "Avenir Next",
size: 15,
weight: "bold"
}
});
barChartModel.setTitleText(`Total hurricanes by month ${startYear} - ${endYear}`);
const config = barChartModel.getConfig();
barChartElement.model = config;
barChartElement.layer = layer;
barChartElement.hideLoaderAnimation = true;
barChartElement.refresh();
}