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]