如何在DevExpress BootstrapChart不同窗格中实现折线序列分组展示?
问题根源
你出现该问题的核心原因是混用了固定系列配置(SeriesCollection节点)和动态系列模板(SettingsSeriesTemplate节点),二者在DevExpress BootstrapChart中是互斥的工作模式:
- 保留
SettingsSeriesTemplate时,控件会忽略你手动定义的固定系列,但你没有为动态生成的系列指定值字段、所属窗格等核心配置,导致图表无法渲染数据,显示为空。 - 删除
SettingsSeriesTemplate时,控件仅读取你定义的两个固定系列,没有按hardware_id做数据拆分和过滤,因此每个窗格只会展示所有硬件汇总后的单条折线。
解决方案
推荐两种适配你需求的实现方式,均可支持hardware_id动态变化的场景:
方案1:后端动态生成系列(兼容性更好,适合v17.2老版本)
无需使用SettingsSeriesTemplate,直接在图表的数据绑定事件中动态生成所有系列:
- 先修改前端控件配置,删除
SettingsSeriesTemplate节点和原有的SeriesCollection节点,给控件添加数据绑定事件:
<dx:BootstrapChart ID="chart" ClientInstanceName="chart" runat="server" DataSourceID="ods_ChartData" Height="640px" TitleText="Chart Data" CrosshairEnabled="true" Panes="A,B" OnDataBound="chart_DataBound"> <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" /> </dx:BootstrapChart>
- 后端添加数据绑定事件处理逻辑,遍历所有不重复的
hardware_id,逐个生成对应两个窗格的系列:
protected void chart_DataBound(object sender, EventArgs e) { // 从数据源获取所有不重复的硬件ID,注意替换为你实际的数据源类型 var rawData = ods_ChartData.Select() as IEnumerable<你的数据源实体类>; var distinctHardwareIds = rawData.Select(d => d.hardware_id).Distinct().ToList(); // 清空已有系列避免重复生成 chart.SeriesCollection.Clear(); foreach (var hardwareId in distinctHardwareIds) { // 生成A窗格对应ademand_im的系列 var seriesA = new BootstrapChartLineSeries(); seriesA.Name = $"{hardwareId} - ademand_im"; seriesA.ValueField = "ademand_im"; seriesA.Pane = "A"; // 过滤当前硬件ID的专属数据 seriesA.FilterExpression = $"[hardware_id] = '{hardwareId}'"; chart.SeriesCollection.Add(seriesA); // 生成B窗格对应rdemand_im的系列 var seriesB = new BootstrapChartLineSeries(); seriesB.Name = $"{hardwareId} - rdemand_im"; seriesB.ValueField = "rdemand_im"; seriesB.Pane = "B"; seriesB.FilterExpression = $"[hardware_id] = '{hardwareId}'"; chart.SeriesCollection.Add(seriesB); } }
方案2:客户端动态配置系列(无需后端代码,适合纯前端配置场景)
保留SettingsSeriesTemplate,通过客户端自定义系列事件配置每个动态生成系列的参数:
- 修改前端
SettingsSeriesTemplate配置,添加自定义系列事件:
<SettingsSeriesTemplate NameField="hardware_id" OnClientCustomizeSeries="customizeChartSeries" />
- 移除原有的固定
SeriesCollection节点,添加对应的JS处理函数:
function customizeChartSeries(s, e) { // 每个硬件ID生成两个系列,分别对应两个指标和不同窗格 return [ { name: e.name + " - ademand_im", valueField: "ademand_im", pane: "A", type: "line" }, { name: e.name + " - rdemand_im", valueField: "rdemand_im", pane: "B", type: "line" } ]; }
内容的提问来源于stack exchange,提问作者Pawich S.
相关产品推荐
相关产品推荐

