Difficulty recreating heatmap renderer with time slider in ArcGIS JS API

755
0
12-26-2020 08:47 PM
SethLutske
New Contributor III

The Goal

I am trying to recreate what I created in ArcGIS online using the ArcGIS JS API.  I have this webmap which uses a heatmap to visualize COVID numbers by country, with a time slider, as this is a time aware layer:

https://www.arcgis.com/home/webmap/viewer.html?webmap=3f2a6426b68247428618ce08bf5ac10b

I love the distribution of colors from the low end to the high end, and how it evolves over time.

What I've Tried

I am trying to code this from scratch using the api.  I'm having a hard time.  In order to get the map to show the right data according to the current timeslider timeextent, I followed the advice from this GIS stack exhange question , and the layer's definitionExpression is updated with each timeslider change:

 

 

timeSlider.watch('timeExtent', function (value) {
		updateDefintionExpression(value);
});

function updateDefintionExpression(timeExtent) {
	const start = toDateString(timeExtent.start);
	const end = toDateString(timeExtent.end);
	covidLayer.definitionExpression = `Date >= DATE '${start}' AND Date <= DATE '${end}'`;
}

 

 

I came up with a heatmap renderer from scratch, but it doesn't show off the low end as well as I'd like.  Here is the renderer code:

 

 

renderer: {
			type: 'heatmap',
			field: 'Confirmed',
			colorStops: [
				{ ratio: 0, color: 'rgba(255, 255, 255, 0)' },
				{ ratio: 0.06, color: 'rgba(255, 255, 255, 1)' },
				{ ratio: 0.15, color: 'rgba(255, 255, 0, 1)' },
				{ ratio: 0.25, color: 'rgba(255, 140, 0, 1)' },
				{ ratio: 0.55, color: 'rgba(255, 0, 0, 1)' },
			],
			minPixelIntensity: 1,
			maxPixelIntensity: 150000000,
			blurRadius: 12,
		},

 

 

You can see this in action here: https://codepen.io/slutske22/pen/poEdqEz

I played endlessly with the stops and the pixelIntensities, and I couldn't get a good range across the low end and high end (low numbers in the data vs high numbers in the data).

I looked into the JSON for the arcgis webmap I initially cereated, and this is the renderer it shows:

 

 

renderer: {
      type: "heatmap",
      blurRadius: 10,
      colorStops: [
        {
          ratio: 0,
          color: [212, 227, 245, 0]
        },
        {
          ratio: 0.01,
          color: [212, 227, 245, 0]
        },
        // ... more color stops
        {
          ratio: 0.9175000000000001,
          color: [204, 211, 51, 255]
        },
        {
          ratio: 1,
          color: [255, 255, 0, 255]
        }
      ],
      maxPixelIntensity: 9566880,
      minPixelIntensity: 0,
      field: "Confirmed"
    }

 

Using that, I get this result: https://codepen.io/slutske22/pen/eYdebdp

Also not quite right - the low end looks nice, but the high end looks blown out, like the heatmap is overflowing against an invisible square border.  Take a look - here is my goal:

Screen Shot 2020-12-26 at 9.10.04 PM.png

But here is what I'm getting with the JS API:

Screen Shot 2020-12-26 at 9.10.00 PM.png

I'm not sure why in my handcoded app, the heatmap looks "cut off"...if I can fix this, then the renderer from JSON will probably work just fine.  (And how to get that nice fade-out effect?)

 

I also tried using the smartmapping heatmap renderer:

 

  timeSlider.watch("timeExtent", function (value) {
    updateDefintionExpression(value);

    const params = {
       layer: covidLayer,
       view,
       field: "Confirmed",
       fadeToTransparent: true,
       minRatio: 0.05
    }

    heatmapRendererCreator.createRenderer(params)
    .then(result => {
       covidLayer.renderer = result.renderer
       console.log(result.renderer)
    })
  });

 

 

You can see the result here: https://codepen.io/slutske22/pen/VwKrqKr

This is also not correct.  This seems to re-evaluate the total range of values on each timeslider update, and distribute the heatmap accordingly, making each timestep look very similar.

 

How can I achieve the effect that I have in the arcgis online web map, using the JS API?  I feel I am close but struggling to see the right way.

0 Replies