Real Time with Local Data Circular Buffers
1Pesgo1.PeData.Subsets = 4;2Pesgo1.PeData.Points = 2000000;3 4// MouseWheelZooming shows frozen data, Example 145 MouseWheelZooming shows moving data5 6// New v10 feature CircularBuffers // Only applies to Append type features.7// Most beneficial with larger data sets and using AppendYData AppendXData8// combined with ComputerShader construction with StagingBuffers.9// CircularBuffers avoid having to shift existing data when appending.10// ComputeShader rendering block copies data so there is no penalty in accessing data11// to build the chart.12Pesgo1.PeData.CircularBuffers = true;13 14Pesgo1.PeData.DuplicateDataX = DuplicateData.PointIncrement;15int nX = 1;16for (int p = 0; p < 2000000; p++)17{18 MainWindow.MyXData146[p] = nX; // MyXData146 is app memory19 nX++;20}21 22// quickly create 8 million random y data points, sin function is slow23float[] MySubData0 = new float[8400];24float[] MySubData1 = new float[8400];25float[] MySubData2 = new float[8400];26float[] MySubData3 = new float[8400];27for (int p = 0; p < 8400; p++)28{29 MySubData0[p] = (float)(50 + (Math.Sin(p * 0.00075) * (0 + 1) * 30) + (Rand_Num.NextDouble() * 15));30 MySubData1[p] = (float)(50 + (Math.Sin(p * 0.00075) * (1 + 1) * 30) + (Rand_Num.NextDouble() * 15));31 MySubData2[p] = (float)(50 + (Math.Sin(p * 0.00075) * (2 + 1) * 30) + (Rand_Num.NextDouble() * 15));32 MySubData3[p] = (float)(50 + (Math.Sin(p * 0.00075) * (3 + 1) * 30) + (Rand_Num.NextDouble() * 15));33}34 35// MyYData146 is app memory36 37for (int j = 0; j < 1991600; j += 8400)38 Array.Copy(MySubData0, 0, MainWindow.MyYData146, j, 8400);39for (int j = 0; j < 1991600; j += 8400)40 Array.Copy(MySubData1, 0, MainWindow.MyYData146, j + 2000000, 8400);41for (int j = 0; j < 1991600; j += 8400)42 Array.Copy(MySubData2, 0, MainWindow.MyYData146, j + 4000000, 8400);43for (int j = 0; j < 1991600; j += 8400)44 Array.Copy(MySubData3, 0, MainWindow.MyYData146, j + 6000000, 8400);45 46// Provide local pointers to circular buffer data, data is not copied to chart // See example 145 that copies data to chart and circular buffer exists inside chart.47Pesgo1.PeData.X.UseDataAtLocation(MainWindow.MyXData146, 2000000);48Pesgo1.PeData.Y.UseDataAtLocation(MainWindow.MyYData146, 8000000);49// compare speed of example 145 to 146. 146 is faster. Likely because it's not copying memory but using app local memory.50 51// Set Manual Y scale // Avoiding cpu intensive searching for min max52Pesgo1.PeGrid.Configure.ManualScaleControlY = ManualScaleControl.MinMax;53Pesgo1.PeGrid.Configure.ManualMinY = -110;54Pesgo1.PeGrid.Configure.ManualMaxY = 220;55 56// Set Manual X scale // Avoiding cpu intensive searching for min max57Pesgo1.PeGrid.Configure.ManualScaleControlX = ManualScaleControl.MinMax;58Pesgo1.PeGrid.Configure.ManualMinX = 0;59Pesgo1.PeGrid.Configure.ManualMaxX = 2000000;60 61// Set Various Other Properties ///62Pesgo1.PeColor.BitmapGradientMode = false;63Pesgo1.PeColor.QuickStyle = QuickStyle.DarkNoBorder;64 65// Set various properties //66Pesgo1.PeString.MainTitle = "4 x 2 Million Real-Time Circular Buffer";67Pesgo1.PeString.SubTitle = "";68 69Pesgo1.PeConfigure.PrepareImages = true;70Pesgo1.PeConfigure.CacheBmp = true;71Pesgo1.PeFont.Fixed = true;72 73Pesgo1.PeColor.SubsetColors[0] = Color.FromArgb(255, 255, 0, 0);74Pesgo1.PeColor.SubsetColors[1] = Color.FromArgb(255, 0, 255, 0);75Pesgo1.PeColor.SubsetColors[2] = Color.FromArgb(255, 255, 255, 0);76Pesgo1.PeColor.SubsetColors[3] = Color.FromArgb(255, 0, 255, 255);77 78Pesgo1.PeConfigure.TextShadows = TextShadows.BoldText;81Pesgo1.PeFont.Label.Bold = true;82Pesgo1.PeFont.SizeGlobalCntl = 1.4F;83 84Pesgo1.PePlot.SubsetLineTypes[0] = LineType.ThinSolid;85Pesgo1.PePlot.SubsetLineTypes[1] = LineType.ThinSolid;86Pesgo1.PePlot.SubsetLineTypes[2] = LineType.ThinSolid;87Pesgo1.PePlot.SubsetLineTypes[3] = LineType.ThinSolid;88Pesgo1.PePlot.SubsetLineTypes[4] = LineType.ThinSolid;89 90Pesgo1.PePlot.Method = SGraphPlottingMethod.Line;91Pesgo1.PePlot.DataShadows = DataShadows.None;92 93Pesgo1.PeGrid.Configure.AutoMinMaxPaddingX = 0;94Pesgo1.PeConfigure.ImageAdjustLeft = 50;95Pesgo1.PeConfigure.ImageAdjustRight = 0;96 97Pesgo1.PeLegend.SimpleLine = true;99 100Pesgo1.PeUserInterface.Dialog.PlotCustomization = false;101Pesgo1.PeUserInterface.Dialog.Page2 = false;102Pesgo1.PeUserInterface.Allow.Popup = true;103Pesgo1.PeUserInterface.Dialog.Axis = false;104Pesgo1.PeUserInterface.Dialog.Subsets = true;105Pesgo1.PeUserInterface.Allow.TextExport = false;106Pesgo1.PeUserInterface.Dialog.AllowEmfExport = false;107Pesgo1.PeUserInterface.Dialog.AllowWmfExport = false;108 109Pesgo1.PeUserInterface.Menu.DataShadow = MenuControl.Hide;110Pesgo1.PeUserInterface.Menu.MarkDataPoints = MenuControl.Hide;111 112Pesgo1.PeConfigure.AntiAliasText = true;113Pesgo1.PeConfigure.AntiAliasGraphics = true;114 115// Allow MouseWheel Zooming //116Pesgo1.PeUserInterface.Scrollbar.ScrollingHorzZoom = true;117Pesgo1.PeUserInterface.Scrollbar.MouseWheelFunction = MouseWheelFunction.HorizontalZoom;118 119Pesgo1.PeConfigure.RenderEngine = RenderEngine.Direct3D;120 121Pesgo1.PeData.ComputeShader = true;122Pesgo1.PeData.StagingBufferX = true;123Pesgo1.PeData.StagingBufferY = true;124Pesgo1.PeData.Filter2D3D = true;125 126Pesgo1.PeSpecial.AutoImageReset = false;127Pesgo1.PeUserInterface.Cursor.HourGlassThreshold = 99999999;128 129Pesgo1.PeFunction.Force3dxVerticeRebuild = true;130Pesgo1.PeFunction.ReinitializeResetImage();131 132// Initialize Counters and Timer //133MainWindow.m_nRealTimeCounter = 2000000;134MainWindow.m_nSinCounter = 2000000;135 136MainWindow.Timer1.Interval = 15;137MainWindow.Timer1.Start();138 139/*140/////////////////////////141// Example Timer Event //142/////////////////////////143private void Timer1_Tick(object sender, System.EventArgs e)144{145 int nNewSamplesPerSubsetsPerTick = 150;146 147 // New y value and x value // Bock of memory subset0p0 subset0p1 subset0p2 subset0p3 subset0p4 subset1p0 subset1p0148 for (int s = 0; s < 4; s++)149 {150 for (int p = 0; p < nNewSamplesPerSubsetsPerTick; p++)151 {152 pNewY145[(s * nNewSamplesPerSubsetsPerTick) + p] = (float)(50 + (Math.Sin((m_nSinCounter + p) * 0.00075) * (s + 1) * 30) + (Rand_Num.NextDouble() * 15));153 }154 }155 for (int p = 0; p < nNewSamplesPerSubsetsPerTick; p++)156 {157 pNewX145[p] = m_nRealTimeCounter + p + 1;158 }159 160 // Append new values //161 Pesgo1.PeData.Y.AppendData(pNewY145, nNewSamplesPerSubsetsPerTick);162 Pesgo1.PeData.X.AppendData(pNewX145, nNewSamplesPerSubsetsPerTick);163 164 // Increment counter ///165 m_nRealTimeCounter = m_nRealTimeCounter + nNewSamplesPerSubsetsPerTick;166 167 // We initialized chart with manual Scaling, so we need to manually control x axis range.168 // For real-time with large data sets, manually scaling axes prevents the chart169 // from having to search for min-max ranges which is cpu intensive.170 171 Pesgo1.PeGrid.Configure.ManualMinX = m_nRealTimeCounter - 2000000;172 Pesgo1.PeGrid.Configure.ManualMaxX = m_nRealTimeCounter;173 174 m_nSinCounter = m_nSinCounter + nNewSamplesPerSubsetsPerTick;175 176 //if (Pesgo1.PeGrid.Zoom.Mode == true) // without this, one can zoom and see a stationary view of the data, else the view shifts177 //{178 // Pesgo1.PeGrid.Zoom.MaxX = Pesgo1.PeGrid.Zoom.MaxX + nNewSamplesPerSubsetsPerTick;179 // Pesgo1.PeGrid.Zoom.MinX = Pesgo1.PeGrid.Zoom.MinX + nNewSamplesPerSubsetsPerTick;180 //}181 182 Pesgo1.PeFunction.Force3dxVerticeRebuild = true;183 Pesgo1.PeFunction.ReinitializeResetImage(); // needed to update the x axis to latest extents184 Pesgo1.Invalidate();185 186 if (m_nSinCounter >= 135) { m_nSinCounter = 0; }187}188 189*/Pego1.PeData.Y[s, p]Click underlined properties to view documentation