You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用InteractiveDataDisplay.WPF导出图像时系列未正常显示求助

解决InteractiveDataDisplay.WPF导出图表时Series不显示的问题

嘿,我看到你遇到了用InteractiveDataDisplay.WPF生成图表正常,但导出为图像时折线系列(Series)消失的问题,咱们来拆解一下原因和解决办法:

问题根源

你代码里的核心问题在于WPF中一个UI元素不能同时属于两个可视化树。你原本的lines Grid已经是原plotter Chart的子元素了,当你直接把它赋值给新创建的Bmain_Chart.Content时,WPF会自动将lines从原plotter的可视化树中移除,但这个过程并没有正确触发LineGraph的布局和渲染逻辑,导致新Chart渲染时无法显示这些折线系列。

解决方案

这里提供两种可行的解决思路:

方案一:直接渲染原有的Chart控件(推荐)

既然原界面的图表显示正常,我们可以直接渲染原有的plotter(或者它的父容器Grafico),不需要新建Chart实例。这样能完整保留所有已绘制的Series:

修改后的代码如下:

public MainWindow()
{
    InitializeComponent();
    double[] x = new double[200];
    for (int i = 0; i < x.Length; i++)
        x[i] = 3.1415 * i / (x.Length - 1);

    for (int i = 0; i < 25; i++)
    {
        var lg = new LineGraph();
        lines.Children.Add(lg);
        lg.Stroke = new SolidColorBrush(Color.FromArgb(255, 0, (byte)(i * 10), 0));
        lg.Description = String.Format("Data series {0}", i + 1);
        lg.StrokeThickness = 2;
        lg.Plot(x, x.Select(v => Math.Sin(v + i / 10.0)).ToArray());
    }

    int width = 800;
    int height = 600;

    // 给原plotter设置需要的标题(如果需要保留原界面标题,可以先保存再恢复)
    var originalLeftTitle = plotter.LeftTitle;
    var originalBottomTitle = plotter.BottomTitle;
    plotter.LeftTitle = "Bmain";
    plotter.BottomTitle = "Time";

    // 测量并排列原plotter控件,确保布局完成
    plotter.Measure(new Size(width, height));
    plotter.Arrange(new Rect(new Size(width, height)));
    plotter.UpdateLayout();

    // 渲染并导出
    RenderTargetBitmap bmp = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32);
    bmp.Render(plotter);

    var encoder = new PngBitmapEncoder();
    encoder.Frames.Add(BitmapFrame.Create(bmp));
    using (Stream stm = File.Create(@"c:\MyCustomPath\test.png"))
    {
        encoder.Save(stm);
    }

    // 恢复原界面的标题(可选)
    plotter.LeftTitle = originalLeftTitle;
    plotter.BottomTitle = originalBottomTitle;
}

方案二:重新创建Series到新Chart中

如果你确实需要创建新的Chart实例来导出,不要复用原有的lines容器,而是重新创建所有LineGraph并添加到新Chart中:

public MainWindow()
{
    InitializeComponent();
    double[] x = new double[200];
    for (int i = 0; i < x.Length; i++)
        x[i] = 3.1415 * i / (x.Length - 1);

    // 先在原界面绘制图表
    for (int i = 0; i < 25; i++)
    {
        var lg = new LineGraph();
        lines.Children.Add(lg);
        lg.Stroke = new SolidColorBrush(Color.FromArgb(255, 0, (byte)(i * 10), 0));
        lg.Description = String.Format("Data series {0}", i + 1);
        lg.StrokeThickness = 2;
        lg.Plot(x, x.Select(v => Math.Sin(v + i / 10.0)).ToArray());
    }

    int width = 800;
    int height = 600;

    // 创建新Chart并重新添加所有Series
    Chart Bmain_Chart = new Chart();
    Bmain_Chart.LeftTitle = "Bmain";
    Bmain_Chart.BottomTitle = "Time";

    // 创建新的容器Grid
    Grid newLines = new Grid();
    Bmain_Chart.Content = newLines;

    // 重新创建所有LineGraph并添加到新容器
    for (int i = 0; i < 25; i++)
    {
        var lg = new LineGraph();
        newLines.Children.Add(lg);
        lg.Stroke = new SolidColorBrush(Color.FromArgb(255, 0, (byte)(i * 10), 0));
        lg.Description = String.Format("Data series {0}", i + 1);
        lg.StrokeThickness = 2;
        lg.Plot(x, x.Select(v => Math.Sin(v + i / 10.0)).ToArray());
    }

    // 测量、排列并渲染
    Bmain_Chart.Measure(new Size(width, height));
    Bmain_Chart.Arrange(new Rect(new Size(width, height)));
    Bmain_Chart.UpdateLayout();

    RenderTargetBitmap bmp = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32);
    bmp.Render(Bmain_Chart);

    var encoder = new PngBitmapEncoder();
    encoder.Frames.Add(BitmapFrame.Create(bmp));
    using (Stream stm = File.Create(@"c:\MyCustomPath\test.png"))
    {
        encoder.Save(stm);
    }
}

效果验证

用方案一修改后,导出的图像应该会和原界面显示的图表完全一致,包含所有25条折线系列。

内容的提问来源于stack exchange,提问作者Ericson da Fonseca

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:16:40