2013-05-06 1 views
1

DataVisualization.Chart 유형의 사용자 정의 구성 요소를 만들고 있습니다. 현재 그는 4 가지 범위 제한 (승인 범위 값 최소 1 개 및 최대 값 1 개, 경고 범위 최소 1 개 범위 및 최대 경고 범위 값 1 개)을 허용합니다. 지금까지 그렇게 좋았습니다. 그것은 작동합니다. 그러나 LineSeries의 끝에는 TextBlock (또는 레이블 또는 TextBox 등)을 추가해야합니다. 결과가 동일하지 않더라도DataVisualizationChart의 LineSeries DataPoint 끝에 TextBlock (또는 레이블) 추가

Chart with label

, 내가 넣어해야합니다

Chart without label

지금 내가 이런 일을해야합니다

이 내 실제 LineSeries의입니다 모든 LineDataPoint의 말미의 라벨 또는 텍스트 블록.

편집 1 :

이 항목의 내 목록이 생성되는 방법입니다

/// <summary> 
    /// Generate ItemsSource to use with chart component 
    /// </summary> 
    /// <returns>A observable collection items of ChartItems type</returns> 
    public ObservableCollection<ChartItems> GenerateActualValues() 
    { 
     var itemsSource = ItemsSource as IEnumerable; 
     if (itemsSource.IsNull()) 
      return null; 

     // Get all values from ItemsSource to set Axis Y of Chart 

     List<Double> listAxisY = new List<Double>(); 

     ObservableCollection<ChartItems> chartItems = new ObservableCollection<ChartItems>(); 

     foreach (ChartItems itemSource in itemsSource) 
     { 
      listAxisY.Add(itemSource.ValueY); 

      chartItems.Add(new ChartItems { Name = itemSource.Name, ValueY = itemSource.ValueY, ValueXDouble = itemSource.ValueXDouble, ValueXDateTime = itemSource.ValueXDateTime, Color = itemSource.Color }); 
     } 

     // Set minimum and maximum axis Y if automatic 

     if (AutomaticAxisY) 
     { 
      Double? maxValue; 
      Double? minValue; 

      if (listAxisY.Count > 0) 
      { 
       if (GetMaxLimitValue1(this) > listAxisY.Max()) 
        maxValue = GetMaxLimitValue1(this); 
       else 
        maxValue = listAxisY.Max(); 

       if (GetMinLimitValue1(this) < listAxisY.Min()) 
        minValue = GetMinLimitValue1(this); 
       else 
        minValue = listAxisY.Min(); 
      } 
      else 
      { 
       maxValue = GetMaxLimitValue1(this); 
       minValue = GetMinLimitValue1(this); 
      } 

      Double? increment = (maxValue - minValue) * 0.05; 

      MaximumAxisY = (maxValue + increment).ConvertNullDoubleToDouble(); 
      MinimumAxisY = (minValue - increment).ConvertNullDoubleToDouble(); 

      if (MaximumAxisY == MinimumAxisY) 
      { 
       MaximumAxisY += 1; 
       MinimumAxisY -= 1; 
      } 
     } 

     return chartItems; 
    } 

기본적으로, 내 차트에 사용할 새 ItemsSource를 생성합니다.

