Back to Devexpress

How to: Create a Movable Legend at Runtime

wpf-11115-controls-and-libraries-charts-suite-chart-control-examples-end-user-interaction-how-to-create-a-movable-legend-at-runtime.md

latest8.1 KB
Original Source

How to: Create a Movable Legend at Runtime

  • Jun 07, 2019
  • 3 minutes to read

This example shows how to provide the capability for end-users to move a chart’s legend at runtime.

For this, you need to assign a TranslateTransform object (named legendTransform) to the Legend.RenderTransform property. This allows you to control and modify a legend position.

Before changing a legend position, you should handle the ChartControl.MouseLeftButtonDown and ChartControl.MouseLeftButtonUp events to make sure that a legend has been dragged by a mouse. After that, it becomes possible to calculate a distance by which a legendTransform object should be moved. To accomplish this task, handle the ChartControl.MouseMove event.

xaml
<Window x:Class="scratch.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:dxc="http://schemas.devexpress.com/winfx/2008/xaml/charts"
        Title="MainWindow" Height="350" Width="525" >
    <Grid>
        <dxc:ChartControl Name="chartControl1" MouseMove="chart_MouseMove" 
                          MouseLeftButtonDown="chart_MouseLeftButtonDown" 
                          MouseLeftButtonUp="chart_MouseLeftButtonUp">
            <dxc:ChartControl.Diagram>
                <dxc:XYDiagram2D>
                    <dxc:XYDiagram2D.Series>
                        <dxc:BarSideBySideSeries2D ColorEach="True">
                            <dxc:BarSideBySideSeries2D.LegendPointOptions>
                                <dxc:PointOptions PointView="Argument"/>
                            </dxc:BarSideBySideSeries2D.LegendPointOptions>
                            <dxc:BarSideBySideSeries2D.Points>
                                <dxc:SeriesPoint Argument ="A" Value="1"/>
                                <dxc:SeriesPoint Argument ="B" Value="2"/>
                                <dxc:SeriesPoint Argument ="C" Value="3"/>
                                <dxc:SeriesPoint Argument ="D" Value="4"/>
                                <dxc:SeriesPoint Argument ="E" Value="5"/>
                                <dxc:SeriesPoint Argument ="F" Value="4"/>
                                <dxc:SeriesPoint Argument ="G" Value="3"/>
                                <dxc:SeriesPoint Argument ="H" Value="2"/>
                            </dxc:BarSideBySideSeries2D.Points>
                        </dxc:BarSideBySideSeries2D>
                    </dxc:XYDiagram2D.Series>
                </dxc:XYDiagram2D>
            </dxc:ChartControl.Diagram>
            <dxc:ChartControl.Legend>
                <dxc:Legend x:Name="legend" Visibility="Visible">
                    <dxc:Legend.RenderTransform>
                        <TranslateTransform x:Name="legendTransform"/>
                    </dxc:Legend.RenderTransform>
                </dxc:Legend>
            </dxc:ChartControl.Legend>
        </dxc:ChartControl>
    </Grid>
</Window>
csharp
using System.Windows;
using System.Windows.Input;
using DevExpress.Xpf.Charts;

namespace scratch {
    public partial class MainWindow : Window {
        Point clickPosition { set; get; }
        Point startDragging;
        public bool isDragging { set; get; }

        public MainWindow() {
            InitializeComponent();
        }

        void chart_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
            startDragging = e.GetPosition(chartControl1);
            ChartHitInfo hitInfo = chartControl1.CalcHitInfo(startDragging);
            isDragging = hitInfo != null && hitInfo.InLegend;
            ((UIElement)sender).CaptureMouse();
        }

        void chart_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) {
            ((UIElement)sender).ReleaseMouseCapture();
            isDragging = false;
        }

        void chart_MouseMove(object sender, MouseEventArgs e) {
            if (e.LeftButton == MouseButtonState.Pressed && isDragging) {
                Point endDragging = e.GetPosition(chartControl1);
                Point inLegendPosition = e.GetPosition(legend);

                if (inLegendPosition.X < 0)
                    inLegendPosition.X = 0;
                else if (inLegendPosition.X > legend.ActualWidth)
                    inLegendPosition.X = legend.ActualWidth;

                if (inLegendPosition.Y < 0)
                    inLegendPosition.Y = 0;
                else if (inLegendPosition.Y > legend.ActualHeight)
                    inLegendPosition.Y = legend.ActualHeight;

                if (endDragging.X - inLegendPosition.X > 0 &&
                    endDragging.X + legend.ActualWidth - inLegendPosition.X < chartControl1.ActualWidth)
                        legendTransform.X += endDragging.X - startDragging.X;

                if (endDragging.Y - inLegendPosition.Y > 0 &&
                    endDragging.Y + legend.ActualHeight - inLegendPosition.Y < chartControl1.ActualHeight)
                        legendTransform.Y += endDragging.Y - startDragging.Y;

                startDragging = endDragging;
            }
        }

    }
}
vb
Imports Microsoft.VisualBasic
Imports System.Windows
Imports System.Windows.Input
Imports DevExpress.Xpf.Charts

Namespace scratch
    Partial Public Class MainWindow
        Inherits Window
        Private privateclickPosition As Point
        Private Property clickPosition() As Point
            Get
                Return privateclickPosition
            End Get
            Set(ByVal value As Point)
                privateclickPosition = value
            End Set
        End Property
        Private startDragging As Point
        Private privateisDragging As Boolean
        Public Property isDragging() As Boolean
            Get
                Return privateisDragging
            End Get
            Set(ByVal value As Boolean)
                privateisDragging = value
            End Set
        End Property

        Public Sub New()
            InitializeComponent()
        End Sub

        Private Sub chart_MouseLeftButtonDown(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
            startDragging = e.GetPosition(chartControl1)
            Dim hitInfo As ChartHitInfo = chartControl1.CalcHitInfo(startDragging)
            isDragging = hitInfo IsNot Nothing AndAlso hitInfo.InLegend
            CType(sender, UIElement).CaptureMouse()
        End Sub

        Private Sub chart_MouseLeftButtonUp(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
            CType(sender, UIElement).ReleaseMouseCapture()
            isDragging = False
        End Sub

        Private Sub chart_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)
            If e.LeftButton = MouseButtonState.Pressed AndAlso isDragging Then
                Dim endDragging As Point = e.GetPosition(chartControl1)
                Dim inLegendPosition As Point = e.GetPosition(legend)

                If inLegendPosition.X < 0 Then
                    inLegendPosition.X = 0
                ElseIf inLegendPosition.X > legend.ActualWidth Then
                    inLegendPosition.X = legend.ActualWidth
                End If

                If inLegendPosition.Y < 0 Then
                    inLegendPosition.Y = 0
                ElseIf inLegendPosition.Y > legend.ActualHeight Then
                    inLegendPosition.Y = legend.ActualHeight
                End If

                If endDragging.X - inLegendPosition.X > 0 AndAlso endDragging.X + legend.ActualWidth - inLegendPosition.X < chartControl1.ActualWidth Then
                        legendTransform.X += endDragging.X - startDragging.X
                End If

                If endDragging.Y - inLegendPosition.Y > 0 AndAlso endDragging.Y + legend.ActualHeight - inLegendPosition.Y < chartControl1.ActualHeight Then
                        legendTransform.Y += endDragging.Y - startDragging.Y
                End If

                startDragging = endDragging
            End If
        End Sub

    End Class
End Namespace