This is a migrated thread and some comments may be shown as answers.

Get axis label count in DataTemplateSelector

4 Answers 108 Views
ChartView
This is a migrated thread and some comments may be shown as answers.
Brandon
Top achievements
Rank 1
Veteran
Brandon asked on 25 Mar 2020, 02:58 PM

I have a RadChartView with a DateTimeContinuousAxis.  I want my first and last labels to display a particular format (such as YYYY-MM-dd HH:mm:ss), but I want all my inner labels to show a different format (such as simply HH).  I was going to do this with the LabelTemplateSelector based on the AxisLabelModel's CollectionIndex.  However, I don't see a way to tell when I'm at the last label. The documentation of CollectionIndex says

"An AxisLabelModel for example will have this property set to the index of the label within the Telerik.Charting.AxisModel.Labels collection."  However, AxisModel is an internal class, so I cannot access the Labels collection to tell how many labels are on the axis.

How do I get the number of axis labels in my LabelTemplateSelector?

4 Answers, 1 is accepted

Sort by
0
Dinko | Tech Support Engineer
Telerik team
answered on 30 Mar 2020, 10:06 AM

Hi Brandon,

Thank you for the provided details.

You are right that in this particular case, there no easy way to check, which is the last label. I have a few things on my mind, but I will need to test them first. That is why I will need more time. I will contact you again in the next couple of days with my observation.

Regards,
Dinko
Progress Telerik

Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
Our thoughts here at Progress are with those affected by the outbreak.
0
Dinko | Tech Support Engineer
Telerik team
answered on 02 Apr 2020, 12:27 PM

Hi Brandon,

Thank you for your patience.

You are right that there isn't a straight forward approach to get the current number of the labels inside the LabelTemplateSelector. After searching for a possible solution I think I was able to find one. What you can do is to set the Maximum property of the DateTimeContinuousAxis. This way you can compare the incoming label DateTime and the Maximum property. Keep in mind that if the last label is not visible in your project, you will need probably to just the MajorStep property so that the last label will be visible. You will also need to remove SmartLabels mode if such is applied.

public DataTemplate LastLabelTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
    var model = item as AxisLabelModel;
    var categoricalAxis = container as DateTimeContinuousAxis;
    if (categoricalAxis.Maximum.Date == ((DateTime)model.Content).Date)
    {
        return LastLabelTemplate;
    }
    return base.SelectTemplate(item, container);
}

Regards,
Dinko
Progress Telerik

Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
Our thoughts here at Progress are with those affected by the outbreak.
0
Brandon
Top achievements
Rank 1
Veteran
answered on 02 Apr 2020, 09:54 PM

The way my axis is currently set up, I manually adjust my TickOrigin, MajorStepUnit, and MajorStep on a Zoom/Pan so my labels have "nice" values (for instance, depending on the zoom level, labels will show ever 1, 5, 15, or 60 minutes).  As the graph pans, I don't always have a label exactly on either edge of my axis, so I can't do an equality comparison with the ActualVisibleRange.Maximum.  I set LastLabelVisibility="Visible" but that doesn't seem to affect it.

Here is the XAML for my HorizontalAxis.

<telerik:DateTimeContinuousAxis x:Name="XAxis"
                     ElementBrush="White"
                     LastLabelVisibility="Visible"
                     IsStepRecalculationOnZoomEnabled="False"
                     PlotMode="OnTicks"
                     ContextMenu="{StaticResource AxisContextMenu}"
                     ActualVisibleRangeChanged="XAxis_OnActualVisibleRangeChanged"
                     ActualRangeChanged="XAxis_OnActualRangeChanged"
                     PreviewMouseDoubleClick="XAxis_OnPreviewMouseDoubleClick">
  <telerik:DateTimeContinuousAxis.Resources>
    <!-- Label templates for different zoom levels go here -->
  </telerik:DateTimeContinuousAxis.Resources>
  <telerik:DateTimeContinuousAxis.LabelTemplateSelector>
    <plot:DateTimeAxisLabelSelector DateTimeFullLabelTemplate="{StaticResource Fullemplate}"
                          DateTimeSecondLabelTemplate="{StaticResource SecondTemplate}"
                          DateTimeMinuteLabelTemplate="{StaticResource MinuteTemplate}"
                          DateTimeHourLabelTemplate="{StaticResource HourTemplate}"
                          DateTimeDateLabelTemplate="{StaticResource DateTemplate}"
                          DateTimeDayLabelTemplate="{StaticResource DayTemplate}"
                          DateTimeMonthLabelTemplate="{StaticResource MonthTemplate}"/>
  </telerik:DateTimeContinuousAxis.LabelTemplateSelector>
</telerik:DateTimeContinuousAxis>

 

And here is a portion of my code-behind for setting my axis label intervals:

private void XAxis_OnActualVisibleRangeChanged(Object sender, DateTimeRangeChangedEventArgs e)
{
  var range = XAxis.ActualVisibleRange.Maximum - XAxis.ActualVisibleRange.Minimum;
 
  // NOTE: Handling for additional zoom levels removed here for space.
  if (range > TimeSpan.FromMinutes(8))
  {
    XAxis.MajorStepUnit = TimeInterval.Minute;
    XAxis.MajorStep = 1;
  }
  else if (range > TimeSpan.FromMinutes(3))
  {
    XAxis.MajorStepUnit = TimeInterval.Second;
    XAxis.MajorStep = 15;
  }
  else if (range > TimeSpan.FromSeconds(30))
  {
    XAxis.MajorStepUnit = TimeInterval.Second;
    XAxis.MajorStep = 5;
  }
  else
  {
    XAxis.MajorStepUnit = TimeInterval.Second;
    XAxis.MajorStep = 1;
  }
 
  // Force the LabelTemplateSelector to re-evaluate.  When the graph is panned/zoomed, a date label
  // may move along the axis and its display format may need to change (e.g. it is no longer the
  // first label, or the label interval has changed).
  var labelTemplateSelector = XAxis.LabelTemplateSelector;
  XAxis.LabelTemplateSelector = null;
  XAxis.LabelTemplateSelector = labelTemplateSelector;
}

 

Any other ideas?  Or is there something I'm missing for how to force an axis label at either edge of my axis?

0
Dinko | Tech Support Engineer
Telerik team
answered on 07 Apr 2020, 01:48 PM

Hi Brandon,

Thank you for the provided additional information.

Another approach that you can try is to manually get the last TextBlock on the axis using the ChildrenOfType<T>() extension method. You can wrap the execution of the code inside a Dispatcher.BeginInvoke() method. To change the TextBlock on the first label you can use the LabelTemplateSelector. I understand that this is not a perfect solution but still, you can consider it. Check the attached project which demonstrates this.

Another approach will be to remove the last label by setting the LastLabelVisibility property to Collapsed. Then you can use a Custom Annotation and manually position a TextBlock on the axis. The TextBlock will serve as the last label. Keep in mind that you will need to write custom code to calculate the date and its position.

Regards,
Dinko
Progress Telerik

Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
Our thoughts here at Progress are with those affected by the outbreak.
Tags
ChartView
Asked by
Brandon
Top achievements
Rank 1
Veteran
Answers by
Dinko | Tech Support Engineer
Telerik team
Brandon
Top achievements
Rank 1
Veteran
Share this question
or