CanvasMap
Getting Started Tutorials 3D Reference

Giving Each Feature a Unique Style From a Legend

The Africa example has different styles for each country. This is done by using the SetFeatureSettings() function with an array where each element in the array contains a style for each feature in the map. This tutorial also shows how to create the legend as the styles for the countries and the legend are tied together.

First, we override the CountryLayer's OnLoad function to update the legend with data from the "pop_est" (Populuation Esimate) attribute.

TheFilledCountryLayer.OnLoad=function()
{
	UpdateLegend("pop_est");
}

The function below updates the legend by setting up two arrays, one for the colors in the legend and another with the intervals for the values that appear in the legend. Then, the code gets an array of colors from CMUtility library and adds each of these colors as the style for a feature. Then, the legend DIV is added to the map.

/**
* Update the contents of the legend.
* For this, we will get the attribute values for each feature, define a set 
* of colors based on the values and the selected attribute, and then
* set these colors as the colors for filling each feature.
*
* @param Heading - the heading of a column with data (e.g. "pop_est")
*/
function UpdateLegend(Heading)
{
	// colors from ColorBrewer (click on the "Export" tab and copy and paste the "JavaScript" colors)
	var TheColors=['#d7191c','#fdae61','#ffffbf','#abd9e9','#2c7bb6']; // default colors for GNP
	
	// these are the intervals that will appear in the legend
	var Intervals=[0,10000000,20000000,30000000,40000000,50000000]; // default intervals for GNP
	
	if (Heading!="pop_est") // setup colors and intervals for population
	{
		TheColors=['#ffffcc','#c2e699','#78c679','#31a354','#006837'];
		Intervals=[0,10000,50000,100000,500000,1000000];
	}
	
	// get the feature values into an array
	var TheDataset=TheFilledCountryLayer.GetDataset();
	
	var FeatureValues=TheDataset.GetAttributeArrayByHeading(Heading);
	
	// Get colors to match the values
	var Result=CMUtilities.GetColorsFromArrays(FeatureValues,TheColors,Intervals);
	
	// Setup an array with styles for each feature based on the colors
	var FeatureColors=Result.FeatureColors;
	var FeatureStyles=[];
	
	var TheDataset=TheFilledCountryLayer.GetDataset();
	for (var i=0;i<TheDataset.GetNumAttributeRows();i++)
	{
		FeatureStyles={
			Style:
			{
				fillStyle:FeatureColors[i],
				strokeStyle:"rgba(220,220,200,0.1)"
			}
		};
		TheFilledCountryLayer.SetFeatureSettings(i,FeatureStyles);
	};
	
	// make sure the layer is repainted
	TheFilledCountryLayer.Repaint();
	
	// remove the legend DIV if needed
	var TheCanvasElement=TheMainContainer.GetElement("CanvasContainerID");
	if (TheLegend!=null) { TheCanvasElement.removeChild(TheLegend); }
	
	// add the legend using the helper function (you can replace this with your own code)
	TheLegend=CMUtilities.AddLegend(TheCanvasElement,TheColors,Result.LegendLabels,10,460,180,115);
	TheLegend.className="CM_Legend";
}

The last step is to add the radio buttons that change the attribute that is show in the legend and used to colorize the map. The code below should be added to the OnLoad() function to create the DIV element for the control. The code contains two radio buttons, each of which has a call to "UpdateLegend()". The UploadLegend() function passes in a different attribute for each radio button changing which one is used ot stylize the map.

 //****************************************************************************
 // setup the DIV for the attribute list with buttons to change the legend
 
 var TheCanvasElement=TheMainContainer.GetElement("CanvasContainerID");
 var TheAttributeListBox=document.createElement("DIV");
 TheAttributeListBox.className="CM_AttributeHeadingList";
 
 TheCanvasElement.appendChild(TheAttributeListBox);
 CMUtilities.AbsolutePosition(TheAttributeListBox,10,390,110,40);
 
 var TheHTML=
 "<input type='radio' name='gender' onClick='UpdateLegend(\"pop_est\")' checked>Population<br> \
 <input type='radio' name='gender' onClick='UpdateLegend(\"gdp_md_est\")' >GDP";
 
 TheAttributeListBox.innerHTML=TheHTML;