微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在 DevExpress BootstrapChart 的不同窗格中分隔一组线系列?

如何解决如何在 DevExpress BootstrapChart 的不同窗格中分隔一组线系列?

现在,我正在使用 DevExpress BootstrapChart (v17.2.13.0) 开发 Web 应用程序,并且我已将控件与对象数据源绑定。以下是用于在图表中显示的示例数据:

enter image description here

这是我的目标:

  • 图表将在不同的窗格中显示“ademand_im”和“rdemand_im”的值(我将它们命名为窗格“A”和“B”)
  • 每个窗格的 X 轴为“data_time”(日期和时间),Y 轴为值(“ademand_im”或“rdemand_im”)
  • 此外,每个窗格中的值将按“hardware_id”分组,因此,在这种情况下,每个窗格中应该有 2 行“83245551”和“88310991”(注意 “hardware_id”可以不时变化)。

所以图表应该是这样的:

enter image description here

但是,我目前唯一实现的要么线系列在两个窗格中都显示但未分组不显示图中的任何内容

这是我的代码

<dx:BootstrapChart ID="chart" ClientInstanceName="chart" runat="server" 
    DataSourceID="ods_ChartData" Height="640px" TitleText="Chart Data" CrosshairEnabled="true" Panes="A,B">
    <ClientSideEvents Init="OnChartinit" />
    <SettingsToolTip Shared="true" Enabled="true" OnClientCustomizetooltip="ChartToolTip" />
    <ArgumentAxis ArgumentType="System.DateTime" GridVisible="True" MinorGridVisible="True" 
        TickVisible="True" MinorTickVisible="True" TickInterval="1" MinorTickCount="3" TitleText="Date">
        <Label displayMode="Rotate" RotationAngle="-0" Format-Formatter="FormatDate" />
    </ArgumentAxis>
    <ValueAxisCollection>
        <dx:BootstrapChartValueAxis Pane="A" TitleText="ademand_im" />
        <dx:BootstrapChartValueAxis Pane="B" TitleText="rdemand_im" />
    </ValueAxisCollection>
    <SettingsCommonSeries Type="Line" ArgumentField="data_time" Point-Size="0" />
    <SettingsSeriestemplate NameField="hardware_id" />
    <SeriesCollection>
        <dx:BootstrapChartLineseries Pane="A" ValueField="ademand_im" />
        <dx:BootstrapChartLineseries Pane="B" ValueField="rdemand_im" />
    </SeriesCollection>
</dx:BootstrapChart>

在此代码中,如果我删除“SettingsSeriestemplate”行,数据将显示在两个窗格中,但仅在每个窗格中的一行中显示。但是,如果我保留这条线,图表将不会显示任何内容

解决方法

在我尝试了解此控件的工作原理后,我发现的唯一解决方案是我必须将“hardware_id”列转换为“ademand_im”和“rdemand_im”值,这可能不是理想的值。

因此,该表不应具有“hardware_id”、“ademand_im”和“rdemand_im”列,而应转换为“ademand_im_83245551”、“ademand_im_88310991”、“rdemand_im_83245551”和“rdemand_im_883109”列。p9

变换后的表格是这样的:

enter image description here

这是我用来转换表格的函数代码(VB.NET):

