Select to view content in your preferred language

Crear Visualizaciones Atractivas en la Ventana Emergente con Arcade

440
0
08-30-2024 03:36 PM
XanderBakker
Esri Esteemed Contributor
3 0 440

Experiencia del usuario

En muchos casos la costumbre es usar una visualización por defecto de los atributos en la ventana emergente, ¿pero con esto estamos entregando la mejor experiencia al usuario?

Arcade - ventana emergente 00.png

Aprovechando Arcade es posible mejorar esta experiencia al usuario y brindar una visualización que no solamente sea más atractiva, pero también optimice la interpretación de los datos. Un ejemplo de los mismos datos se puede observar abajo:

Arcade - ventana emergente 01.png

En este caso estamos usando una capa de municipios y para cada municipio tiene información sobre la cantidad de personas con acceso y sin acceso a los servicios públicos (acueducto, alcantarillado, electricidad, gas y telefonía). Con base en esto podemos calcular el porcentaje de cobertura para cada servicio:

Arcade - servicios públicos.png

El cálculo es sencillo, pero para crear una visualización atractiva con los datos, debemos usar un elemento de Arcade que genere código HTML. La expresión de Arcade consiste en 2 partes; la configuración y el análisis donde se conecta a los datos, realicen los cálculos y genere el HTML basada en la configuración:

Arcade - configuración y análisis.png

Para agregar HTML a la ventana emergente, no se debe elegir la opción “Expresiones de atributos”, pero hacer clic en “Agregar contenido” y luego elegir “</> Arcade”:

Arcade - Agregar contenido.png

En el editor de Arcade se puede ver un ejemplo del formato que la expresión debe entregar:

Arcade - ventana emergente 02.png

Es un diccionario, que indique que el tipo de información que genere es un texto y el texto es el HTML que la expresión debe generar.

El HTML no es muy complejo y utilice un número de tags limitado.

  • Tablas para alinear la información y presentar la rampa de colores (<table>, <tbody>, <tr> y <td>)
  • Imágenes (<img>)
  • Encabezado (<h3>)
  • Negrilla (<b>)

En las tables el uso de estilo CSS si es frecuente para obtener la visualización deseada. Al final de este documento pueden encontrar el código completo de Arcade usado para este ejemplo.

Una explicación de la expresión Arcade:

  • Línea 1 a 17, configuración de estilo CSS para las tablas
  • Línea 20 a 59, listado de los servicios a graficar y un diccionario con información sobre nombres de campos con los datos y la imagen a usar en la ventana emergente. Estas imágenes fueron sacadas de Flaticon.com
  • Línea 61 a 74, definición de la campa de colores (10 colores de verde a rojo) y crear una rampa invertida para ofrecer esta opción en la visualización.
  • Línea 76 a 96, definición de variables
  • Línea 98, inicio del bucle por los 5 servicios
  • Línea 100, leer la configuración de campos, títulos e imagen para el servicio a procesar
  • Línea 104 a 107, definición de la rampa de colores a usar para la visualización del servicio
  • Línea 110 a 130, calcular la cobertura del servicio
  • Línea 132 a 141, crear la tabla con el título y la imagen del servicio
  • Línea 143 a 146, inicio de la tabla con la rampa
  • Línea 148 a 178, crear las 10 celdas según la cobertura (0-10%, 10-20%, … , 90-100%), colocando el porcentaje en la celda que contiene este valor y dejando celdas de un rango mayor al porcentaje de cobertura en colores gris y blanco)
  • Línea 184 a 187, donde se devuelve el código html para su representación.

 

El código Arcade

