public TimeStampDataEntity(PlotManager plotManager, DataEntityInfo dataInfo, int sampleCount) : base(plotManager, dataInfo)
        {
            _samplesInChart       = 0;
            _singleSamplePlotMode = (sampleCount == 1);
            if (_singleSamplePlotMode)
            {
                _timeStamps  = new List <DateTime>(dataInfo.Capacity);
                _blockCounts = null;
                _isEven      = true;
            }
            else
            {
                _timeStamps  = new List <DateTime>(dataInfo.Capacity / sampleCount);
                _blockCounts = new List <int>(dataInfo.Capacity / sampleCount);
                _isEven      = true;
            }

            _yBuffers = new List <OverLapWrapBuffer <TDataType> >(DataInfo.LineCount);
            for (int i = 0; i < DataInfo.LineCount; i++)
            {
                _yBuffers.Add(new OverLapWrapBuffer <TDataType>(DataInfo.Capacity));
            }

            _plotBuffer = new PlotBuffer <TDataType>(DataInfo.LineCount, DataInfo.Capacity);
        }
Example #2
0
 public StringDataEntity(PlotManager plotManager, DataEntityInfo dataInfo) : base(plotManager, dataInfo)
 {
     _xBuffer  = new OverLapStrBuffer(DataInfo.Capacity);
     _yBuffers = new List <OverLapWrapBuffer <TDataType> >(DataInfo.LineCount);
     for (int i = 0; i < DataInfo.LineCount; i++)
     {
         _yBuffers.Add(new OverLapWrapBuffer <TDataType>(DataInfo.Capacity));
     }
     _plotBuffer = new PlotBuffer <TDataType>(DataInfo.LineCount, DataInfo.Capacity);
 }
        public ParallelHandler(DataEntity dataEntity, DataCheckParameters dataCheckParams)
        {
            this._dataEntity      = dataEntity;
            this._buffer          = dataEntity.PlotBuf;
            this._option          = new ParallelOptions();
            this._indexOffset     = 0;
            this._dataCheckParams = dataCheckParams;
            // 计算限制型配置并行度为内核个数
            _option.MaxDegreeOfParallelism = Environment.ProcessorCount;

            this._maxDatas = new double[_option.MaxDegreeOfParallelism];
            this._minDatas = new double[_option.MaxDegreeOfParallelism];
        }
