mjg 发表于 2012-12-19 21:10:12

User control likes Google Financial Chart V1.0

<div id="cnblogs_post_body">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
http://pic002.cnblogs.com/images/2012/155436/2012100717335462.png

4. Backend Code
<div class="cnblogs_Highlighter">/// <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.Interior;                MoveEllipse(area, canvas                , serieses.Data , e, el.Value , out currentChartPoint);                if (currentChartPoint != null)                {                  titles.Text = " " + el.Key + ":" + currentChartPoint.Y;                  titles.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);      }    }
页: [1]
查看完整版本: User control likes Google Financial Chart V1.0