New York City 311 helicopter noise complaints by day of week and hour of day.

What is a heat chart?

Heat chart visualizes data in a grid format, where individual values are represented as colors in cells. It is useful for identifying patterns, correlations, and outliers in large datasets.

Data configurations

This section demonstrates how different data configurations can be used to create various types of heat charts, including calendar heat charts that use date fields and matrix heat charts that use categorical fields.

Calendar heat chart

A calendar heat chart visualizes data over time using two date fields. Each cell corresponds to a specific calendar unit defined by the intersection of the row and column, with color representing the value for that unit.

  • The temporal binning for each axis needs to be set accordingly via xTemporalBinning and yTemporalBinning to define the calendar units (e.g., day of month, month of year).

The above chart visualizes the amount of helicopter noise complaints in New York City by day of week and hour of day. Each cell represents a specific combination of day of week and hour of day, with darker colors indicating more complaints for that time period.

  1. Set the xAxisField and yAxisField properties to "Created_Date" to specify the date field.
  2. Set the xTemporalBinning property to have a unit of hourOfDay to bin the x-axis by hour of day, and set the yTemporalBinning property to have a unit of dayOfWeek to bin the y-axis by day of week.
  3. Use the setAxisValueFormat method to format the x-axis to display hours in 24-hour format and the y-axis to display a shortened version of weekdays.
  4. Use the setYAxisSortOrder method to sort the y-axis in descending order to have Sunday at the top and Saturday at the bottom.
Charts component
32 collapsed lines
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<title>Esri Developer Guide: Calendar Heat Chart</title>
<style>
html,
body,
arcgis-chart {
height: 100%;
margin: 0;
}
</style>
<!-- Load the ArcGIS Maps SDK for JavaScript from CDN -->
<script type="module" src="https://js.arcgis.com/5.1/"></script>
</head>
<body>
<arcgis-chart></arcgis-chart>
<script type="module">
const { createModel } = await $arcgis.import("@arcgis/charts-components/model/shared/setup-utils.js");
const FeatureLayer = await $arcgis.import("@arcgis/core/layers/FeatureLayer.js");
const featureLayer = new FeatureLayer({
portalItem: {
id: "caea6a7ab4fe44b9b4ec3abb7314c1bb",
},
});
const chartElement = document.querySelector("arcgis-chart");
const heatChartModel = await createModel({
layer: featureLayer,
chartType: "heatChart",
});
heatChartModel.xAxisField = "Created_Date";
heatChartModel.yAxisField = "Created_Date";
heatChartModel.xTemporalBinning = { type: "calendarDateParts", unit: "hourOfDay" };
heatChartModel.yTemporalBinning = { type: "calendarDateParts", unit: "dayOfWeek" };
heatChartModel.setAxisValueFormat(0, { type: "date", intlOptions: { hour: "numeric", hour12: false } });
heatChartModel.setAxisValueFormat(1, { type: "date", intlOptions: { weekday: "short" } });
heatChartModel.setYAxisSortOrder("Desc");
16 collapsed lines
heatChartModel.gradientRules = {
colorList: [
[200, 225, 255, 255],
[220, 0, 0, 255],
],
};
heatChartModel.titleText = "NYC 311 Helicopter Noise Complaints";
heatChartModel.dataLabelsVisibility = true;
heatChartModel.legendPosition = "top";
chartElement.autoInverseDataLabelTextColor = true;
chartElement.model = heatChartModel;
chartElement.actionMode = "none";
</script>
</body>
</html>

Matrix heat chart

A matrix heat chart visualizes relationships between two categorical fields. Each cell represents the intersection of the two categories, and all records sharing the same category values are aggregated into the same cell, with color representing the aggregated value.

  • The axis values needs to be set with the setAxisValueFormat method to have a type of "category" to specify that the axis fields are categorical.

The above chart visualizes the average price of short term rentals listings in New York City for each combination of room type and neighborhood group. Each cell represents a specific combination of room type and neighborhood group, with darker colors indicating higher average prices.

  1. Set the xAxisField and yAxisField properties to "room_type" and "neighbourhood_group" respectively to specify the categorical fields.
  2. Set the numericFields property to ["price"] to specify the numeric field to be aggregated for color representation, and set the aggregationType property to "avg" to aggregate using the average value of the price field.
  3. Use the setAxisValueFormat method to format both axes to display category values.