Example #4
0
        public IndexDataEntity(PlotManager plotManager, DataEntityInfo dataInfo) : base(plotManager, dataInfo)
        {
            _plotManager     = plotManager;
            this._startIndex = _plotManager.StartIndex;
            this._nextIndex  = _plotManager.StartIndex;

            this._plotBuffer = new PlotBuffer <TDataType>(DataInfo.LineCount, DataInfo.Capacity);

            _yBuffers = new List <OverLapWrapBuffer <TDataType> >(DataInfo.LineCount);
            for (int i = 0; i < DataInfo.LineCount; i++)
            {
                _yBuffers.Add(new OverLapWrapBuffer <TDataType>(DataInfo.Capacity));
            }
        }
        // TODO 后期优化,记录当前Series的Plot范围,然后再判断是否需要重新Plot

        // 在begin和end区间内绘制单条曲线,分区视图使用。如果forceRefresh为true时(调用Plot方法时)始终更新绘图。

        // 如果forceRefresh为false时(用户进行缩放等操作时)如果判断数据区间和原来的兼容(稀疏比相同且是上次绘图范围的子集则无需更新)

        // 使用forceRefresh是为了避免在数据量过大,用户缩放后拖动滚动条会比较卡顿的问题

        internal void PlotDataInRange(double beginXValue, double endXValue, int seriesIndex, bool forceRefresh, bool isLogView)
        {
            int        lineIndex;
            DataEntity dataEntity = GetDataEntityBySeriesIndex(seriesIndex, out lineIndex);

            if (null == dataEntity)
            {
                return;
            }

            bool isNeedRefreshPlot = dataEntity.FillPlotDataInRange(beginXValue, endXValue, forceRefresh, lineIndex, isLogView);

            if (isNeedRefreshPlot)
            {
                PlotBuffer plotBuffer = dataEntity.PlotBuf;
                if (PlotSeries[seriesIndex].Points.Count == plotBuffer.PlotSize)
                {
                    for (int i = 0; i < plotBuffer.PlotSize; i++)
                    {
                        double yValue = plotBuffer.YPlotBuffer[lineIndex][i];
                        PlotSeries[seriesIndex].Points[i].SetValueXY(plotBuffer.XPlotBuffer[i], yValue);
                        if (PlotSeries[seriesIndex].Points[i].IsEmpty && !double.IsNaN(yValue))
                        {
                            PlotSeries[seriesIndex].Points[i].IsEmpty = false;
                        }
                    }
                }
                else
                {
                    IList <double> xDataBuf = plotBuffer.GetXPlotDataCollection();
                    IList <double> yDataBuf = plotBuffer.GetYPlotDataCollection(lineIndex);
                    PlotSeries[seriesIndex].Points.DataBindXY(xDataBuf, yDataBuf);
                }
                // 如果有校验Nan数据,则将标记为Nan数据的点不显示
                if (DataCheckParams.CheckNaN)
                {
                    HideNanDataPoint(seriesIndex);
                }
                //if (dataEntity.DataInfo.XDataType != XDataType.Number)
                //{
                //    RefreshTimeToXLabel(seriesIndex);
                //}
            }
        }
        // 在begin和end区间内绘制所有曲线,在主视图使用。如果forceRefresh为true时(调用Plot方法时)始终更新绘图。
        // 如果forceRefresh为false时(用户进行缩放等操作时)如果判断数据区间和原来的兼容(稀疏比相同且是上次绘图范围的子集则无需更新)
        // 使用forceRefresh是为了避免在数据量过大,用户缩放后拖动滚动条会比较卡顿的问题
        internal void PlotDataInRange(double beginXValue, double endXValue, bool forceRefresh, bool isLogView)
        {
            int seriesIndex = 0;

            foreach (DataEntity dataEntity in PlotDatas)
            {
                // 根据begin和end的范围,将数据填充到PlotBuffer中。如果无需更新绘图则返回false。
                bool       isNeedRefreshPlot = dataEntity.FillPlotDataInRange(beginXValue, endXValue, forceRefresh, -1, isLogView);
                PlotBuffer plotBuffer        = dataEntity.PlotBuf;
                if (isNeedRefreshPlot)
                {
                    bool pointCountChanged = false;
                    for (int i = seriesIndex; i < seriesIndex + dataEntity.DataInfo.LineNum; i++)
                    {
                        if (PlotSeries[i].Points.Count != plotBuffer.PlotSize)
                        {
                            pointCountChanged = true;
                            break;
                        }
                    }
                    //如果点的个数和上次相同,则直接使用PlotBuffer的数据直接更新点的数据
                    if (!pointCountChanged)
                    {
                        for (int lineIndex = 0; lineIndex < dataEntity.DataInfo.LineNum; lineIndex++)
                        {
                            for (int i = 0; i < plotBuffer.PlotSize; i++)
                            {
                                double yValue = plotBuffer.YPlotBuffer[lineIndex][i];
                                PlotSeries[seriesIndex].Points[i].SetValueXY(plotBuffer.XPlotBuffer[i], yValue);
                                if (PlotSeries[seriesIndex].Points[i].IsEmpty && !double.IsNaN(yValue))
                                {
                                    PlotSeries[seriesIndex].Points[i].IsEmpty = false;
                                }
                            }
                            // 如果有校验Nan数据,则将标记为Nan数据的点不显示
                            if (DataCheckParams.CheckNaN)
                            {
                                HideNanDataPoint(seriesIndex);
                            }
                            seriesIndex++;
                        }
                    }
                    // 如果点的个数和上次不同,则使用数据绑定,则获取当前点的数据集合,直接绑定点的数据到Chart
                    else
                    {
                        IList <double>          xDataBuf = plotBuffer.GetXPlotDataCollection();
                        IList <IList <double> > yDataBuf = plotBuffer.GetYPlotDataCollections();
                        for (int lineIndex = 0; lineIndex < dataEntity.DataInfo.LineNum; lineIndex++)
                        {
                            PlotSeries[seriesIndex].Points.DataBindXY(xDataBuf, yDataBuf[lineIndex]);
                            // 如果有校验Nan数据,则将标记为Nan数据的点不显示
                            if (DataCheckParams.CheckNaN)
                            {
                                HideNanDataPoint(seriesIndex);
                            }
                            seriesIndex++;
                        }
                    }
                }
                else
                {
                    seriesIndex += dataEntity.DataInfo.LineNum;
                }
            }
        }
