Hello Steema,
I am drawing an oscilloscope in realtime using FastLine series. I also need a special "accumulation" mode to visualize signal noise by drawing each incoming data set *without* removing any of the previous data already visible. Adding a new series each time my data (8K point set) changes is not an option in a realtime scenario. I tried the Error series, but it does not exactly give me the result I need. Do you have any ideas?
Thanks in advance
Philipp
P.S.
Another small question... How can I convert a mouse client coordinate inside the chart area (not series) to the corresponding chart view position? I need to position the cursor tool to the mouse click position...
Accumulation mode
Re: Accumulation mode
Hello Philipp,
Thanks,
Can you please send us a simple code with your data so we can try to find a solution for you? Also, I recommend you take a look in demo project,concretely, in All Features\Welcome !\Functions where there are a examples of function that can helpful for you.I am drawing an oscilloscope in realtime using FastLine series. I also need a special "accumulation" mode to visualize signal noise by drawing each incoming data set *without* removing any of the previous data already visible. Adding a new series each time my data (8K point set) changes is not an option in a realtime scenario. I tried the Error series, but it does not exactly give me the result I need. Do you have any ideas?
I recommend you use method CalcPosPoint(int value) of axes that returns the corresponding value of a Screen position.P.S.
Another small question... How can I convert a mouse client coordinate inside the chart area (not series) to the corresponding chart view position? I need to position the cursor tool to the mouse click position...
Thanks,
Best Regards,
Sandra Pazos / Development & Support Steema Software Avinguda Montilivi 33, 17003 Girona, Catalonia Tel: 34 972 218 797 http://www.steema.com |
Instructions - How to post in this forum |
Re: Accumulation mode
Hello Sandra,
thanks for your quick reply. I could not find sth. suitable in the demo projects. Here is some code, that should give you the basic idea:
Your second tip worked great
Thanks
thanks for your quick reply. I could not find sth. suitable in the demo projects. Here is some code, that should give you the basic idea:
Code: Select all
// Methods gets called whenever data is available
public void UpdateChannelData(string seriesName, double[] data)
{
var series = _oscilloscopeDataSeries[seriesName];
if (this.EnableAccumulation)
{
// TODO: I want to draw the new set of data while keeping all past series data visualized in the chart.
// I do not need the complete data and properties of all last series in memory, but just the graphics...
// Since this method gets called very often (every 30ms) I can not add a new series with approx. 8000 values
// each time. Is there some way to draw the updated series, without erasing the old series?
}
else
{
// simple: just reset old values and update the series with incoming data
series.Delete(0, series.Count);
series.Add(data);
}
Thanks
Re: Accumulation mode
I figured out how to do it, but it is rather cumbersome...
_accumulationBuffer must be the size of the chart area and updated /reset if scroll or zoom changes or chart size... And yes, this also comes with a performance penalty, but is a lot faster and memory friendly than adding a new series each time
the data changes...
If there is a more elegant / faster way please help me out
Thanks
Philipp
Code: Select all
void OnAfterDraw(object sender, Graphics3D g)
{
if (_enableAccumulationMode)
{
// 1) render current frame to accumulation buffer
using (Graphics gfx = Graphics.FromImage(_accumulationBuffer[0]))
{
g.BackBuffer.Render(gfx);
}
// 2) combine current frame with accumulation buffer
unsafe
{
int width = _accumulationBuffer[0].Width;
int height = _accumulationBuffer[0].Height;
var srcData =
_accumulationBuffer[0].LockBits(Rectangle.FromLTRB(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
var dstData =
_accumulationBuffer[1].LockBits(Rectangle.FromLTRB(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
int* srcPtr = (int*)srcData.Scan0;
int* dstPtr = (int*)dstData.Scan0;
HashSet<int> colorLut = new HashSet<int>();
foreach (var series in _osciDataChannels.Values)
{
colorLut.Add(series.Color.ToArgb());
}
for (int idx = 0; idx < height * width; idx++, srcPtr++, dstPtr++)
{
int srcValue = *srcPtr;
if (colorLut.Contains(srcValue))
{
*dstPtr = srcValue;
}
}
_accumulationBuffer[0].UnlockBits(srcData);
_accumulationBuffer[1].UnlockBits(dstData);
}
// 3) draw combined frame on top
g.Draw(0, 0, _accumulationBuffer[1]);
}
}
the data changes...
If there is a more elegant / faster way please help me out
Thanks
Philipp
Re: Accumulation mode
Hello Philipp,
Thanks for your code and your solution. I am glad that you have found a solution for your problem. On the other hand, to try to optimize your code would be very helpful for us if you can send your project.
Thanks,
Thanks for your code and your solution. I am glad that you have found a solution for your problem. On the other hand, to try to optimize your code would be very helpful for us if you can send your project.
Thanks,
Best Regards,
Sandra Pazos / Development & Support Steema Software Avinguda Montilivi 33, 17003 Girona, Catalonia Tel: 34 972 218 797 http://www.steema.com |
Instructions - How to post in this forum |