// configuración
var img_width = "50";
var img_height = "50";
var style_table1 = "width: 100%;border: 0px solid black;border-collapse: collapse;font-family: Segoe UI, Tahoma, Verdana, Geneva, Arial, Helvetica, sans-serif;font-size: 11pt;";
var style_tbl1tr = "valign='valign' style='background-color: rgb(255, 255, 255);'";
var style_tbl1cell1 = "border: 0px solid rgb(255, 255, 255);background-color:rgb(255, 255, 255);text-align:left;height:60px;width:60px";
var style_tbl1cell2 = "border: 0px solid rgb(255, 255, 255);padding-right: 5px;color:rgb(0, 0, 0);background-color:rgb(255, 255, 255);text-align:left;height:60px;width:250px";
var style_table2 = "width: 100%;border: 0px solid black;border-collapse: collapse;font-family: Segoe UI, Tahoma, Verdana, Geneva, Arial, Helvetica, sans-serif;font-size: 9pt;";
var style_tbl2tr = "valign='valign' style='background-color: rgb(255, 255, 255);'";
var style_tbl2tdpart1 = "style='border: 1px solid ";
var style_tbl2tdpart2 = ";padding-right: 5px;color:rgb(0, 0, 0);background-color:";
var style_tbl2tdpart3 = ";text-align:center;height:25px;width:10%'";
var separation_between_data = "<br />";
var separation_after_header = ""; //"<br />";
var border_col_data = "rgb(0, 0, 0)";
var border_col_nodata = "rgb(200, 200, 200)";
var backgr_col_nodata = "rgb(255, 255, 255)";


// temas a tratar
var arr_info = ["Electricidad", "Acueducto", "Alcantarillado", "Gas Natural", "Telefonía"];

// info por tema
var dct_fieldinfo = {"Electricidad": 
											{"Title": "Cobertura de Electricidad", 
											 "With": "P_ENERSI",
											 "Without": "P_ENERNO",
											 "NoData": "", 
						 					 "img": "https://utility-esri-co.maps.arcgis.com/sharing/rest/content/items/817da1062ed643a39b0b721f7136f684/data", 
						 					"reverse": true},
										"Acueducto":
											{"Title": "Cobertura de Acueducto", 
											 "With": "P_ACUESI",
											 "Without": "P_ACUENO",
											 "NoData": "", 
						 					 "img": "https://utility-esri-co.maps.arcgis.com/sharing/rest/content/items/7c37c2849bbd475e94cb053d6081f641/data", 
						 					"reverse": true},
										"Alcantarillado":
											{"Title": "Cobertura de Alcantarillado", 
											 "With": "P_ALCANSI",
											 "Without": "P_ALCANNO",
											 "NoData": "", 
						 					 "img": "https://utility-esri-co.maps.arcgis.com/sharing/rest/content/items/015376acd80c41a4bf2fe6ac2bd53e92/data", 
						 					"reverse": true},
										"Gas Natural":
											{"Title": "Cobertura de Gas Natural", 
											 "With": "P_GASNSI",
											 "Without": "P_GASNNO",
											 "NoData": "P_GASNNOIN", 
						 					 "img": "https://utility-esri-co.maps.arcgis.com/sharing/rest/content/items/a9811a6c7e9c444381d1dad8d1f9894d/data", 
						 					"reverse": true},
										"Telefonía":
											{"Title": "Cobertura de Telefonía", 
											 "With": "P_TELEFSI",
											 "Without": "P_TELEFNO",
											 "NoData": "P_TELEFNOI", 
						 					 "img": "https://utility-esri-co.maps.arcgis.com/sharing/rest/content/items/c5b285416954406a9883748c6b30ddad/data", 
						 					"reverse": true},
										};

// colores
var arr_rampcolors = ["rgb(113, 159, 102)", 
                      "rgb(82, 186, 149)",
                      "rgb(128, 221, 164)",
                      "rgb(195, 255, 151)",
                      "rgb(235, 255, 100)",
                      "rgb(254, 233, 77)",
                      "rgb(252, 191, 76)",
                      "rgb(244, 136, 87)",
                      "rgb(210, 76, 76)",
					  "rgb(151, 76, 76)"];

// invertir colores (en caso que aplique)
var arr_rampcolorsrev = Reverse(arr_rampcolors);

var html = "";
Console($feature["MUNICIPIO"]);
Console($feature["DEPTO"]);

