Hello,
I just purchased this library 2 days ago, and my first impression is WOW! Very happy with my purchase for my small team. That being said I have a unique design requirement and I’m struggling to figure out how to resolve.
Our app utilizes a cursor indicator in the form of a vertical line, this indicator is used as a visual reference and synced across multiple charts. The behavior needs to be similar to how a RollOver modifier works, however the vertical line needs to stay in place, when the user is not “Mouse – Left Down”. Because the RollOver indicator goes away when not hovering over the chart, I decided to make a custom mouse modifier.
Essentially I created a “vertical line annotation” then disabled the dragging (want it to be moved only by mouse cursor movement, and not requiring the user to drag). Made a custom mouse modifier, where OnMouseModiferDown I set a bool flag, then OnMouseMoodiferMove I get the mouse cursor position and update the X1 binding of the cursor, finally OnMouseModiferUp I set the bool flag to false.
The Issue: With my custom mouse modifier the Vertical Line annotation lags the mouse position, It almost looks like there is some sort of smoothing applied to the movement? Is there a way to turn this effect off or reduce it? Here is a link to the behavior to highlight what I’m seeing.
Video of Behavior
My Code is given below.
Xaml
<local:mouseMove ExecuteOn="MouseMove"/>
<s:VerticalSliceModifier IsEnabled="True">
<s:VerticalSliceModifier.VerticalLines>
<s:VerticalLineAnnotation IsEditable="False" LabelPlacement="Axis" ShowLabel="False" X1="{Binding cursorPoint Mode=TwoWay}" Style="{StaticResource sliceStyle}" />
</s:VerticalSliceModifier.VerticalLines>
</s:VerticalSliceModifier>
C#, Mouse Modifier (MouseMove)
public class mouseMove : XAxisDragModifier
{
private bool moveCursor { get; set; }
public override void OnModifierMouseDown(ModifierMouseArgs e)
{
if (e.MouseButtons == MouseButtons.Left)
{
moveCursor = true;
}
}
public override void OnModifierMouseUp(ModifierMouseArgs e)
{
if (e.MouseButtons == MouseButtons.Left)
{
moveCursor = false;
}
}
public override void OnModifierMouseMove(ModifierMouseArgs e)
{
if ((Keyboard.Modifiers == ModifierKeys.Control))
{
//This is my keybind for the RuberBandXY, ignore this mouse event if Ctrl + Left Mouse Down
}
else
{
if (moveCursor)
{
// Get mouse point
var mousePoint = e.MousePoint;
mousePoint = ParentSurface.RootGrid.TranslatePoint(mousePoint, ParentSurface.ModifierSurface);
var xDataValue = ParentSurface.XAxis.GetDataValue(mousePoint.X);
ParentSurface.Annotations[0].X1 = xDataValue;
}
}
}
}
- Zachary Etier asked 4 years ago
- You must login to post comments
Hi Zachary
Firstly, very happy to hear that you like SciChart!! If you like it, please review it! It helps us!
Regarding the lag, this may be down to just WPF wierdness … however Id like to ask, does the RolloverModifier exhibit the same lag?
One RolloverModifier vs. 5 VerticalSliceModifiers is not a fair test, so does 1 VerticalSlice exhibit the same lag?
We can profile it if you can give us access to some code, and see if there are any bottlenecks that can be improved. Note that Annotations are on a different rendering path (they use plain WPF) and moving the annotation requires that all of them are hit-tested (testing which data-values lie under the series) and all redrawn/updated, which can cause some of the latency you see depending on how busy your chart surface is.
Best regards,
Andrew
- Andrew Burnett-Thompson answered 4 years ago
- You must login to post comments
By the way, RolloverModifier has the property ShowTooltipOn
When you set this to always, you get the desired behaviour you want.
RolloverModifier.ShowTooltipOn = ShowTooltipOn.Always;
Also, if you have four charts don’t write any complex logic to synchronise the charts, the MouseManager.MouseEventGroup property will do that for you.
Let me know if this helps!
Best regards
Andrew
- Andrew Burnett-Thompson answered 4 years ago
- You must login to post comments
Andrew thank you for the quick response, unfortunately using
RolloverModifier.ShowTooltipOn = ShowTooltipOn.Always;
Isn’t exactly the same behavior I’m after.
I did the 1 slicer vs 1 rollover test, and it seemed to be very close and I didn’t really detect any lag, so I went back to my code, and profiled it with the Visual Studio Profiler. It looks like the Binding I have bound to X1 was getting called way to many times and the “OnPropertyNotify” was accounting for 39% of my cpu cycles!!!!, so I created a timer check on the OnPropertyNotify to where it will only update every 16 m/s (60 fps) this has significantly increased the performance to where it is no longer an issue.
Thank you for your help!
- Zachary Etier answered 4 years ago
- You must login to post comments
Update: I noticed that using the TimeMethod from SciChart.Core only updates when I stop moving the mouse. Is there anyway to get the TimeMethod to fire while the SciChartSurfaces are still receiving mouse movements? Here is the code in question
if (_timedMethod != null) _timedMethod.Dispose();
_timedMethod = TimedMethod.Invoke(() =>
{
//Update the OnNotify for the binding to update labels
updateCursor();
}).After(16).Go();
- Zachary Etier answered 4 years ago
- You must login to post comments
Please login first to submit.