SciChart® the market leader in Fast WPF Charts, WPF 3D Charts, and iOS Chart & Android Chart Components

Welcome to the SciChart Community Forums!

Please use the forums below to ask questions about SciChart. Take a moment to read our Question asking guidelines on how to ask a good question and our support policy. We also have a tag=SciChart on Stackoverflow.com where you can earn rep for your questions!

Please note: SciChart team will only answer questions from customers with active support subscriptions. Expired support questions will be ignored. If your support status shows incorrectly, contact us and we will be glad to help.

0
1

Good day,

I have an interesting requirement that I cannot make work. I am trying to define 3 charts, all using the same X-Axis of time. Each chart shows a different piece of data related to a point-set; the actual Value, the Rate of change, and the Sigma (error value) for the calculation. I need to use your DataPointSelectionModifier to select sections of the data from any of the 3 charts, and have the state of selection reflect in all 3.

To do this, I have a PointViewModel that has the 3 data points, plus the timestamp and the implementation of IPointMetadata that provides IsSelected. I use a helper to use this to create 3 DataSeries that are bound to each of 3 SciChartSurfaces. This all works fine.

The issue resides in the behavior of the modifier. Single point selection seems to work, but when a box is drawn on any of the charts, the points that are actually selected are sporadic. Run the attached project to see the behavior. I have tried to capture the behavior in a couple of screenshots.

I have tried playing with various sequences of the modifiers, ReceiveHandledEvents settings, and mousegroupings (which sounds a little like mouse droppings 🙂 but I can’t figure it out.

Please advise what I can do to provide this behavior.

Thanks,
Mike.

Version
4.0.8578
Images
  • Michael Dusoe
    This must be a challenge – the natives are suspiciously quiet :)
  • Andrew
    The natives haven’t had a chance to look yet :) I must be honest, first comment is ‘please try upgrading to the latest version to see if the problem still exists’. After that, if problem still exists, when we get a moment we will look into it.
  • Michael Dusoe
    Andrew – as it happens, I upgraded to 4.2.0.9227 from your NuGet repo just after I submitted this, since I needed the SelectedPointMarker property on the ViewModels, and I saw that it was added roughly a week ago. And yes, I am still seeing this behavior.
  • Michael Dusoe
    Ummm, where did the content of this message go??
  • Andrew
    Glitch in the matrix! It’s back I think. Markiyan on our team is investigating as we speak. Best regards, Andrew
  • You must to post comments
0
0

Hi Michael,

The inbuilt behavior of mouse event sharing is pretty simple. It just sends the same point over to all the modifiers. It doesn’t work in your case, surely – all your surfaces are of different height.

So a possible solution is a custom modifier which does scaling of Y coordinate relative to the original chart’s height. I’ve drafted a simple implementation (which works though) for you as an example:

    public class DataPointSelectionModifierEx : DataPointSelectionModifier
{
    public override void OnModifierMouseDown(ModifierMouseArgs e)
    {
        if (!e.IsMaster)
        {
            e.MousePoint = TransformRelativeToMaster(e.MousePoint, e.Source as IChartModifier);
        }

        base.OnModifierMouseDown(e);
    }

    private Point TransformRelativeToMaster(Point originalPoint, IChartModifier masterModifier)
    {
        var height = masterModifier.YAxis.Height;
        var scale = originalPoint.Y / height;

        var currY = YAxis.Height*scale;

        return new Point(originalPoint.X, currY);
    }

    public override void OnModifierMouseMove(ModifierMouseArgs e)
    {
        if (!e.IsMaster)
        {
            e.MousePoint = TransformRelativeToMaster(e.MousePoint, e.Source as IChartModifier);
        }

        base.OnModifierMouseMove(e);
    }

    public override void OnModifierMouseUp(ModifierMouseArgs e)
    {
        if (!e.IsMaster)
        {
            e.MousePoint = TransformRelativeToMaster(e.MousePoint, e.Source as IChartModifier);
        }

        base.OnModifierMouseUp(e);
    }
}

ModifierMouseArgs.IsMaster indicates whether this modifier belongs to the chart where the mouse event occurred. ModifierMouseArgs.Source gets the “master” modifier from that chart.

Hope this code gives you the idea. Please let us know if you have any complications with it,

Best regards,
Yuriy

  • You must to post comments
0
0

Yuriy,

That solution didn’t quite work, and I think I now understand why… For any given point, each of the 3 modifiers are pointing at the same Metadata object. It doesn’t matter if the “box” of selection is translated correctly, any time a single point is selected in one plot but not selected in another, I create a race condition of sorts, because now there are 3 instances trying to update the same IsSelected property.

However, your response was very insightful. I think I have solved this by using the IsMaster property in a different way. I only allow the mouse events to be handled if the sender is the master! This way, the selected points are always in relation to the box being drawn, and the “selectedness” is propagated to the other 2 plots after a ParentSurface.Invalidate call. The only trouble I ran into was that each Modifier has its own SelectedPointMarkers collection, so I have to clear them all out on Mouse down to ensure no linger points stick around.

Honestly, I think the root of the problem is that I am trying to use a modifier that shouldn’t share mouse events in a ModifierGroup that is set to share mouse events. I haven’t seen any solution to that problem, but this seems to work pretty well.

Anyway, here is the final result:

public class DataPointSelectionModifierEx : DataPointSelectionModifier
{

    public override void OnModifierMouseDown(ModifierMouseArgs e)
    {
        foreach (var pt in SelectedPointMarkers)
        {
            pt.DataPointMetadata.IsSelected = false;
        }

        if (e.IsMaster)
            base.OnModifierMouseDown(e);
    }

    public override void OnModifierMouseMove(ModifierMouseArgs e)
    {
        if (e.IsMaster)
            base.OnModifierMouseMove(e);
    }

    public override void OnModifierMouseUp(ModifierMouseArgs e)
    {
        if (e.IsMaster)
        {
            base.OnModifierMouseUp(e);
        }
        this.ParentSurface.InvalidateElement();
    }

}

Thank you for your help!

Mike.

  • You must to post comments
Showing 2 results
Your Answer

Please first to submit.