/// <summary> 
/// Generates series with values for chart 
/// </summary> 
public void RenderizeChart() 
{ 
    while (this.chartView.Series.Count() - 1 >= 0) 
     this.chartView.Series.Remove(this.chartView.Series[0]); 

    DataPointSeries lineSeriesActualValue = null; 
    DataPointSeries lineSeriesMaxValue1 = null; 
    DataPointSeries lineSeriesMinValue1 = null; 
    DataPointSeries lineSeriesMaxValue2 = null; 
    DataPointSeries lineSeriesMinValue2 = null; 
    DataPointSeries lineSeriesTarget = null; 

    if (!ChartTypeSelectedItem.IsNull()) 

     switch ((ChartTypes)ChartTypeSelectedItem) 
     { 
      case ChartTypes.Bar: 

       this.chartView.Series.Add(new BarSeries()); 
       lineSeriesActualValue = this.chartView.Series[0] as BarSeries; 

       break; 

      case ChartTypes.Columns: 

       this.chartView.Series.Add(new ColumnSeries()); 
       lineSeriesActualValue = this.chartView.Series[0] as ColumnSeries; 
       lineSeriesActualValue.DataPointStyle = (Style)this.Resources["ColumnDataPointStyle"]; 

       break; 

      case ChartTypes.Pie: 

       this.chartView.Series.Add(new PieSeries()); 
       lineSeriesActualValue = this.chartView.Series[0] as PieSeries; 

       break; 

      case ChartTypes.Lines: 

       this.chartView.Series.Add(new LineSeries()); 
       lineSeriesActualValue = this.chartView.Series[0] as LineSeries; 
       lineSeriesActualValue.Style = (Style)this.Resources["LineSeriesStyle"]; 

       if (!ShowPoints) 
       { 
        // Brief explanation: if user wants to hide Data Points, it's necessary to get all Setters on 
        // LineDataPointStyle inside xaml, clear previous style and add new Setter. 
        // Otherwise, it will not work, will deny changes because its sealed. 

        Style style = (Style)this.Resources["LineDataPointStyle"]; 

        List<Setter> setterList = new List<Setter>(); 

        foreach (Setter setter in style.Setters) 
         setterList.Add(setter); 

        style = new Style(); 

        foreach (var setter in setterList) 
         style.Setters.Add(setter); 

        style.Setters.Add(new Setter(LineSeries.TemplateProperty, null)); 

        lineSeriesActualValue.DataPointStyle = style; 
       } 
       else 

        lineSeriesActualValue.DataPointStyle = (Style)this.Resources["LineDataPointStyle"]; 

       break; 

      case ChartTypes.Area: 

       this.chartView.Series.Add(new AreaSeries()); 
       lineSeriesActualValue = this.chartView.Series[0] as AreaSeries; 

       break; 

      default: 

       break; 
     } 

    if (!lineSeriesActualValue.IsNull()) 
    { 
     lineSeriesActualValue.IsSelectionEnabled = true; 

     lineSeriesActualValue.DependentValuePath = FieldForDependentValue; 
     lineSeriesActualValue.IndependentValuePath = FieldForIndependentValue; 

     lineSeriesActualValue.ItemsSource = GenerateActualValues(); 

     // Adding a max limit to chart 
     if (!ItemsSource.IsNull() && ((!GetMaxLimitValue1(this).IsNull()) && !GetMaxLimitValue1(this).Equals(0.0))) 
     { 
      this.chartView.Series.Add(new LineSeries()); 

      lineSeriesMaxValue1 = this.chartView.Series[1] as LineSeries; 

      Style styleMaxLineSeries = new Style(); 
      styleMaxLineSeries.Setters.Add(new Setter(LineSeries.BackgroundProperty, new SolidColorBrush(Color.FromArgb(255, 234, 178, 15)))); 
      styleMaxLineSeries.Setters.Add(new Setter(LineSeries.TemplateProperty, null)); 

      lineSeriesMaxValue1.DataPointStyle = styleMaxLineSeries; 

      lineSeriesMaxValue1.DependentValuePath = FieldForDependentValue; 
      lineSeriesMaxValue1.IndependentValuePath = FieldForIndependentValue; 

      lineSeriesMaxValue1.ItemsSource = GenerateLimitValues("Max1"); 

      if (this.chartView.Series.Contains(lineSeriesMaxValue1)) 
       this.chartView.Series.Remove(lineSeriesMaxValue1); 

      this.chartView.Series.Add(lineSeriesMaxValue1); 
     } 

     // Adding a min limit to chart 
     if (!ItemsSource.IsNull() && ((!GetMinLimitValue1(this).IsNull()) && !GetMinLimitValue1(this).Equals(0.0))) 
     { 
      this.chartView.Series.Add(new LineSeries()); 

      lineSeriesMinValue1 = this.chartView.Series[2] as LineSeries; 

      Style styleMinLineSeries = new Style(); 
      styleMinLineSeries.Setters.Add(new Setter(LineSeries.BackgroundProperty, new SolidColorBrush(Color.FromArgb(255, 234, 178, 15)))); 
      styleMinLineSeries.Setters.Add(new Setter(LineSeries.TemplateProperty, null)); 

      lineSeriesMinValue1.DataPointStyle = styleMinLineSeries; 

      lineSeriesMinValue1.DependentValuePath = FieldForDependentValue; 
      lineSeriesMinValue1.IndependentValuePath = FieldForIndependentValue; 

      lineSeriesMinValue1.ItemsSource = GenerateLimitValues("Min1"); 

      if (this.chartView.Series.Contains(lineSeriesMinValue1)) 
       this.chartView.Series.Remove(lineSeriesMinValue1); 

      this.chartView.Series.Add(lineSeriesMinValue1); 
     } 

     // Adding a target value to chart 
     if (!ItemsSource.IsNull() && ((!GetTargetValue(this).IsNull()) && !GetTargetValue(this).Equals(0.0))) 
     { 
      this.chartView.Series.Add(new LineSeries()); 

      lineSeriesTarget = this.chartView.Series[3] as LineSeries; 

      Style styleTargetLineSeries = new Style(); 
      styleTargetLineSeries.Setters.Add(new Setter(LineSeries.BackgroundProperty, Brushes.Gray)); 
      styleTargetLineSeries.Setters.Add(new Setter(LineSeries.TemplateProperty, null)); 

      lineSeriesTarget.DataPointStyle = styleTargetLineSeries; 

      lineSeriesTarget.DependentValuePath = FieldForDependentValue; 
      lineSeriesTarget.IndependentValuePath = FieldForIndependentValue; 

      lineSeriesTarget.ItemsSource = GenerateLimitValues("Target"); 

      if (this.chartView.Series.Contains(lineSeriesTarget)) 
       this.chartView.Series.Remove(lineSeriesTarget); 

      this.chartView.Series.Add(lineSeriesTarget); 
     } 

     // Adding a max limit to chart 
     if (!ItemsSource.IsNull() && ((!GetMaxLimitValue2(this).IsNull()) && !GetMaxLimitValue2(this).Equals(0.0))) 
     { 
      this.chartView.Series.Add(new LineSeries()); 

      lineSeriesMaxValue2 = this.chartView.Series[4] as LineSeries; 

      Style styleMaxLineSeries = new Style(); 
      styleMaxLineSeries.Setters.Add(new Setter(LineSeries.BackgroundProperty, new SolidColorBrush(Color.FromArgb(255, 255, 0, 0)))); 
      styleMaxLineSeries.Setters.Add(new Setter(LineSeries.TemplateProperty, null)); 

      lineSeriesMaxValue2.DataPointStyle = styleMaxLineSeries; 

      lineSeriesMaxValue2.DependentValuePath = FieldForDependentValue; 
      lineSeriesMaxValue2.IndependentValuePath = FieldForIndependentValue; 

      lineSeriesMaxValue2.ItemsSource = GenerateLimitValues("Max2"); 

      if (this.chartView.Series.Contains(lineSeriesMaxValue2)) 
       this.chartView.Series.Remove(lineSeriesMaxValue2); 

      this.chartView.Series.Add(lineSeriesMaxValue2); 
     } 

     // Adding a min limit to chart 
     if (!ItemsSource.IsNull() && ((!GetMinLimitValue2(this).IsNull()) && !GetMinLimitValue2(this).Equals(0.0))) 
     { 
      this.chartView.Series.Add(new LineSeries()); 

      lineSeriesMinValue2 = this.chartView.Series[5] as LineSeries; 

      Style styleMinLineSeries = new Style(); 
      styleMinLineSeries.Setters.Add(new Setter(LineSeries.BackgroundProperty, new SolidColorBrush(Color.FromArgb(255, 255, 0, 0)))); 
      styleMinLineSeries.Setters.Add(new Setter(LineSeries.TemplateProperty, null)); 

      lineSeriesMinValue2.DataPointStyle = styleMinLineSeries; 

      lineSeriesMinValue2.DependentValuePath = FieldForDependentValue; 
      lineSeriesMinValue2.IndependentValuePath = FieldForIndependentValue; 

      lineSeriesMinValue2.ItemsSource = GenerateLimitValues("Min2"); 

      if (this.chartView.Series.Contains(lineSeriesMinValue2)) 
       this.chartView.Series.Remove(lineSeriesMinValue2); 

      this.chartView.Series.Add(lineSeriesMinValue2); 
     } 

     // Configure axis 

     if (ItemsSource.IsNull() || (((IList)ItemsSource).Count == 0)) 
     { 
      foreach (var actualAxis in this.chartView.ActualAxes) 
       if (actualAxis.Orientation.Equals(AxisOrientation.Y)) 
       { 
        (actualAxis as LinearAxis).Maximum = null; 
        (actualAxis as LinearAxis).Minimum = null; 

        (actualAxis as LinearAxis).ShowGridLines = ShowGridLinesY; 
        (actualAxis as LinearAxis).Visibility = Visibility.Collapsed; 
       } 
       else if (actualAxis.Orientation.Equals(AxisOrientation.X)) 
       { 
        if (actualAxis is DateTimeAxis) 
        { 
         if (!FieldForIndependentValue.IsNullOrEmpty() && FieldForIndependentValue.Contains("DateTime")) 
         { 
          (actualAxis as DateTimeAxis).Maximum = null; 
          (actualAxis as DateTimeAxis).Minimum = null; 

          (actualAxis as DateTimeAxis).Visibility = Visibility.Collapsed; 
         } 
         else 

          (actualAxis as DateTimeAxis).Visibility = Visibility.Collapsed; 
        } 
        else 
        { 
         if (!FieldForIndependentValue.IsNullOrEmpty() && FieldForIndependentValue.Contains("Double")) 
         { 
          (actualAxis as LinearAxis).Maximum = null; 
          (actualAxis as LinearAxis).Minimum = null; 

          (actualAxis as LinearAxis).Visibility = Visibility.Collapsed; 

          (actualAxis as LinearAxis).ShowGridLines = ShowGridLinesX; 
         } 
         else 

          (actualAxis as LinearAxis).Visibility = Visibility.Collapsed; 
        } 
       } 
     } 
     else if ((this.chartView.Axes.Count > 0) && ((!ItemsSource.IsNull()) && ((IList)ItemsSource).Count > 0)) 
     { 
      foreach (var actualAxis in this.chartView.ActualAxes) 
      { 

       if (actualAxis.Orientation.Equals(AxisOrientation.Y)) 
       { 
        (actualAxis as LinearAxis).Maximum = null; 
        (actualAxis as LinearAxis).Minimum = null; 

        (actualAxis as LinearAxis).Maximum = MaximumAxisY; 
        (actualAxis as LinearAxis).Minimum = MinimumAxisY; 

        (actualAxis as LinearAxis).Visibility = Visibility.Visible; 

        (actualAxis as LinearAxis).ShowGridLines = ShowGridLinesY; 
       } 
       else if (actualAxis.Orientation.Equals(AxisOrientation.X)) 
       { 
        if (actualAxis is DateTimeAxis) 
        { 
         if (!FieldForIndependentValue.IsNullOrEmpty() && FieldForIndependentValue.Contains("DateTime")) 
         { 
          (actualAxis as DateTimeAxis).Maximum = null; 
          (actualAxis as DateTimeAxis).Minimum = null; 

          (actualAxis as DateTimeAxis).Maximum = ((IList<ChartItems>)ItemsSource).Select(s => s.ValueXDateTime).LastOrDefault(); 
          (actualAxis as DateTimeAxis).Minimum = ((IList<ChartItems>)ItemsSource).Select(s => s.ValueXDateTime).FirstOrDefault(); 

          (actualAxis as DateTimeAxis).ShowGridLines = ShowGridLinesX; 

          (actualAxis as DateTimeAxis).Visibility = Visibility.Visible; 
         } 
         else 

          (actualAxis as DateTimeAxis).Visibility = Visibility.Collapsed; 
        } 
        else 
        { 
         if (!FieldForIndependentValue.IsNullOrEmpty() && FieldForIndependentValue.Contains("Double")) 
         { 
          (actualAxis as LinearAxis).Maximum = null; 
          (actualAxis as LinearAxis).Minimum = null; 

          if (IntervalAxisX > 0) 
           (actualAxis as LinearAxis).Interval = IntervalAxisX; 

          (actualAxis as LinearAxis).Maximum = ((IList<ChartItems>)ItemsSource).Select(s => s.ValueXDouble).LastOrDefault() + 0.5; 
          (actualAxis as LinearAxis).Minimum = ((IList<ChartItems>)ItemsSource).Select(s => s.ValueXDouble).FirstOrDefault() - 0.5; 

          (actualAxis as LinearAxis).Visibility = Visibility.Visible; 

          (actualAxis as LinearAxis).ShowGridLines = ShowGridLinesX; 


         } 
         else 
         (actualAxis as LinearAxis).Visibility = Visibility.Collapsed; 
        } 
       } 
      } 
     } 
    } 
} 