Charts component
32 collapsed lines
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<title>Esri Developer Guide: Matrix Heat Chart</title>
<style>
html,
body,
arcgis-chart {
height: 100%;
margin: 0;
}
</style>
<!-- Load the ArcGIS Maps SDK for JavaScript from CDN -->
<script type="module" src="https://js.arcgis.com/5.1/"></script>
</head>
<body>
<arcgis-chart></arcgis-chart>
<script type="module">
const { createModel } = await $arcgis.import("@arcgis/charts-components/model/shared/setup-utils.js");
const FeatureLayer = await $arcgis.import("@arcgis/core/layers/FeatureLayer.js");
const featureLayer = new FeatureLayer({
portalItem: {
id: "a8fbe2753beb4cd4aeef4d47e5e32a7c",
},
});
const chartElement = document.querySelector("arcgis-chart");
const heatChartModel = await createModel({
layer: featureLayer,
chartType: "heatChart",
});
heatChartModel.xAxisField = "room_type";
heatChartModel.yAxisField = "neighbourhood_group";
heatChartModel.numericFields = ["price"];
heatChartModel.aggregationType = "avg";
heatChartModel.setAxisValueFormat(0, {
type: "category",
});
heatChartModel.setAxisValueFormat(1, {
type: "category",
});
10 collapsed lines
heatChartModel.titleText = "Helicopter Noise Complaints grouped by weekdays and hours";
heatChartModel.dataLabelsVisibility = true;
heatChartModel.legendPosition = "top";
chartElement.autoInverseDataLabelTextColor = true;
chartElement.model = heatChartModel;
chartElement.actionMode = "none";
</script>
</body>
</html>

Customization options

Gradient legend vs. class break legend

Gradient legend represents data using a continuous range of colors, which can provide a more detailed view of the data distribution but may be harder to interpret at a glance.

  • This is the default legend type for heat charts.

Class break legend divides the data into discrete classes or ranges, with each class represented by a specific color. This can make it easier to interpret the data by grouping similar values together and providing clear distinctions between different ranges.

  • By setting the heatRulesType property of the heat chart model to "renderer", the legend will defaults into five classes with equal intervals.

The above chart visualizes the same data as the calendar heat chart above but with a class break legend that divides the data into five classes.

  1. Set the heatRulesType property to "renderer" to switch to class break legend.
Charts component
39 collapsed lines
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<title>Esri Developer Guide: Calendar Heat Chart with class break legend</title>
<style>
html,
body,
arcgis-chart {
height: 100%;
margin: 0;
}
</style>
<!-- Load the ArcGIS Maps SDK for JavaScript from CDN -->
<script type="module" src="https://js.arcgis.com/5.1/"></script>
</head>
<body>
<arcgis-chart></arcgis-chart>
<script type="module">
const { createModel } = await $arcgis.import("@arcgis/charts-components/model/shared/setup-utils.js");
const FeatureLayer = await $arcgis.import("@arcgis/core/layers/FeatureLayer.js");
const featureLayer = new FeatureLayer({
portalItem: {
id: "caea6a7ab4fe44b9b4ec3abb7314c1bb",
},
});
const chartElement = document.querySelector("arcgis-chart");
const heatChartModel = await createModel({
layer: featureLayer,
chartType: "heatChart",
});
heatChartModel.xAxisField = "Created_Date";
heatChartModel.yAxisField = "Created_Date";
heatChartModel.xTemporalBinning = { type: "calendarDateParts", unit: "hourOfDay" };
heatChartModel.yTemporalBinning = { type: "calendarDateParts", unit: "dayOfWeek" };
heatChartModel.setAxisValueFormat(0, { type: "date", intlOptions: { hour: "numeric", hour12: false } });
heatChartModel.setAxisValueFormat(1, { type: "date", intlOptions: { weekday: "short" } });
heatChartModel.setYAxisSortOrder("Desc");
heatChartModel.heatRulesType = "renderer";
10 collapsed lines
heatChartModel.titleText = "Helicopter Noise Complaints (Class Break Legend)";
heatChartModel.dataLabelsVisibility = true;
heatChartModel.legendPosition = "top";
chartElement.autoInverseDataLabelTextColor = true;
chartElement.model = heatChartModel;
chartElement.actionMode = "none";
</script>
</body>
</html>