<Extension()>
Public Function PivotDataTableColumnGroup(srcData As DataTable,rowGroupField As String,pivotColumnField As String,valueGroupFields As IEnumerable(Of String),Optional ValueGroupColumnName As Func(Of String,String,String) = Nothing,Optional otherFields As IEnumerable(Of String) = Nothing,Optional GetOtherFieldValue As Func(Of DataTable,Object,Object) = Nothing
                                            ) As DataTable
    Dim groupValueList As List(Of Object) = srcData.GetDistinctValuesByColumnName(rowGroupField)
    Dim pivotValueList As List(Of Object) = srcData.GetDistinctValuesByColumnName(pivotColumnField)
    Dim hasOtherFieldColumn As Boolean = Not (otherFields Is Nothing Or GetOtherFieldValue Is Nothing)

    Dim dt As New DataTable
    With dt
        .Columns.Add(rowGroupField,srcData.Columns(rowGroupField).DataType)
        For i As Integer = 0 To valueGroupFields.Count - 1
            For j As Integer = 0 To pivotValueList.Count - 1
                Dim columnName As String = GetColumnNameFromGroupFieldAndPivotValues(valueGroupFields(i),pivotValueList(j),ValueGroupColumnName)
                dt.Columns.Add(columnName,srcData.Columns(valueGroupFields(i)).DataType)
            Next
        Next
        If hasOtherFieldColumn Then
            For i As Integer = 0 To otherFields.Count - 1
                .Columns.Add(otherFields(i),srcData.Columns(otherFields(i)).DataType)
            Next
        End If

        For i As Integer = 0 To groupValueList.Count - 1
            Dim currentGroupValue As Object = groupValueList(i)
            Dim dr As DataRow = dt.NewRow()
            dr(rowGroupField) = currentGroupValue
            If hasOtherFieldColumn Then
                For j As Integer = 0 To otherFields.Count - 1
                    dr(otherFields(j)) = DBNullIfNothing(GetOtherFieldValue(srcData,otherFields(j),currentGroupValue))
                Next
            End If
            For j As Integer = 0 To valueGroupFields.Count - 1
                Dim currentField As String = valueGroupFields(j)
                For k As Integer = 0 To pivotValueList.Count - 1
                    Dim currentPivotValue As Object = pivotValueList(k)
                    Dim columnName As String = GetColumnNameFromGroupFieldAndPivotValues(valueGroupFields(j),pivotValueList(k),ValueGroupColumnName)
                    Dim value As Object = (From row In srcData.AsEnumerable
                                            Where row(rowGroupField) = currentGroupValue _
                                                    AndAlso row(pivotColumnField) = currentPivotValue
                                            Select row(currentField)
                                            ).FirstOrDefault
                    dr(columnName) = DBNullIfNothing(value)
                Next
            Next
            dt.Rows.Add(dr)
        Next
    End With
    Return dt
End Function

<Extension()>
Public Function GetDistinctValuesByColumnName(dt As DataTable,columnName As String) As List(Of Object)
    Dim valueList As List(Of Object) = (From row As DataRow In dt.AsEnumerable
                                        Where Not IsDBNull(row(columnName))
                                        Order By row(columnName)
                                        Select row(columnName) Distinct
                                        ).ToList
    Return valueList
End Function

Private Function GetColumnNameFromGroupFieldAndPivotValues(groupField As String,pivotValue As Object,String) = Nothing) As String
    Dim columnName As String = groupField & "_" & pivotValue.ToString()
    If ValueGroupColumnName IsNot Nothing Then
        columnName = ValueGroupColumnName(groupField,pivotValue)
    End If
    Return columnName
End Function

Public Function DBNullIfNothing(o As Object) As Object
    If o Is Nothing Then Return DBNull.Value
    Return o
End Function

这就是我使用该函数转换表格的方式:

Dim chartData As DataTable = result.PivotDataTableColumnGroup("data_time","hardware_id",{"ademand_im","rdemand_im"},Nothing,Nothing)
ResultChartData = chartData     'Stored in ASPxHiddenField in JSON form

之后,我必须在后面的代码中手动添加图表系列,而不是在 aspx 文件中设置图表系列属性:

Private Sub chart_LoadProfile_DataBound(sender As Object,e As EventArgs) Handles chart_LoadProfile.DataBound
    Using ResultChartData
        Dim seriesList As List(Of String) = (From col As DataColumn In ResultChartData.Columns
                                                Where col.ColumnName <> "data_time"
                                                Order By col.ColumnName
                                                Select col.ColumnName
                                        ).ToList
        Dim hardWardCount As Integer = (From s In seriesList Where s.Contains("ademand_im_")).Count
        Dim showInLegend As Boolean = hardWardCount > 1
        With chart_LoadProfile.SeriesCollection
            .Clear()
            For i As Integer = 0 To seriesList.Count - 1
                Dim fieldName As String = seriesList(i)
                Dim hardwareId As String = seriesList(i).Split("_")(2)
                Dim series As New BootstrapChartLineSeries
                With series
                    .ArgumentField = "data_time"
                    .ValueField = fieldName
                    .Point.Size = 0
                    .ShowInLegend = showInLegend
                    If fieldName.Contains("ademand_im_") Then
                        .Pane = "A"
                        .Name = "kW - " & hardwareId
                    Else
                        .Pane = "B"
                        .Name = "kVar - " & hardwareId
                    End If
                End With
                .Add(series)
            Next
        End With
    End Using
End Sub

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。