var conservicio = -1;
var sinservicio = -1;
var nodata = -1;
var score = -1;
var scoreint10 = -1;
var scoredec = -1;
var scoredectxt = "";
var servicio = "";
var info = {};
var img = "";
var title = "";
var i = 0;
var fld_nodata = "";
var fld_border_col = "";
var fld_backgr_col = "";
var fld_with = "";
var fld_without = "";

for (i in arr_info) {
	servicio = arr_info[i];
	info = dct_fieldinfo[servicio];
	// construir titulo
	img = info["img"]; // url de imagen
	title = info["Title"]; // titulo del dato
	var reverseramp = info["reverse"]; // no está implementado por el momento TODO
	var use_ramp = arr_rampcolors;
	if (reverseramp == true) {
		use_ramp = arr_rampcolorsrev;
	}

	// calcular porcentaje
	fld_with = info["With"];
	fld_without = info["Without"];
	fld_nodata = info["NoData"];
	Console(fld_with);
	Console(fld_without);
	Console(fld_nodata);

	conservicio = $feature[fld_with];
	sinservicio = $feature[fld_without];
	Console(conservicio);
	Console(sinservicio);
	
	if (fld_nodata == "") {
			nodata = 0;
	} else {
			nodata = $feature[fld_nodata];
	}
	score = conservicio / (conservicio + sinservicio + nodata) * 100.0;
	scoreint10 = Round(score/10, 0);
	scoredec = Round(score, 2);

	// tabla con datos a presentar
	html += "<table style='" + style_table1 + "'>";
	html += "<tbody>";
	html += "    <tr " + style_tbl1tr+ ">";
	html += "      <td style='" + style_tbl1cell1 + "'><img src='" + img + "' width='" + img_width + "' height='" + img_height + "'></td>";
	html += "      <td style='" + style_tbl1cell2 + "'><h3>" + title + "</h3></td>";
	html += "    </tr>";
	html += "  </tbody>";
	html += "</table>";
	html += separation_after_header;

	// tabla con colores
	html += "<table style='" + style_table2 + "'>";
	html += "<tbody>";
	html += "    <tr " + style_tbl2tr + ">";

	for (var j = 0; j < 10; j++) {
		Console("j:" + j)
		// construir tabla con colores
		if (scoreint10 == j+1) {
			// usar colores y texto
			Console("usar colores y texto");
			scoredectxt = scoredec;
			fld_border_col = border_col_data;
			fld_backgr_col = use_ramp[j];
		} else if (scoreint10 > j+1) {
			Console("usar colores sin texto");
			// usar colores sin texto
			scoredectxt = "";
			fld_border_col = border_col_data;
			fld_backgr_col = use_ramp[j];

		} else {
			// sin color y sin texto
			Console("sin color y sin texto");
			scoredectxt = "";
			fld_border_col = border_col_nodata;
			fld_backgr_col = backgr_col_nodata;
		}
		html += "      <td "+ style_tbl2tdpart1 + fld_border_col + style_tbl2tdpart2 + fld_backgr_col + style_tbl2tdpart3 + "><b>" + scoredectxt + "</b></td>";
		Console("      <td "+ style_tbl2tdpart1 + fld_border_col + style_tbl2tdpart2 + fld_backgr_col + style_tbl2tdpart3 + "><b>" + scoredectxt + "</b></td>")
	}
	html += "    </tr>";
	html += "  </tbody>";
	html += "</table>";
	html += separation_between_data
}

Console("");
Console("");
Console(html);

return { 
	type : 'text', 
	text : html
}

 

Contributors
About the Author
Solution Engineer for the Utilities Sector @ Esri Colombia - Ecuador - Panamá sr GIS Advisor / Python - Arcpy developer / GIS analyst / technical project leader / lecturer and GeoNet moderator, focusing on innovations in the field of GIS. Specialties: ArcGIS, Python, ArcGIS Enterprise, ArcGIS Online, Arcade, Configurable Apps, WAB, Mobile Apps, Insights, Spatial Analysis, LiDAR / 3D Laser Scanning / Point Clouds. UNME http://nl.linkedin.com/in/xanderbakker/ http://www.slideshare.net/XanderBakker http://www.scribd.com/xbakker http://twitter.com/#!/XanderBakker