Code changes :
– Grab the SciChart_ScatterChart example
<s:SciChartSurface Name="sciChart"
Grid.Column="1"
Padding="0"
BorderThickness="0">
<s:SciChartSurface.RenderableSeries>
<s:XyScatterRenderableSeries x:Name="scatterRenderSeries0"
Opacity="0.67">
<s:XyScatterRenderableSeries.PointMarker>
<s:EllipsePointMarker Width="14"
Height="14"
Fill="{StaticResource PointMarkerFillColor}"
StrokeThickness="0" />
</s:XyScatterRenderableSeries.PointMarker>
</s:XyScatterRenderableSeries>
</s:SciChartSurface.RenderableSeries>
<s:SciChartSurface.XAxis>
<s:NumericAxis DrawMajorBands="True"
GrowBy="0.1, 0.1"
VisibleRangeLimit="0, 0"
VisibleRangeLimitMode="Min" />
</s:SciChartSurface.XAxis>
<s:SciChartSurface.YAxis>
<s:NumericAxis DrawMajorBands="True"
GrowBy="0.1, 0.1"
VisibleRangeLimit="0, 0"
VisibleRangeLimitMode="Min" />
</s:SciChartSurface.YAxis>
<s:SciChartSurface.ChartModifier>
<s:ModifierGroup>
<s:ZoomPanModifier ClipModeX="ClipAtMin" />
<s:MouseWheelZoomModifier />
</s:ModifierGroup>
</s:SciChartSurface.ChartModifier>
Repro steps :
- Zoom out using the wheel
- Try to pan
- Notice that it appears to apply an unwanted zoomToExtents operation
Can I also ask why there is still no ClipModeY for the ZoomPanModifier? there are a few posts relating to this with workarounds, but none of them seem to work as far as I can tell without weird side affects.
- Ben Green asked 9 months ago
- You must login to post comments
Hi Ben,
Firstly thanks for the excellent reproduction. Something very quick to true:
is ClipModeX=”ClipAtMin” causing this? Try changing this line
<s:ZoomPanModifier ClipModeX="None" />
The ClipMode on ZoomPanModifier defaults to clip at extents, its not a very good or nice behaviour but it’s there for legacy reasons. It will prevent you from panning outside the visiblerange on X, however it will not prevent other modifiers from doing so.
If you wanted to ensure both ZoomPanModifier
and MouseWheelZoomModifier
cannot go outside a certain range, then using this technique would be a better choice:
Clipping the Axis.VisibleRange on Zoom and Pan Documentation
Two techniques presented in the above.
-
Using Axis.VisibleRangeLimit, this modifies the behaviour of ZoomExtents() and AutoRanging however still users can pan or zoom outside the range sometimes (exact behaviour with various modifiers is actually undefined)
-
So technique (2) and the one which we recommend for complex interactions is to apply axis visiblerange clipping in code.
For example:
axis.VisibleRangeChanged += (s, e) =>
{
// e is VisibleRangeChangedEventArgs
// Assuming axis is NumericAxis
// Choose your rule here of when to limit visiblerange
if (e.NewVisibleRange != null && e.NewVisibleRange.Min < 0)
{
// Force minimum visiblerange to zero always
((NumericAxis)sender).VisibleRange = new DoubleRange(0, e.NewVisibleRange.Max);
}
};
From the Documentation page above this can be applied in code or in MVVM and can be attached to one or more axis. It would give you unlimited and specific control of where you can and cannot zoom.
Does that help?
Best regards
Andrew
- Andrew Burnett-Thompson answered 9 months ago
- You must login to post comments
Thankyou Andrew.
It does seem to be related to the ClipModeX
I have tried your second technique which clamps panning from going beyond 0, but I still have the issue that it will now Zoom if you can’t pan.
What I am trying to achieve is :
- Don’t let the user pan into negative X or Y (i.e don’t pan below zero)
- Once the user reaches the point where they can no longer pan (zero), just stop, don’t zoom
- Ben Green answered 9 months ago
- last edited 9 months ago
-
OK let me think. Its possible just need to think of all the combinations
- You must login to post comments
I think I found a workaround. Thee other requirement was that I needed it to work with UndoRedo
internal class ZoomPanModifierEx : ZoomPanModifier
{
public override void Pan(Point currentPoint, Point lastPoint, Point startPoint)
{
using (ParentSurface.SuspendUpdates())
{
PanAxis(XAxis, currentPoint.X, lastPoint.X);
PanAxis(YAxis, currentPoint.Y, lastPoint.Y);
}
}
private void PanAxis(IAxis axis, double current, double last)
{
double y1 = axis.GetDataValue(current).ToDouble();
double y2 = axis.GetDataValue(last).ToDouble();
double value = y2 - y1;
var currentRange = (DoubleRange)axis.VisibleRange;
double limit = (axis.VisibleRangeLimit as DoubleRange)?.Min ?? double.MinValue;
double newMin = Math.Max(limit, currentRange.Min + value);
if (newMin == limit)
return;
double newMax = Math.Max(0, currentRange.Max + value);
var newRange = new DoubleRange(newMin, newMax);
axis.VisibleRange = newRange;
ParentSurface.ZoomHistoryManager?.SaveLatestRange(new AxisKey(axis), newRange);
}
}
- Ben Green answered 9 months ago
- last edited 9 months ago
- You must login to post comments
Hi Ben,
Regarding ClipModeY for the ZoomPanModifier, it haven’t been added to SciChart API yet because it is quite slow. While operations on X values are quite fast (because of the requirement that data values are sorted in X direction), similar operations on Y values are slow because they require traversing entire data set. It will require working on the whole bunch of optimizations to make such operations viable in SciChart.
So at the moment, it is not possible to add ClipModeY as a part of SciChart API. However, we can make a standalone example with a custom ZoomPanModifier that would demonstrate this feature (although having performance drawbacks potentially). Please let me know if you’d be interested in such example.
Best Regards,
Joeri
- Joeri R answered 9 months ago
- You must login to post comments
Hi Joeri,
Thanks for the reply.
Do you think the workaround I posted is ok? is it going to have any hidden side effects? If so, I’m happy to just use that.
- Ben Green answered 9 months ago
- You must login to post comments
Please login first to submit.