如何解决如何在 DevExpress BootstrapChart 的不同窗格中分隔一组线系列?
现在,我正在使用 DevExpress BootstrapChart (v17.2.13.0) 开发 Web 应用程序,并且我已将控件与对象数据源绑定。以下是用于在图表中显示的示例数据:
这是我的目标:
- 图表将在不同的窗格中显示“ademand_im”和“rdemand_im”的值(我将它们命名为窗格“A”和“B”)
- 每个窗格的 X 轴为“data_time”(日期和时间),Y 轴为值(“ademand_im”或“rdemand_im”)
- 此外,每个窗格中的值将按“hardware_id”分组,因此,在这种情况下,每个窗格中应该有 2 行“83245551”和“88310991”(注意 “hardware_id”可以不时变化)。
所以图表应该是这样的:
但是,我目前唯一实现的是要么线系列在两个窗格中都显示但未分组或不显示图中的任何内容。
这是我的代码:
<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
变换后的表格是这样的:
这是我用来转换表格的函数代码(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 举报,一经查实,本站将立刻删除。