어떤 도움을 이해할 수있을 것이다 : 자, 그 여분의 라인을 생성하는 모든 것들이 내 차트에서 일하는 곳

/// <summary> 
/// Generate a ItemsSource using param option informed 
/// </summary> 
/// <param name="option">Min1, Max1, Min2, Max2 or Target Value</param> 
/// <returns>Observable Collection of ChartItems</returns> 
public ObservableCollection<ChartItems> GenerateLimitValues(String option) 
{ 
    var itemsSource = ItemsSource as IEnumerable; 

    if (itemsSource.IsNull()) 
     return null; 

    Double? valueY = 0.0; 

    ObservableCollection<ChartItems> chartItems = new ObservableCollection<ChartItems>(); 

    switch (option) 
    { 
     case "Min1": 
      valueY = GetMinLimitValue1(this); 
      break; 

     case "Max1": 
      valueY = GetMaxLimitValue1(this); 
      break; 

     case "Target": 
      valueY = GetTargetValue(this); 
      break; 

     case "Min2": 
      valueY = GetMinLimitValue2(this); 
      break; 

     case "Max2": 
      valueY = GetMaxLimitValue2(this); 
      break; 
    } 

    foreach (ChartItems itemSource in itemsSource) 
     chartItems.Add(new ChartItems { Name = itemSource.Name, ValueY = valueY.ConvertNullDoubleToDouble(), ValueXDouble = itemSource.ValueXDouble, ValueXDateTime = itemSource.ValueXDateTime }); 

    return chartItems; 
} 

