【问题标题】:How do I keep colors consistent from chart to chart in Reporting Services 2005?如何在 Reporting Services 2005 中保持图表之间的颜色一致?
【发布时间】:2010-01-14 20:07:05
【问题描述】:

我在 TechNet 上使用 a technique described 为我的图表创建了一个自定义调色板。

我还有一系列钻取柱形图,您在其中单击一个列,它将参数传递到下一个图表,依此类推,呈现向下钻取的外观。

我的图表由 3 种劳动类型组成,主图表上有三种颜色。当我深入到下一张图表时,一些类别没有主要类别拥有的所有三种劳动力。因此,调色板中的第一种颜色被分配给该系列,即使它是上一张图表中的第二种颜色。如果可能的话,我想避免这种情况。

因此,第一个图表上的数据值是绿色的(颜色顺序中的第二个),下一个图表上的数据值是黄色的(颜色顺序中的第一个)。如何让图表“记住”第一个图表中的系列组总数?

这是 Reporting Services 2005。

【问题讨论】:

    标签: reporting-services reportingservices-2005


    【解决方案1】:

    您无法使用自定义调色板解决此问题。

    您可以在数据库中为劳动力类型分配颜色(使用 HEX 最简单)。然后将其传递到您的数据集中。然后将颜色属性设置为十六进制值。

    【讨论】:

    • 当然。这不是最漂亮的,但如果没有找到一种方法来为劳动类型分配颜色,我看不出你打算如何做到这一点。
    • 你必须在它到达任何子报表之前分配它。
    【解决方案2】:

    很遗憾,这是不可能的。这个我找了好久...

    【讨论】:

    • 你的评论让我很伤心。当然必须有一种自定义代码的方法......
    • 如果你找到它,请告诉我...我过去不得不这样做,但找不到任何解决方案。
    【解决方案3】:

    我能够解决这个问题,因为我使用了自定义调色板,实现为哈希表。我基本上将这些信息序列化并传递给子报表上的隐藏参数,然后重新填充数据结构。

    它并不完美,但现在可以使用。

    ' Define some globals, including the color palette '
    Private colorPalette As String() = _
        {"#FFF8A3", "#A9CC8F", "#B2C8D9", "#BEA37A", "#F3AA79", "#B5B5A9", "#E6A5A4", _
         "#F8D753", "#5C9746", "#3E75A7", "#7A653E", "#E1662A", "#74796F", "#C4384F", _
         "#F0B400", "#1E6C0B", "#00488C", "#332600", "#D84000", "#434C43", "#B30023"}
         ' color palette pulled from SAP guidelines '
         ' http://www.sapdesignguild.org/resources/diagram_guidelines/color_palettes.html '
    Private count As Integer = 0
    Private colorMapping As New System.Collections.Hashtable()
    ' Create a custom color palette '
    Public Function GetColor(ByVal groupingValue As String) As String
        If colorMapping.ContainsKey(groupingValue) Then
            Return colorMapping(groupingValue)
        End If
        Dim c As String = colorPalette(count Mod colorPalette.Length)
        count = count + 1
        colorMapping.Add(groupingValue, c)
        Return c
    End Function
    
    ' In custom actions of the data value, set the results of this '
    ' function to the mapping parameter in the next report '
    Public Function PassColorMapping() As String
        If colorMapping.Count = 0 Then
            Return Nothing
        End If
        Try
            ' convert the hashtable to an array so it can be serialized '
            Dim objHash As Object()() = ToJaggedArray(colorMapping)
    
            ' serialize the colorMapping variable '
            Dim outStream As New System.IO.StringWriter()
            Dim s As New System.Xml.Serialization.XmlSerializer(GetType(Object()()))
            s.Serialize(outStream, objHash)
    
            ' move on to the next report '
            Return outStream.ToString()
        Catch ex As Exception
            MsgBox(ex.Message)
        End Try
    End Function
    

    我遇到了一个问题,我找不到报告的 onLoad 事件的等效项。由于我不确定将这个膨胀代码放在哪里,所以我将它粘贴在绘图区域的背景颜色中。因此我总是返回“WhiteSmoke”。如果我能找到合适的位置,我会改变它。

    ' Call this function when the report loads to get the series groups '
    ' that have already been loaded into the custom color palette '
    ' Pass in the parameter used to store the color mapping '
    Public Function InflateParamMapping(ByVal paramMapping As Parameter) As String
        Try
            If paramMapping.Value Is Nothing Then
                Return "WhiteSmoke"
            ElseIf colorMapping.Count = 0 Then      
                Dim pXmlized As String = paramMapping.Value
                ' deserialize the mapping parameter '
                Dim s As New System.Xml.Serialization.XmlSerializer(GetType(Object()()))
    
                ' get the jagged array and convert to hashtable '
                Dim objHash As Object()() = DirectCast(s.Deserialize(New System.IO.StringReader(pXmlized)), Object()())
                ' stick the result in the global colorMapping hashtable '
                colorMapping = ToHashTable(objHash)
                count = colorMapping.Count
            End If
        Catch ex As Exception
    '       MsgBox(ex.Message) '
        End Try
        Return "WhiteSmoke"
    End Function
    

    ToJaggedArray() 和 ToHashTable() 是辅助函数,因为 HashTable 是不可序列化的,因为它们实现了 IDictionary。我很着急,所以我很快就把它们转换成了一个数组。代码来自 Mark Richman 撰写的 Collection Serialization in ASP.NET Web Services 文章。我将代码从 C# 转换为 VB.NET 以在报告中使用。

    Public Function ToJaggedArray(ByVal ht As System.Collections.HashTable) As Object()()
        Dim oo As Object()() = New Object(ht.Count - 1)() {}
        Dim i As Integer = 0
        For EAch key As Object in ht.Keys
            oo(i) = New Object() {key, ht(key)}
            i += 1
        Next
        Return oo
    End Function
    
    Public Function ToHashTable(ByVal oo As Object()()) As System.Collections.HashTable
        Dim ht As New System.Collections.HashTable(oo.Length)
        For Each pair As Object() In oo
            Dim key As Object = pair(0)
            Dim value As Object = pair(1)
            ht(key) = value
        Next
        Return ht
    End Function
    

    现在,您需要在报告本身中做几件事。

    • 在两个报告的报告属性中添加对System.Xml 的引用。
    • 在父报表的Actions中,将包含您的数据结构的参数设置为=Code.PassColorMapping()
    • 在报告的 绘图区 部分中,将此表达式作为背景:=Code.InflateParamMapping(Parameters!colorMapping)
    • 当然,在 Fill 中为您的数据 Series Style 在两个图表上输入以下表达式:=Code.GetColor(Fields!Type.Value)

    您可以继续为任意数量的子报表执行此操作 - 我目前有 3 个级别的钻取,并且效果很好。

    【讨论】:

    • 好吧,这是我应得的。现在想来,我想我可以将系列订单存储在数据库中,并使用该数字来查找颜色。当然,这肯定仍然需要清理。但是很高兴不碰我的数据库架构和我的查询。
    【解决方案4】:

    我很容易就解决了。

    在我的父报告中,我可以说 12 个系列字段,每个字段在图表中都有自己的颜色,在我的子报告中,我只是将所有系列保留在图表上,例如从柱形图到折线图使用向下钻取,但我控制它们的可见性...

    因此,在 Series Properties -> Visibility 的子报表中,我只需添加一个表达式: =(字段!ContentType.Value 参数!ContentType.Value)

    这样报告只保持点击值的可见性并隐藏所有其他值并且颜色保持不变:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多