• User control likes Google Financial Chart V1.0


    UI:

    1.Display current indexes

    2.Ellipses of current selected node (Select node by move mouse) 

    3.Move 3 to show details of selected days

    4. Backend Code

    /// <summary>
        /// Interaction logic for CitiFinancialChart.xaml
        /// </summary>
        public partial class FinancialChart : UserControl
        {
           
            public FinancialChart()
            {
                InitializeComponent();
            }
    
            Action<object> displayItem;
    
            Dictionary<string,Ellipse> ellipses=null ;
            Dictionary<string, ChartSeries> serieses = null;
            Dictionary<string, TextBlock> titles = null;
            public void SetChartData(IEnumerable data, Dictionary<string, string> seriesNamePathPairs,
                string xAxisPath,
                string yAxisHeader,
                Action<object> _displayItem)
            {
                displayItem = _displayItem;
                canvas .Children .Clear();
                ellipses=new Dictionary<string,Ellipse>();
                titles = new Dictionary<string, TextBlock>();
                serieses = new Dictionary<string, ChartSeries>();
                area.Series.Clear();
                stck.Children.Clear();
                foreach(var kvp in seriesNamePathPairs)
                {
                    Ellipse ellipse=new Ellipse();
                    ellipse .Width =5;
                    ellipse .Height =5;
                    ellipse.Visibility = System.Windows.Visibility.Collapsed ;
                    ellipses.Add(kvp.Key ,ellipse);
                    canvas.Children.Add(ellipse);
    
                    TextBlock txt = new TextBlock();
                    stck.Children.Add(txt);
                    titles.Add(kvp.Key, txt);
    
                    ChartSeries series = new ChartSeries();
                    series.ShowToolTip = false;
                    series.BindingPathX = xAxisPath;
                    series.BindingPathsY = new string[]{ kvp.Value};
                    series.Type = ChartTypes.Line;
                    Binding binding = new Binding();
                    binding.ElementName = "timelineControl";
                    binding.Path = new PropertyPath("SelectedData", null);
                    binding.Mode = BindingMode.TwoWay;
                    binding.UpdateSourceTrigger = UpdateSourceTrigger.Explicit;
                    series.SetBinding(ChartSeries.DataSourceProperty, binding);
                    area.Series.Add(series);
                    serieses.Add(kvp.Key, series);
                }
               
                this.yAxisHeader.Text = yAxisHeader;
                timelineControl.HoldUpdate = true;
                timelineControl.PrimaryAxis.DateTimeInterval = new TimeSpan(268, 0, 0, 0);
                timelineControl.DataSource = data ;
                timelineControl.BindingPathX = xAxisPath;
                timelineControl.BindingPathsY = seriesNamePathPairs.Values .ToArray(); 
                timelineControl.HoldUpdate = false;
                timelineControl.EndInit();
                DataContext = data;
                area.MouseMove += new System.Windows.Input.MouseEventHandler(area_MouseMove);
                area.MouseEnter += new System.Windows.Input.MouseEventHandler(area_MouseEnter);
                area.MouseLeave += new System.Windows.Input.MouseEventHandler(area_MouseLeave);
            }
    
            void area_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
            {
                foreach (var el in ellipses)
                    el.Value.Visibility = System.Windows.Visibility.Collapsed; 
            }
    
            void area_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
            {
                foreach (var el in ellipses)
                    el.Value.Visibility = System.Windows.Visibility.Visible ;
            }
    
            void area_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
            {
                ChartArea area = sender as ChartArea;
                IChartDataPoint currentChartPoint=null ;
                foreach (var el in ellipses)
                {
                    el.Value.Fill = serieses[el.Key].Interior;
                    MoveEllipse(area, canvas
                    , serieses[el.Key].Data , e, el.Value , out currentChartPoint);
                    if (currentChartPoint != null)
                    {
                        titles[el.Key].Text = " " + el.Key + ":" + currentChartPoint.Y;
                        titles[el.Key].Foreground = el.Value.Fill;
                    }
                }
    
                if (displayItem != null && currentChartPoint != null)
                {
                    displayItem(currentChartPoint.Item);
                }
                 
            }
    
            void MoveEllipse(ChartArea area, Canvas canvas, IChartData chartData, System.Windows.Input.MouseEventArgs e, Ellipse ellipse, out IChartDataPoint currentChartPoint)
            {
                //Get mouse position related with chart area
                Point mousePointOnChartArea = e.GetPosition(area);
                //Get xAxis Value and Round value
                double xValue = area.PointToValue(area.PrimaryAxis, mousePointOnChartArea), yValue;
                double xRoundValue = Math.Round(xValue);
    
                //Wrapper ChartData to use Linq 
                EnumerableChartData data = new EnumerableChartData(chartData);
    
                //Get Current chart point
                currentChartPoint = data.FirstOrDefault(x => x.X == xRoundValue);
                if (currentChartPoint == null)
                    return;
    
    
    
                // Get next Chart point statisfied xValue betweens nextChartPoint.X and currentChartPoint.X
                IChartDataPoint nextChartPoint;
                if (xValue > xRoundValue)
                    nextChartPoint = data.OrderBy(x => x.X).FirstOrDefault(x => x.X > xValue);
                else
                    nextChartPoint = data.OrderBy(x => x.X).LastOrDefault(x => x.X < xValue);
                if (nextChartPoint == null)
                    nextChartPoint = currentChartPoint;
    
                // Get Value of Y axis
                yValue = GetValueFromLinearFunction(currentChartPoint.X, currentChartPoint.Y, nextChartPoint.X, nextChartPoint.Y, xValue);
                // convert yValue to Point
                double yPoint = area.ValueToPoint(area.SecondaryAxis, yValue);
                var epc = e.GetPosition(canvas);
                ellipse.SetValue(Canvas.LeftProperty, epc.X - ellipse.Width / 2);
                ellipse.SetValue(Canvas.TopProperty, epc.Y + (yPoint - mousePointOnChartArea.Y) - ellipse.Height / 2);
                //ellipse .Fill = 
            }
    
    
            double GetValueFromLinearFunction(double x1, double y1, double x2, double y2, double x)
            {
                if (x1 == x2)
                    return y1;
                return y1 + ((y2 - y1) / (x2 - x1)) * (x - x1);
            }
        }
    

      5.XAML

    <UserControl x:Class="TimeLineControlSample.UserControls.FinancialChart"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:sync="http://schemas.syncfusion.com/wpf"
                 xmlns:local="clr-namespace:TimeLineControlSample" 
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300">
        <UserControl.Resources>
            <local:LabelConverter  x:Key="LabelConverterKey" />
        </UserControl.Resources>
        <Grid>
            <Grid.RowDefinitions> 
                <RowDefinition Height="40"></RowDefinition>
                <RowDefinition Height="0.75*" />
                <RowDefinition Height="0.25*" />
            </Grid.RowDefinitions>
            
            <StackPanel Name="stck" Orientation="Horizontal" HorizontalAlignment="Right"  ></StackPanel>
            
            <Canvas Grid.Row="1" Name="canvas" Background="Transparent">
            </Canvas>
            <sync:Chart Grid.Row="1" Name="chart" >
                <sync:ChartArea Name="area">
                    <sync:ChartArea.PrimaryAxis>
                        <sync:ChartAxis ValueType="DateTime"  LabelDateTimeFormat="MMM/dd/yyy">
                            <sync:ChartAxis.Header>
                                <TextBlock Text="Date" FontFamily="Segoe UI" FontSize="12"/>
                            </sync:ChartAxis.Header>
                        </sync:ChartAxis>
                    </sync:ChartArea.PrimaryAxis>
    
                    <sync:ChartArea.SecondaryAxis>
                        <sync:ChartAxis>
                            <sync:ChartAxis.Header>
                                <TextBlock Name="yAxisHeader" FontFamily="Segoe UI" FontSize="12"/>
                            </sync:ChartAxis.Header>
                        </sync:ChartAxis>
                    </sync:ChartArea.SecondaryAxis> 
    
                </sync:ChartArea>
            </sync:Chart>
    
            <sync:TimeLineControl x:Name="timelineControl" Grid.Row="2"
                                  StartValue="0" EndValue="85" IsContextMenuEnabled="True">
    
                <sync:TimeLineControl.PrimaryAxis>
                    <sync:ChartAxis x:Name="primary" TickSize="0" SmallTickSize="0" RangePadding="None" EdgeLabelsDrawingMode="Fit" IntersectAction="Hide" ValueType="DateTime"  LabelDateTimeFormat="yyyy" Interval="1"  LabelPosition="Outside" LabelForeground="#FFD8F0F0" OpposedPosition="True">
                        <sync:ChartArea.ShowGridLines>False</sync:ChartArea.ShowGridLines>
                        <sync:ChartArea.ShowMajorGridLines>True</sync:ChartArea.ShowMajorGridLines>
                        <sync:ChartArea.OriginLineStroke>
                            <Pen Brush="#FF4A9BC6" Thickness="1"/>
                        </sync:ChartArea.OriginLineStroke>
                        <sync:ChartAxis.LineStroke>
                            <Pen Brush="#FF4A9BC6" Thickness="1"/>
                        </sync:ChartAxis.LineStroke>
                    </sync:ChartAxis>
                </sync:TimeLineControl.PrimaryAxis>
                <sync:TimeLineControl.Axes>
                    <sync:ChartAxis x:Name="quater" ValueType="DateTime">
                        <sync:ChartArea.ShowGridLines>True</sync:ChartArea.ShowGridLines>
                        <sync:ChartArea.ShowMajorGridLines>True</sync:ChartArea.ShowMajorGridLines>
                        <sync:ChartAxis.LabelTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding Converter={StaticResource LabelConverterKey}}"/>
                            </DataTemplate>
                        </sync:ChartAxis.LabelTemplate>
                    </sync:ChartAxis>
                </sync:TimeLineControl.Axes>
            </sync:TimeLineControl>
            
        </Grid>
    </UserControl>

    6. Test Window XMAL

    <Window x:Class="TimeLineControlSample.TestCustomerControls"
            xmlns:my="clr-namespace:TimeLineControlSample.UserControls"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="TestCustomerControls" MinHeight="300" MinWidth="300">
        <Grid>
            <my:CitiFinancialChart x:Name="cfc" />
        </Grid>
    </Window>

    7. Test Window Backend Code

      public partial class TestCustomerControls : Window
        {
            public TestCustomerControls()
            {
                InitializeComponent();
                DataCollection collection = new DataCollection();
                cfc.SetChartData(collection.datalist,
                    new Dictionary<string, string> { { "High", "High" }, { "Low", "Low" }, { "Last", "Last" } },
                    "TimeStamp", "date", null);
                    
            }
        }
    

      

  • 相关阅读:
    AndroidStudio gradle配置
    Git中pull对比fetch和merge
    Knockout.js随手记(7)
    Knockout.js随手记(6)
    MVC自动绑定整数数组
    Knockout.js随手记(5)
    ASP.NET4.5Web API及非同步程序开发系列(3)
    Knockout.js随手记(4)
    ASP.NET4.5Web API及非同步程序开发系列(2)
    ASP.NET4.5Web API及非同步程序开发系列(1)
  • 原文地址:https://www.cnblogs.com/mjgb/p/2714254.html
Copyright © 2020-2023  润新知