0

I have a drop down list that allows a user to choose what heat map they would like displayed on the map.The drop down contains check boxes whos values determine select statements that build all potential layers. I would like to have color ramps generated automatically for each item in the drop down. Here's the tricky part, the drop down list is created from a table on a sql server. This table will change from time to time. This means that I cannot simply hard code everything and must take into consideration the unpredictable volatility of the options.

So far I have played around with the idea of creating a javascript object or array containing "X" amount of color ramp possibilities, cursing through options and assign accordingly. An item in the list contains colors that the ESRI api then builds a gradient for.

    app.colorRamps = [
        ["rgba(0,0,0,0)","#F1948A","#E74C3C","#943126"],
        ["rgba(0,0,0,0)","#BB8FCE", "#8E44AD", "#5B2C6F"],
        ["rgba(0,0,0,0)","#85C1E9", "#3498DB", "#21618C"]
    ]

And then something like the below to get the option index. purposeOptions is an object whos key is the value of the checkbox and its value is the layer itself. Thus to grab a integer index that can be used to then grab a color from the list above I have a for loop and increment appropriately. This int then can be used for the array above...

    function selectColors(v) {
        var i = 0;
        for (var key in purposeOptions) {
            if (purposeOptions[key] == v) {
                var index = i;
                var color = app.colorRamps[index];
                return color;
            }
            else {
                i++
            }
        }
    }

I was wondering if there would be a cleaner and more scale-able way to do this rather than hard coding a list of colors. Is there a library out there that can handle this? The app is also an asp.net MVC app so I am open to stacking this from that end as well.

Part B of this question would then be suggestions for how to show that gradient next to the check box in the drop down.

EDIT

I've tackled this by adding a function that builds color ramps when looping trough the options and building layers.

            app.colors = [
                [255, 0, 0],//0
                [0, 255, 0],//1
                [0, 0, 255],//2
                [255, 255, 0],//3
                [0, 255, 255],//4
                [255, 0, 255],//5
                [128, 0, 0],//6
                [128, 128, 0],//7
                [0, 128, 0],//8
                [128, 0, 128],//9
                [0, 0, 128],//10
                [255, 165, 0]//11
            ];

            var buildColorStops = function (baseColorRGA_Array,numberOfValues,initialAlpha,alpha) {
                var b = baseColorRGA_Array;
                console.log("base color:" + b);
                var n = numberOfValues 
                var d = 1 / n;
                console.log(d);
                var ia = initialAlpha; 
                var a = alpha;
                var r = b[0];
                var g = b[1];
                var b = b[2];

                //var max = Math.max(r, Math.max(g, b));
                //console.log("max:" + max);
                //var step = (255 - max);
                //console.log("step:" + step);

                var outputArray = [];
                var i = 0;
                while (i < n) {
                    if (i == 0) {
                        var c = [r * d, g  * d, b  * d, ia];
                        var s = "rgba(" + c[0] + "," + c[1] + "," + c[2] + "," + c[3] + ")";

                        outputArray.push(s);
                    }
                    else {
                        var c = [r *  (d * (i + 1)), g *  (d * (i + 1)), b  * (d * (i + 1)), a];
                        var s = "rgba(" + c[0] + "," + c[1] + "," + c[2] + "," + c[3] + ")";
                        outputArray.push(s);

                    }
                    i++;
                }
                return outputArray;
            }// end of buildColorStops


            function buildLyr(v, c) {
                handle.show();

                console.log(v);
                var lyr = new FeatureLayer(serviceURL);
                var expression = extend.interpolateStr('"purpose" = %s', [extend.interpolateStr("'%s'",[v])]);
                console.log(expression);
                lyr.setDefinitionExpression(expression);

                if (c > 11) {
                    var clr = app.colors[c - 12];
                }
                else {
                    var clr = app.colors[c];
                }

                var g = buildColorStops(clr, 5, 0, 1);
                console.log(typeof (g));
                console.log(g);

                console.log("creating renderer");
                var heatmapRenderer = new HeatmapRenderer({
                    colors: g,
                    blurRadius: 8
                });

                console.log("setting renderer to lyr");
                lyr.setRenderer(heatmapRenderer);
                lyr.setVisibility(false);
                if (v != null || v != "" || v!= "/") {
                    app.purposeOptions[v] = lyr;
                    map.addLayer(app.purposeOptions[v]);

                }
                else {
                    app.purposeOptions["undifiened"] = lyr;
                    map.addLayer(app.purposeOptions["undifiened"])

                }
                handle.hide();
            }

On page load, a function loops through each option in the drop down and enters the buildLyr() function. The option values are passed in as well as a counter that indicates the current amount of options it has been through in that loop.

The build layer then creates a new feature layer, applies a selection using the option value, and then sets a render for the heatmap.

The color ramp is determined by taking the counter from earlier selecting a pre built list of basic colors and passes all that into a function called buildColorStops. This ultimately takes an argument of desired output colors to the build the shades using ratios and percentages. The out put is an array that looks something like the following... ["rgba(0, 0, 255, 0)","rgba(0, 0, 255,1)","rgba(255, 0, 255,1)", "rgba(255, 0, 0,1)"]..

This would appear to be an acceptable argument for the building of the heatMapRender from the ESRI API, however it is crashing when it comes to setting the color. https://developers.arcgis.com/javascript/3/jsapi/heatmaprenderer-amd.html#colors

I get a javascript error message (nothing to useful) when the script reached the renderer. Im directed to this line of code in the ESRI api... h.addColorStop(f.ratio,f.color.toCss(!0))

I can confirm from other attempts with this script that the output of my colorRampGenerator is an array of strings formatted appropriately. Using console.log() I was able to conclude it is specific to the color argument.

1

The above code will work (from the Edit Section). The final error was that by using a percent of the base colors we could end up with values such as 156.000344403344 or whatever. This threw the error because of issues with rendering this value into a color. If you use Math.round() to ensure integers the problem is solved.

var c = [Math.round(r *  (d * (i + 1))), Math.round(g *  (d * (i + 1))),Math.round(b  * (d * (i + 1))), a];

To me the next logical step here would be to add a color picker next to the check box in the dropdown for each item. We could then get at that value the user selects and apply it to the functions rather than have a preset array of colors.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.