DEV Community

Cover image for Intro to Binning with ArcGIS API for JavaScript
Rene Rubalcava
Rene Rubalcava

Posted on • Edited on • Originally published at odoe.net

Intro to Binning with ArcGIS API for JavaScript

What the bin?

There's an option for layers in the ArcGIS API for JavaScript called featureReduction. Up until recently, you could use it to define clusters of features in your application. FeatureReduction is a way to summarize data visually on the map. For clusters, this means the amount of features in the cluster determine how large the cluster is. Recently, the API introduced the ability use binning for FeatureReduction. For more details on binning, I highly recommend you read this blog post!

Here is a codepen of the sample used in this post.

Adding binning to my features

I have this webmap that I like to use when I want to demonstrate using a large amount of features. The service over 2 million points, so it's a pretty good test map and layer. The first thing to do is define a bin level.

const layer = new FeatureLayer({
    portalItem,
    featureReduction: {
        type: "binning",
        fixedBinLevel: 4
    }
});
Enter fullscreen mode Exit fullscreen mode

The fixedBinLevel will keep the bins the same size regardless of how much you zoom in and out. Depending on your dataset, and the scale you plan to use, this could take some tweaking, but once you've found a good level, you are all set.

FeatureReduction Renderer

One of the first things you would normally do is set up your aggregateFields, where you can set up the statistics for your bins. My service doesn't have a numeric field I could really use, so I won't set it up, but this is a great way to aggregate your data for visualizations. By default, bins will have an aggregateCount field I can use.

const layer = new FeatureLayer({
    portalItem,
    featureReduction: {
        type: "binning",
        fixedBinLevel: 4,
        renderer: {
            type: "simple",
            symbol: {
                type: "simple-fill",
                color: [0, 255, 71, 1],
                outline: null,
                outline: {
                    color: "rgba(153, 31, 23, 0.3)",
                    width: 0.3
                }
            },
            visualVariables: [
                {
                    type: "color",
                    field: "aggregateCount",
                    legendOptions: {
                        title: "Number of Places"
                    },
                    stops: [
                        { value: 0, color: "#d7e1ee" },
                        { value: 25, color: "#cbd6e4" },
                        { value: 75, color: "#b3bfd1" },
                        { value: 200, color: "#c86558" },
                        { value: 300, color: "#991f17" }
                    ]
                }
            ]
        }
    }
});
Enter fullscreen mode Exit fullscreen mode

Ok, so in this renderer, I set up some visual variables that will define bin colors based on the amount of features in the bin. Notice that all these properties are part of the featureReduction of the layer, not the root of the layer itself.

Adding Labels

Not only can define a renderer for the bins, you can define labels! I'll admit though, this might be something you want to toggle, because it can get busy. I would say, use bin labels cautiously.

labelingInfo: [
    new LabelClass({
        minScale: 0,
        maxScale: 0,
        deconflictionStrategy: "none",
        symbol: {
            type: "text",
            color: "white",
            font: {
                family: "Noto Sans",
                size: 10,
            },
            haloColor: "gray",
            haloSize: 0.5,
        },
        labelExpressionInfo: {
            expression: "Text($feature.aggregateCount, '#,###')",
        },
    }),
]
Enter fullscreen mode Exit fullscreen mode

Notice we can use an arcade expression for the aggregate fields "Text($feature.aggregateCount, '#,###')", for labels. When it comes to arcade, $feature refers to the binned feature. not any of the source features.

Color Ramps

I want to touch on a pretty cool feature in the documentation for the ArcGIS API for JavaScript. That would be the Esri Color Ramps. I don't know about you, but I don't exactly have the skill set to be creating hand crafted artisanal color ramps for my visual variables. What's great is you can browse the color ramps, filter them by type and color scheme, then they provide a nice copy button for hex values. The best part? The copy button adds a JavaScript snippet to your clipboard you can paste right into you applications!

// #48385f|#995375|#db4a5b|#fc9a59|#fee086
const colors = ["#48385f", "#995375", "#db4a5b", "#fc9a59", "#fee086"];
Enter fullscreen mode Exit fullscreen mode

Now, I can update my visual variables to use them!

visualVariables: [
    {
        type: "color",
        field: "aggregateCount",
        legendOptions: {
            title: "Number of Places",
        },
        stops: [
            { value: 0, color: colors[4] },
            { value: 25, color: colors[3] },
            { value: 75, color: colors[2] },
            { value: 200, color: colors[1] },
            { value: 500, color: colors[0] },
        ],
    },
],
Enter fullscreen mode Exit fullscreen mode

Look at that! Have more stops? Less stops? You can filter the color ramps to find what suits your needs!

Summary

Using bins for feature reduction and aggregating data is a great way to visualize your larger datasets. Visually, a large amount of points may not tell the story you want. Tools like binning and clusters, especially with aggregate fields can help you make the maps and apps that make your data shine!

You can watch a video on this topic below!

Top comments (0)