As Q2 2011 is officially out, we are really excited about all the interactivity features we shipped with our charting component. Together with all the built-in goodies like PanAndZoom, Trackball and Tooltip, we have also implemented a flexible and convenient way for extending the default gesture handling behavior of RadChart. By implementing a handler for the RadChart.PreviewGesture event you may provide completely custom interactivity depending on your custom scenario. When marked as “Handled” the event will have higher priority than any default behaviors registered with the Chart.

Simple drill-down functionality

Let’s play a bit more with the PreviewGesture event by implementing a very simple drill-down scenario that changes the data source of the chart when clicked on a Bar item.

The XAML is minimal – we have a Cartesian chart with one Bar series and a handler for the PreviewGesture event:

<telerikChart:RadCartesianChart x:Name="radChart" PreviewGesture="RadCartesianChart_PreviewGesture">
    <telerikChart:RadCartesianChart.HorizontalAxis>
        <telerikChart:CategoricalAxis LabelFitMode="MultiLine"/>
    </telerikChart:RadCartesianChart.HorizontalAxis>
    <telerikChart:RadCartesianChart.VerticalAxis>
        <telerikChart:LinearAxis/>
    </telerikChart:RadCartesianChart.VerticalAxis>
    <telerikChart:BarSeries ItemsSource="{Binding}" ValueBinding="Value"/>
</telerikChart:RadCartesianChart>

And the handler looks like:

private void RadCartesianChart_PreviewGesture(object sender, ChartGestureEventArgs e)
{
    if (e.Gesture.GestureType == GestureType.Tap)
    {
        this.HandleTap(e.Gesture, e.GetContext());
    }
}

private void HandleTap(GestureSample gesture, ChartDataContext context)
{
    if (context.ClosestDataPoint == null)
    {
        return;
    }
 
    Point touchLocation = this.GetTouchLocation(gesture);
 
    // tap is directly on a bar
    if (context.ClosestDataPoint.DataPoint.LayoutSlot.Contains(touchLocation.X, touchLocation.Y))
    {
        // toggle data sources
        if (this.radChart.DataContext == this.source1)
        {
            this.radChart.DataContext = this.source2;
        }
        else
        {
            this.radChart.DataContext = this.source1;
        }
    }
}

Gotcha: The ChartGestureEventArgs.PrimaryLocation property is not properly translated to chart coordinates, so do not use it until our next internal build :)

Adding scale upon Hold

Now let's handle the Hold gesture and perform a scale animation upon the chart:

private void RadCartesianChart_PreviewGesture(object sender, ChartGestureEventArgs e)
{
    if (e.Gesture.GestureType == GestureType.Tap)
    {
        this.HandleTap(e.Gesture, e.GetContext());
    }
    else if (e.Gesture.GestureType == GestureType.Hold)
    {
        this.HandleHold(e.Gesture, e.GetContext());
    }
}

private void HandleHold(GestureSample gesture, ChartDataContext context)
{
    this.ScaleChart(1, 1, 2, 2);
    this.chartZoomed = true;
}

private void ScaleChart(double fromX, double fromY, double endX, double endY)
{
    RadScaleAnimation scale = new RadScaleAnimation();
    scale.StartScaleX = fromX;
    scale.StartScaleY = fromY;
    scale.EndScaleX = endX;
    scale.EndScaleY = endY;
    scale.Duration = new Duration(TimeSpan.FromSeconds(0.5));
 
    RadAnimationManager.Play(this.radChart, scale);
}

Pretty easy, right? We have further plans of extending the chart interactivity with selection, visual filtering and probably annotations, so stay tuned for future releases :)

Attached is the sample project, you will just need to add the Telerik references to it. Enjoy!

ChartGestures.zip


About the Author

Georgi Atanasov


Related Posts

Comments

Comments are disabled in preview mode.