Zooming and panning are features that are often needed when
using a charting component. This article shows how zooming and
panning can be achieved using the free version of Visiblox
Silverlight charts with a few lines of code. It then digs a bit
deeper to understand how zooming and panning is implemented on
Visiblox charts.
The structure of the article is the following:
Setting Up a Basic Chart
Before adding zooming and panning support, let's create a simple
chart with some random data. This is pretty straightforward to do,
let's add a
Chartin XAML and in the constructor of the main page auto
generate some points:
<UserControl (...) xmlns:charts="clr-namespace:Visiblox.Charts;assembly=Visiblox.Charts">
<Grid x:Name="LayoutRoot" Background="White">
<charts:Chart x:Name="MainChart"/>
</Grid>
</UserControl>
// Add 100 points to the chart
var rnd = new Random();
var dataSerires = new DataSeries<DateTime, double>(){ Title = "Series 1" };
var startDate = Convert.ToDateTime("2010. 08. 01.");
for (int i = 0; i < 100; i++)
{
dataSerires.Add(new DataPoint<DateTime, double>(startDate.AddDays(i), rnd.Next(-20, 20)));
}
// Add a line series with the created data series that shows points
MainChart.Series.Add(new LineSeries() { DataSeries = dataSerires, ShowPoints = true, ToolTipEnabled=true});
The result is the following simple chart with a line series:
Adding Zooming and Panning
The Behaviour Model
Both zooming and panning are quite similar in both of them have
to respond to mouse events. For such "interactive" behaviours,
Visiblox has defined the Behaviour model which is an easy extension
point for creating interactive components. Both zoom and pan are
such behaviours (
IBehaviours). To use them, one simply has to assign either of
them as the
Behaviour property of the chart. So let's add that single line
to enable them:
Zooming using the
ZoomBehaviour
Enabling zoom can be done by setting the
ZoomBehaviouras the Behaviour of the chart:
<charts:Chart x:Name="MainChart">
<charts:Chart.Behaviour>
<charts:ZoomBehaviour />
</charts:Chart.Behaviour>
</charts:Chart>
On the following chart, zooming has been enabled. Click and
select a rectangle to zoom in, double click to zoom out:
Panning with the
PanBehaviour
Enabling panning is done is done in a similar way, by setting
the
PanBehaviour as the behaviour of the chart. By default,
however, the chart renders itself to fit the plottable area, thus
making panning pointless.
Panning is typically useful when the chart's axes' ranges are
set so that part of it is off the screen. To do so, let's manually
set the range of the X axis to be smaller than the range of the
series:
<charts:Chart x:Name="MainChart">
<!-- Set the X range to be smaller than the range of the series we're generating-->
<charts:Chart.XAxis>
<charts:DateTimeAxis>
<charts:DateTimeAxis.Range>
<charts:DateTimeRange Minimum="2010. 09. 01" Maximum="2010. 10. 01"/>
</charts:DateTimeAxis.Range>
</charts:DateTimeAxis>
</charts:Chart.XAxis>
<!-- Enable panning -->
<charts:Chart.Behaviour>
<charts:PanBehaviour/>
</charts:Chart.Behaviour>
</charts:Chart>
The result is a chart that can be panned in either direction.
Just click and drag any area of the chart:
Multiple Behaviours using the
BehaviourManager
As discussed before, both zooming and panning are examples of
behaviours on the Visiblox charts. The free version of Visiblox
ships with some other behaviours such as
CrosshairBehaviour (displaying a crosshair on the chart) and
TrackballBehaviour (displaying trackball(s) on series). There
might be cases when it would be desirable to use two or more
behaviours at the same time, however the chart's Behaviour property
is of type IBehaviour, meaning only one behaviour can be set.
This problem can be solved by using the
BehaviourManagerclass which is also an IBehaviour and follows
the composite pattern, being composed of multiple behaviours. So
for example enabling panning and crosshair can be done assigning a
BehaviourManager to the chart's Behaviour property the following
way:
<charts:Chart.Behaviour>
<charts:BehaviourManager AllowMultipleEnabled="True">
<charts:PanBehaviour/>
<charts:CrosshairBehaviour ShowAxisLabels="True"/>
</charts:BehaviourManager>
</charts:Chart.Behaviour>
By using the BehaviourManager it is possible to view the
crosshair and pan at the same time as in this example:
Download the source code of this example here: Zooming and
Panning with Visiblox.zip
Understanding how
Zooming and Panning Work
Now that we've seen how behaviours can add interaction to
Silverlight or WPF charts using Visiblox, it's interesting to see
what the ZoomBehaviour and PanBehaviour actually do to make zooming
and panning possible.
All of the behaviours shipped with Visiblox have mouse events
forwarded to them, consume those, draw something on the plot area
and utilize the API of the Visiblox Chart object. In this case,
both ZoomBehaviour and PanBehaviour simply animate the
Scale and
Offset of the
Zoom property on the X and Y axis of the chart. Since it's
mostly the chart that's doing the work of performing the actual
zooming / panning, it should be easy enough to control these, for
example with a slider.
Zooming and Panning via
Bindings
To control the zoom (or pan) level with a slider, we simply have
to set up bindings to the Scale and Offset of the X and Y axis'
Zoom property, for example like this:
<StackPanel Orientation="Horizontal">
<TextBlock>X Axis Zoom:</TextBlock>
<TextBlock Margin="10,0,0,0">Scale:</TextBlock>
<Slider Minimum="0.1" Maximum="5.0" Value="{Binding ElementName=MainChart, Path=XAxis.Zoom.Scale, Mode=TwoWay}" Width="100"/>
<TextBlock Text="{Binding ElementName=MainChart, Path=XAxis.Zoom.Scale}"/>
<TextBlock Margin="10,0,0,0">Offset:</TextBlock>
<Slider Minimum="-1.5" Maximum="1.5" Value="{Binding ElementName=MainChart, Path=XAxis.Zoom.Offset, Mode=TwoWay}" Width="100"/>
<TextBlock Text="{Binding ElementName=MainChart, Path=XAxis.Zoom.Offset}"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock>Y Axis Zoom:</TextBlock>
<TextBlock Margin="10,0,0,0">Scale:</TextBlock>
<Slider Minimum="0.1" Maximum="5.0" Value="{Binding ElementName=MainChart, Path=YAxis.Zoom.Scale, Mode=TwoWay}" Width="100"/>
<TextBlock Text="{Binding ElementName=MainChart, Path=YAxis.Zoom.Scale}"/>
<TextBlock Margin="10,0,0,0">Offset:</TextBlock>
<Slider Minimum="-1.5" Maximum="1.5" Value="{Binding ElementName=MainChart, Path=YAxis.Zoom.Offset, Mode=TwoWay}" Width="100"/>
<TextBlock Text="{Binding ElementName=MainChart, Path=YAxis.Zoom.Offset}"/>
</StackPanel>
As a result it's now possible to change the zoom scale and
offset of both axes with sliders:
Download the source of this example here: Zooming and
Panning using Bindings.zip.
Conclusion
In this article I've shown how easy it is to implement zooming
and panning on Visiblox Silverlight (or WPF) charts. Both zooming
and panning are behaviours, which behaviours can be used together,
and it's also possible to create
custom behaviours according to custom needs. I've also taken a
step further to understand how ZoomBehaviour and PanBehaviour use
the chart's API to perform zooming and panning and created an
example where the zoom scale and offset are controlled by
sliders.
All of the examples created in this article were done with the
free version of Visiblox charts. If you're interested in a
Silverlight / WPF charting component with built in support for
various interactions such as zooming and panning, download the free version
of Visiblox Charts now to get started or look at some of the
examples (most with source code) to get an idea of the chart's
capabilities.