ENUNCIADO
En la entrada (1) de esta serie definimos los objetivos: una regla de color personalizada para un mapa generado mediante Reporting Services que fuera uniforme, redondeada, con cero y colores desplazados
En la entrada (2) vimos como podemos cargar un informe en memoria, para modificarlo y volcarlo en un control ReportViewer.
En la entrada (3) modificamos la definición XML del informe dejando pendientes las funciones que cálculan los rangos y colores.
En la entrada (4) calculamos los intervalo numéricos de la regla.
En está última entrada de la serie veremos como obtener una escala de colores con degradados centrados en el rango que contiene el valor cero.
En nuestro caso para simplificar y porque los colores son los mas intuitivos situaremos el centro en el color amarillo y degradaremos hacia el azulo por los valores negativos y hacia el rojo por los valores positivos.
En mi algoritmo el color amarillo se situará a la derecha o a la izquierda del cero según el número de rangos que haya en cada lado. El objetivo es aminorar la perdida de definición en los colores y visualizar siempre los tres colores, lo que podría no ocurrir si el cero estuviera en primera o última posición.
SOLUCIÓN
El algoritmo rellena la lista en tres pasos:Primero por la parte derecha donde:
- El azul está en máximos (#FF o 255) y decrece hasta casi #00.
- El rojo y el verde crecen desde #00 hasta "casi" #FF
Luego la parte derecha:
- El azul se mantiene en #00
- El rojo que empieza en casi #FF deberá terminar en #FF (aunque puede sufrir una perdida de intensidad intermedia).
- El verde empieza el casi #FF pero termina en #00
- El punto medio donde situamos el amarillo
- Los pasos para cada color en los degradados derecho e izquierdo.
- 'Operar' con colores para generar el string hexadecimal.
'''''' Calcula un rango de colores que empieza en azul, pasa por el verde en el valor cero y termina en el rojo ''' ''' colección de extremos de rango que contiene el valor cero '''devuelve la lista de colores '''Public Function coloresCero(rango As List(Of Double)) As List(Of String) Dim colores As New List(Of String) Dim posicionMedio = rango.IndexOf(0) + 1 If posicionMedio > rango.Count / 2 Then posicionMedio -= 1 Dim cuentaIniciales = posicionMedio - 1 Dim cuentaFinales = rango.Count - posicionMedio Dim pasoInicial = 255 / cuentaIniciales Dim pasoMedio = 255 / (cuentaIniciales + 1) For i = 0 To cuentaIniciales - 1 colores.Add(HexString(pasoMedio * i, pasoMedio * i, 255 - pasoInicial * i)) Next colores.Add(HexString(255, 255, 0)) Dim pasoFinal = 255 / cuentaFinales pasoMedio = 255 / cuentaFinales For i = 1 To cuentaFinales colores.Add(HexString((pasoFinal * i) + (pasoMedio * (cuentaFinales - i)), pasoMedio * (cuentaFinales - i), 0)) Next Return colores End Function Function HexString(r As Integer, g As Integer, b As Integer) As String ' cálcula el string hexadecimal de color RGB Return "#" + hex(r) + hex(g) + hex(b) End Function Function hex(v As Integer) As String ' Obtiene el hexadecimal de un entero con cero por delante si hace falta Dim r = String.Format("{0:x}", v) If r.Length > 1 Then Return r Else Return "0" + r End If End Function
Reconozco que hay un poco de juego fácil en la elección de los colores, pero eran los que me pedían. ¡Más fácil habría sido elegir como central el verde¡.
No hay comentarios:
Publicar un comentario