Hi,
I wonder if there is a way of modifying the Z-Index/render priority of individual points in a XyScatterRenderableSeries based on a value in the metadata.
I have a chart with tons of datapoints (anything between 100k -2M points) and they are plotted very close to each other in X/Y. I’m also using a custom pointmaker to color and resize the points based on a value in the metadata.
Even when using ResamplingMode.None, some points are automatically “optimized” away (not rendered). I’d like a way of setting a render priority based on a value in the metadata so the points with higher values are rendered on top of the ones of lower values. Or the ones with lower values are “optimized away” first. Can this be done?
- Jonathan Janesjö asked 9 years ago
- last edited 8 years ago
- You must login to post comments
Hey Andrew,
Sorry for the late reply, it took me a while to be able to circle back to this problem and test your solution. Well, it works! …but with a few modifications:
- The EndBatch needed to be an override instead of a virtual.
- I didn’t notice any difference in calling the base.EndBatch or not, so I kept it on.
- The base.BeginBatch needs to be on otherwise I ended up without any points at all.
The graph seems now to not optimize any points out of existence (as intended) at a slight performance cost, but we can live with it.
Thanks for the help.
/D
- Jonathan Janesjö answered 8 years ago
-
Great, glad it works :) We also have the task in our queue to Enable/Disable clustering for v4.1 of SciChart.
- You must login to post comments
Hi Daniel,
Very good question. In SciChart v4 by default we enable clustering, which prevents a PointMarker from being drawn to the same location twice. This cannot be turned off.
Obviously in our own PointMarker implementations you are going to be drawing the same shape, same size each time. On pen (color) change we automatically reset the cluster so with our own PointMarkers there is zero visual loss but a big performance increase by preventing overdraw.
In a custom PointMarker (drawing different sizes or shapes per point) the clustering algorithm could mistakenly cull a large PointMarker in front of a small one, resulting in visual loss (a bad thing).
What you could do if you are implementing BasePointMarker is to override the batching / clusting algorithm. For instance:
public class DrawsEverythingPointMarker : BasePointMarker
{
private List<Point> _points;
public override void BeginBatch(IRenderContext2D context, Color? strokeColor, Color? fillColor)
{
context.SetPrimitvesCachingEnabled(true);
// Don't call base
// base.BeginBatch(context, strokeColor, fillColor);
// Todo: potentially you could re-use this memory or initialize with a capacity
_points = new List<Point>();
}
public override void Draw(IRenderContext2D context, IEnumerable<Point> centers)
{
// TODO: your drawing here
}
public virtual void MoveTo(IRenderContext2D context, double x, double y, int index)
{
// Set pixel as marked to draw.
// If out of bounds, skip.
if (IsInBounds(x, y))
{
_points.Add(new Point(x,y));
}
}
public virtual void EndBatch(IRenderContext2D context)
{
Draw(context, _points);
context.SetPrimitvesCachingEnabled(false);
// Don't call base
// base.EndBatch(context);
}
}
Try that, I haven’t tested it but looking at the code it should disable clustering for your custom BasePointMarker. It will draw everything.
Give it a test and if you have any problems or questions, just ask.
Best regards,
Andrew
- Andrew Burnett-Thompson answered 9 years ago
- You must login to post comments
Please login first to submit.