マーカーを使用しているときに、D3 の ChartPlotter が表示されるのを待つのに非常に苦労しています。もちろん、Gazillion レコード (まあ、700,000 レコード) をプロットしようとしています。ラインだけを使用する場合は、すべて問題ありません (20 秒程度)。マーカーを使用する場合、5 分で話します。それは受け入れられません。
何か案は?
これが私が行ったことであり、その下に説明があります。
public static string MakeSimplePlot(double[][] xData, double[][] yData, string[] legend, string xAxisTitle, string yAxisTitle, bool[] showLines, bool[] showMarkers)
{
ChartPlotter plotter = new ChartPlotter();
plotter.MainHorizontalAxis = new HorizontalAxis();
plotter.MainVerticalAxis = new VerticalAxis();
HorizontalAxisTitle horizontalAxisTitle = new HorizontalAxisTitle();
horizontalAxisTitle.Content = xAxisTitle;
plotter.AddChild(horizontalAxisTitle);
VerticalAxisTitle verticalAxisTitle = new VerticalAxisTitle();
verticalAxisTitle.Content = yAxisTitle;
plotter.AddChild(verticalAxisTitle);
Color[] plotColors = new Color[13] { Colors.Blue, Colors.Red, Colors.Green, Colors.Chartreuse, Colors.Yellow, Colors.Violet, Colors.Tan, Colors.Silver, Colors.Salmon, Colors.Lime, Colors.Brown, Colors.Chartreuse, Colors.DarkGray };
for (int seriesCounter = 0; seriesCounter < legend.Count(); seriesCounter++)
{
DataFile clearedInputs = ClearExcess(new DataFile(xData[seriesCounter], yData[seriesCounter]));
xData[seriesCounter] = clearedInputs.time;
yData[seriesCounter] = clearedInputs.data;
var xDataSource = new EnumerableDataSource<double>(xData[seriesCounter]);
xDataSource.SetXMapping(x => x);
var yDataSource = new EnumerableDataSource<double>(yData[seriesCounter]);
yDataSource.SetYMapping(x => x);
CompositeDataSource plotSeries = new CompositeDataSource(xDataSource, yDataSource);
CirclePointMarker circlePointMarker = new CirclePointMarker();
circlePointMarker.Fill = new SolidColorBrush(plotColors[seriesCounter]);
circlePointMarker.Pen = new Pen(circlePointMarker.Fill, 0);
circlePointMarker.Size = (showMarkers[seriesCounter] == false) ? 0 : 8;
int lineWidth = (showLines[seriesCounter] == false) ? 0 : 2;
if (showMarkers[seriesCounter] == false)
{
plotter.AddLineGraph(plotSeries, new Pen(circlePointMarker.Fill, lineWidth), new PenDescription("Dummy"));
}
else
{
plotter.AddLineGraph(plotSeries, new Pen(circlePointMarker.Fill, lineWidth), circlePointMarker, new PenDescription("Dummy"));
}
}
UIParameters.plotWindow.mainGrid.Children.Clear();
UIParameters.plotWindow.mainGrid.RowDefinitions.Clear();
UIParameters.plotWindow.mainGrid.Children.Add(plotter);
plotter.Viewport.FitToView();
plotter.LegendVisible = false;
plotter.NewLegendVisible = false;
if (legend.Count() > 1)
{
ShowLegend(legend, plotColors);
}
UIParameters.plotWindow.WindowState = WindowState.Minimized;
UIParameters.plotWindow.WindowState = WindowState.Normal;
string filename = Path.ChangeExtension(Path.GetTempFileName(), "png");
RenderTargetBitmap targetBitmap = new RenderTargetBitmap((int)UIParameters.plotWindow.mainGrid.ActualWidth, (int)UIParameters.plotWindow.mainGrid.ActualHeight, 96d, 96d, PixelFormats.Default);
targetBitmap.Render(UIParameters.plotWindow.mainGrid);
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(targetBitmap));
using (var fileStream = File.Open(filename, FileMode.OpenOrCreate))
{
encoder.Save(fileStream);
UIParameters.plotWindow.mainGrid.Clip = null;
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
targetBitmap.Freeze();
if (targetBitmap != null) targetBitmap.Clear();
targetBitmap = null;
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
}
return filename;
}
説明:
- プロッターの凡例を非表示にし、ShowLegend を使用して独自の凡例を作成します。これは、凡例にマーカーしかないと表示されないためです (間違っていますか?)
- そうしないと、プロットが更新されないか、更新されてもファイルに保存されないため、プロット ウィンドウを最小化および最大化します。これは、ウィンドウを移動しても機能しますが (ある種の再描画イベントだと思います)、プロセスは自動であるため、ユーザーは操作を行いません。無効化を試みますが、無駄です。アイデア?
ありがとう!