I'm creating a User Control componente of type DataVisualization.Chart. Right now, he accepts 4 range limits (1 range minimum of accept value and 1 maximum, also 1 range minimum of warning value and 1 maximum warning range value). So far, so good. It works. But i need to add a TextBlock (or label, or TextBox, whatever) at the end of the LineSeries.
This is my actual LineSeries:
Now i need to make something like this:
Even if the result is not the same, i need to put a label or textblock at the end of every LineDataPoint.
Edit 1:
This is how my list of items is generated:
/// <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;
}
Basically, it generate a new ItemsSource to use in my Chart. Now, to generate those extra lines:
/// <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;
}
Now, this is where all the things work in my Chart:
/// <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;
}
}
}
}
}
}
Any help will be appreciated.
Best Regards, Gustavo.