을 자,이입니다.

최고 감사합니다. 구스타보.

+0

(19)가 어떻게이 줄을 추가 않았다 빨간색 숫자 15과 녹색 번호가 표시됩니다 : 여기

은 완전한 예입니다? 차트의 내부 캔버스 (http://vortexwolf.wordpress.com/2011/09/15/silverlight-chart-with-a-goal-line/)를 사용하여 Silverlight 용으로 구현했습니다. 제 기사에서와 같은 방식으로 선을 구현 한 경우 Canvas에 텍스트 블록을 쉽게 추가 할 수 있습니다. – vorrtex

+0

Hy vorrtex, 일부 코드를 추가했습니다. 지연에 대한 미안, 요즘 여행 해요. –

+0

많은 코드가 있지만 어쨌든 여전히 내 대답을 사용할 수 있습니다. Axes를 설정 한 코드 뒤에'OnChartLoaded' 함수를 호출하십시오. – vorrtex

답변

1

차트에 맞춤 요소를 추가하는 것은 어렵지 않습니다. 차트 영역을 가져 와서 요소의 위치를 ​​계산하고 패널에 추가 할 때 요소를 추가해야합니다.

private Canvas canvas; 

public MainWindow() 
{ 
    InitializeComponent(); 

    chart.Loaded += this.OnChartLoaded; 
} 

private void OnChartLoaded(object sender, RoutedEventArgs e) 
{ 
    var chartArea = (Panel)chart.GetType().GetProperty("ChartArea", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(chart, null); 

    // create a canvas to which all text blocks will be added 
    this.canvas = new Canvas(); 
    chartArea.Children.Add(this.canvas); 
} 

public void AddAllLineLabels() 
{ 
    // add a red label 
    double value = 15; 
    var text = new TextBlock() { Text = value.ToString(), Foreground = Brushes.Red }; 
    AddTextToCanvas(canvas, text, value); 

    // add a green label 
    value = 19; 
    text = new TextBlock() { Text = value.ToString(), Foreground = Brushes.Green }; 
    AddTextToCanvas(canvas, text, value); 
} 

private void AddTextToCanvas(Canvas canvas, TextBlock text, double value) 
{ 
    var valuesAxis = chart.ActualAxes.OfType<LinearAxis>().FirstOrDefault(ax => ax.Orientation == AxisOrientation.Y); 

    var min = valuesAxis.ActualMinimum.Value; 
    var max = valuesAxis.ActualMaximum.Value; 

    var maxPixels = valuesAxis.ActualHeight; 
    var valuePixels = (value - min)/(max - min) * maxPixels; // from the bottom edge to the value in pixels 

    Canvas.SetRight(text, 5); // 5 is a padding from the right edge, you can use any number 
    Canvas.SetBottom(text, valuePixels); 
    canvas.Children.Add(text); 
} 

당신이 AddAllLineLabels 메소드를 호출하는 경우가