Example #7
0
            public List <PlotItemGroup> RenderAllGroups(StackPanel panel, double plotHeight)
            {
                // first access
                var res = new List <PlotItemGroup>();

                if (panel == null)
                {
                    return(null);
                }
                panel.Children.Clear();

                // before applying arguments
                _autoScaleX = true;
                _autoScaleY = true;

                // go over all groups
                ScottPlot.WpfPlot lastPlot = null;
                foreach (var groupPI in GetItemsGrouped())
                {
                    // start new group
                    var pvc = new WpfPlotViewControlHorizontal();
                    pvc.Text = "Single value plot";
                    if (groupPI.Group >= 0 && groupPI.Group < 9999)
                    {
                        pvc.Text += $"; grp={groupPI.Group}";
                    }
                    var wpfPlot = pvc.WpfPlot;

                    // some basic attributes
                    lastPlot = wpfPlot;
                    wpfPlot.plt.AntiAlias(false, false, false);
                    wpfPlot.AxisChanged += (s, e) => WpfPlot_AxisChanged(wpfPlot, e);
                    groupPI.WpfPlot      = wpfPlot;
                    res.Add(groupPI);

                    // for all wpf / all signals
                    pvc.Height       = plotHeight;
                    pvc.ButtonClick += WpfPlot_ButtonClicked;

                    // for each signal
                    double?yMin = null, yMax = null;

                    foreach (var pi in groupPI)
                    {
                        // value
                        var val = pi.SME?.ValueAsDouble();

                        // integrate args
                        if (pi.Args != null)
                        {
                            if (pi.Args.ymin.HasValue)
                            {
                                yMin = Nullable.Compare(pi.Args.ymin, yMin) > 0 ? pi.Args.ymin : yMin;
                            }

                            if (pi.Args.ymax.HasValue)
                            {
                                yMax = Nullable.Compare(yMax, pi.Args.ymax) > 0 ? yMax : pi.Args.ymax;
                            }
                        }

                        // prepare data
                        var pb = new PlotBuffer();
                        pi.Buffer = pb;

                        // factory new Plottable
                        pb.Plottable = wpfPlot.plt.PlotSignal(pb.BufferData, label: "" + pi.DisplayPath);
                        pb.Push(val.HasValue ? val.Value : 0.0);
                    }

                    // apply some more args to the group
                    if (yMin.HasValue)
                    {
                        wpfPlot.plt.Axis(y1: yMin.Value);
                        _autoScaleY = false;
                    }

                    if (yMax.HasValue)
                    {
                        wpfPlot.plt.Axis(y2: yMax.Value);
                        _autoScaleY = false;
                    }

                    // render the plot into panel
                    wpfPlot.plt.Legend(fontSize: 9.0f);
                    panel.Children.Add(pvc);
                    wpfPlot.Render(skipIfCurrentlyRendering: true);
                }

                // for the last plot ..
                if (lastPlot != null)
                {
                    lastPlot.plt.XLabel("Samples");
                }

                // return groups for notice
                return(res);
            }