sábado, 25 de mayo de 2013

Una regla de color uniforme, redondeada, con cero y colores desplazados (3)


ENUNCIADO:

En la primera entrada de esta serie presentamos nuestro objetivo: Personalizar la regla de colores en un mapa incluido en un informe SSRS de forma que los valores y colores cumplieran ciertos requisitos.
En la segunda entrada vimos cómo podíamos cargar en memoria del cliente la definición XML de un informe SSRS para poder modificarla antes de entregarsela al control ReportViewer.
En esta entrada veremos como modificamos la entrada XML.

SOLUCIÓN:

El código esta comentado:
 
 Public Function ParametrizaMapa(informe As XDocument, 
                  s as string,
                  numRangos as integer) As XDocument
' s contiene una sentencia MDX 
' numRangos numero de rangos que deseamos

        'Calculamos los rangos de la regla de colores
        dim rangosMapa As List(Of Double)=rangosMapa(s,numRangos)
        
        ' Para escribir menos.
        Dim df = informe.Root.Name.Namespace
        Dim capas = informe.Root.Element(
            df + "ReportSections").Element(
            df + "ReportSection").Element(
            df + "Body").Element(
            df + "ReportItems").Element(
            df + "Map").Element(
            df + "MapLayers").Element(
            df + "MapPolygonLayer")

        ' comienzan las reglas de color
        Dim reglasColor As XElement

        ' borramos cualquier regla existente en el informe original
        If capa.Element(df + "MapPolygonRules").Element(df + "MapColorRangeRule") IsNot Nothing Then 
              capa.Element(df + "MapPolygonRules").Element(df + "MapColorRangeRule").Remove()
        end if
        If capa.Element(df + "MapPolygonRules").Element(df + "MapCustomColorRule") IsNot Nothing Then
              capa.Element(df + "MapPolygonRules").Element(df + "MapCustomColorRule").Remove()
        end if
        'Vamos a establecer los colores y sus degradados
        If rangosMapa.Contains(0) Then
            'mapa coloreado alrededor del cero 
            'hay que generar la personalización "MapColorRangeRule" mediante la función coloresCero
            capa.Element(df + "MapPolygonRules").Add(New XElement(df + "MapCustomColorRule"))
            reglasColor = capa.Element(df + "MapPolygonRules").Element(df + "MapCustomColorRule") 'Personalizado
            reglasColor.Add(New XElement(df + "MapCustomColors"))
            Dim colorines = reglasColor.Element(df + "MapCustomColors")
            dim colores as list (of String)= coloresCero(rangosMapa)  'obtenemos una lista de colores
            For Each color In colores
                colorines.Add(New XElement(df + "MapCustomColor", color))
            Next
        Else
            'mapa estándar podemos dejar utilizar la generación automática "MapColorRangeRule"
            capa.Element(df + "MapPolygonRules").Add(New XElement(df + "MapColorRangeRule")) 'Generado por SSRS
            reglasColor = capa.Element(df + "MapPolygonRules").Element(df + "MapColorRangeRule")
            reglasColor.Add(New XElement(df + "StartColor", My.Settings.ReglaColorInicio))
            reglasColor.Add(New XElement(df + "MiddleColor", My.Settings.ReglaColorIntermedio))
            reglasColor.Add(New XElement(df + "EndColor", My.Settings.reglaColorFin))

        End If
        'algunas cosas que siempre son necesarias
        reglasColor.Add(New XElement(df + "ShowInColorScale", "true"))
        reglasColor.Add(New XElement(df + "DataValue", "=Sum(Fields!Dato.Value)"))
        reglasColor.Add(New XElement(df + "BucketCount", rangosMapa.count.toString))
        reglasColor.Add(New XElement(df + "LegendText", "#FROMVALUE{N0} - #TOVALUE{N0}"))

        'Vamos a rellenar los rangos de valores
        Dim culturaUSA = New System.Globalization.CultureInfo("en-US")
        If rangosMapa.Count = 2 Then 'solo max y min
            reglasColor.Add(New XElement(df + "DistributionType", "EqualInterval"))
            reglasColor.Add(New XElement(df + "StartValue"), rangosMapa(0).ToString(culturaUSA.NumberFormat))
            reglasColor.Add(New XElement(df + "EndValue"), rangosMapa(1).ToString(culturaUSA.NumberFormat))
        Else
            'aquí es donde realmente estamos personalizando con nuestro rango personalizado
            reglasColor.Add(New XElement(df + "DistributionType", "Custom"))
            reglasColor.Add(New XElement(df + "MapBuckets"))
            Dim rangos = reglasColor.Element(df + "MapBuckets")
            For i = 0 To rangosMapa.Count - 2
                rangos.Add(New XElement(df + "MapBucket"))
                Dim rango = rangos.Elements(df + "MapBucket")(i)
                rango.Add(New XElement(df + "StartValue", rangosMapa(i).ToString(culturaUSA.NumberFormat)))
                rango.Add(New XElement(df + "EndValue", (rangosMapa(i + 1)).ToString(culturaUSA.NumberFormat)))
            Next
        End If

        'Establecemos la sentencia MDX que suministra los datos al informe
        Dim xdatos = (From f In doc.Root.Element(df + "DataSets").Elements(df + "DataSet")).First(
            Function(x As XElement) x.Attribute("Name") = "Datos").Element(df + "Query").Element(df + "CommandText")
            xdatos.SetValue(s)
        Return informe
End Function
          

Con esto hemos terminado la personalización del informe, nos quedan por definir las  dos funciones rangosMapa y coloresCero que presentaremos en la siguientes entradas



No hay comentarios: