Hi,
I am zooming to particular area of the ChartView. Depending on the zoom, some lines may not be visible in the current zoomed in portion of the chart. So, the legend is displaying items that are not currently visible in the chart. I need to display legend only for the lines that are visible in different zoom/pan settings. How to achieve this?
5 Answers, 1 is accepted
0
Hello, Borislav,
Thank you for writing.
You can iterate the ChartElement.LegendElement.StackElement.Children collection and show/hide the respective LegendItemElement according to your custom requirement. You can find below a sample code snippet demonstrating how to hide the chart legend items for series that are not visible in the chart:
If you have any further questions feel free to submit a support ticket in the support ticketing system where threads are handled according to license and time of posting. Thank you for your understanding.
I hope this information helps.
Regards,
Dess
Progress Telerik
Thank you for writing.
You can iterate the ChartElement.LegendElement.StackElement.Children collection and show/hide the respective LegendItemElement according to your custom requirement. You can find below a sample code snippet demonstrating how to hide the chart legend items for series that are not visible in the chart:
public
RadForm1()
{
InitializeComponent();
BarSeries barSeries =
new
BarSeries(
"Performance"
,
"RepresentativeName"
);
barSeries.LegendTitle =
"Q1"
;
barSeries.DataPoints.Add(
new
CategoricalDataPoint(177,
"Harley"
));
barSeries.DataPoints.Add(
new
CategoricalDataPoint(128,
"White"
));
barSeries.DataPoints.Add(
new
CategoricalDataPoint(143,
"Smith"
));
barSeries.DataPoints.Add(
new
CategoricalDataPoint(111,
"Jones"
));
barSeries.DataPoints.Add(
new
CategoricalDataPoint(118,
"Marshall"
));
this
.radChartView1.Series.Add(barSeries);
BarSeries barSeries2 =
new
BarSeries(
"Performance"
,
"RepresentativeName"
);
barSeries2.LegendTitle =
"Q2"
;
barSeries2.DataPoints.Add(
new
CategoricalDataPoint(153,
"Harley"
));
barSeries2.DataPoints.Add(
new
CategoricalDataPoint(141,
"White"
));
barSeries2.DataPoints.Add(
new
CategoricalDataPoint(130,
"Smith"
));
barSeries2.DataPoints.Add(
new
CategoricalDataPoint(88,
"Jones"
));
barSeries2.DataPoints.Add(
new
CategoricalDataPoint(109,
"Marshall"
));
this
.radChartView1.Series.Add(barSeries2);
this
.radChartView1.ShowLegend =
true
;
}
private
void
radButton1_Click(
object
sender, EventArgs e)
{
this
.radChartView1.Series[0].IsVisible = !
this
.radChartView1.Series[0].IsVisible;
foreach
(LegendItemElement itemElement
in
this
.radChartView1.ChartElement.LegendElement.StackElement.Children)
{
BarSeries s = itemElement.LegendItem.Element
as
BarSeries;
if
(s !=
null
)
{
if
(s.IsVisible)
{
itemElement.Visibility = Telerik.WinControls.ElementVisibility.Visible;
}
else
{
itemElement.Visibility = Telerik.WinControls.ElementVisibility.Collapsed;
}
}
}
}
If you have any further questions feel free to submit a support ticket in the support ticketing system where threads are handled according to license and time of posting. Thank you for your understanding.
I hope this information helps.
Regards,
Dess
Progress Telerik
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Borislav
Top achievements
Rank 1
answered on 18 Oct 2017, 04:22 PM
The solution you provided is not applicable to the situation I have, since all of my series have values on the whole x axis range. I believe this is why IsVisible is always true for all series. However, I want to hide labels in case a user has zoomed in somewhere on the chart where values of particular series are not visible in the current viewport, For example, current viewport has range between 20 and 40 on the y axis, and the series have values that are below 20, so they are not visible in the current viewport. I want to hide legend items for these series that are not visible in the current viewport. How to achieve this? I hope my question is clear enough.
0
Borislav
Top achievements
Rank 1
answered on 18 Oct 2017, 06:21 PM
If it's of importance, my x axis is CategoricalAxis.
0
Borislav
Top achievements
Rank 1
answered on 20 Oct 2017, 12:33 PM
I narrowed problem to to checking if all of the categorical points of the series fall into visible range. Thing is that I didn't find of way of comparing the layout slot of the point with the layout slot of the chart. Regardless of the zoom level, layout slot of the chart has always fixed dimensions (1000 x 800), while the layout slot of the point depends on the zoom level so it can be anywhere in the range of (xZoomLevel * 1000) X (yZoomLevel * 800) thus I cannot try to find intersection of the visible portion of the chart and categorical points. Do you have any suggestion on how to achieve this?
0
Hello, Borislav,
Thank you for writing back.
I have prepared a sample code snippet demonstrating how to hide the legend items for series that are not visible in the zoomed view range:
Note that this is just a sample approach and it may not cover all possible cases. Feel free to modify it in a way which suits your requirement best.
I hope this information helps. If you have any additional questions, please let me know.
Regards,
Dess
Progress Telerik
Thank you for writing back.
I have prepared a sample code snippet demonstrating how to hide the legend items for series that are not visible in the zoomed view range:
public
RadForm1()
{
InitializeComponent();
BarSeries barSeries =
new
BarSeries(
"Performance"
,
"RepresentativeName"
);
barSeries.LegendTitle =
"Q1"
;
barSeries.DataPoints.Add(
new
CategoricalDataPoint(177,
"Harley"
));
barSeries.DataPoints.Add(
new
CategoricalDataPoint(128,
"White"
));
this
.radChartView1.Series.Add(barSeries);
BarSeries barSeries2 =
new
BarSeries(
"Performance"
,
"RepresentativeName"
);
barSeries2.LegendTitle =
"Q2"
;
barSeries2.DataPoints.Add(
new
CategoricalDataPoint(130,
"Smith"
));
barSeries2.DataPoints.Add(
new
CategoricalDataPoint(88,
"Jones"
));
barSeries2.DataPoints.Add(
new
CategoricalDataPoint(109,
"Marshall"
));
this
.radChartView1.Series.Add(barSeries2);
this
.radChartView1.ShowLegend =
true
;
ChartPanZoomController panZoomController =
new
ChartPanZoomController();
panZoomController.PanZoomMode = ChartPanZoomMode.Horizontal;
radChartView1.Controllers.Add(panZoomController);
this
.radChartView1.View.ZoomChanged += View_ZoomChanged;
this
.radChartView1.View.PanChanged += View_PanChanged;
}
void
View_PanChanged(
object
sender, EventArgs e)
{
UpdateLegentItems();
}
private
void
View_ZoomChanged(
object
sender, EventArgs e)
{
UpdateLegentItems();
}
private
void
UpdateLegentItems()
{
Dictionary<ChartSeries,
int
> visiblePoints =
new
Dictionary<ChartSeries,
int
>();
IChartView view = ((IChartView)
this
.radChartView1.View);
foreach
(ChartSeries series
in
this
.radChartView1.Series)
{
foreach
(var dp
in
series.DataPoints)
{
CategoricalDataPoint cdp = (CategoricalDataPoint)dp;
if
(CheckIfDataPointIsVisible(view, cdp))
{
if
(!visiblePoints.ContainsKey(series))
{
visiblePoints.Add(series, 0);
}
visiblePoints[series]++;
}
}
}
//update the legend items considering the visible series
foreach
(LegendItemElement itemElement
in
this
.radChartView1.ChartElement.LegendElement.StackElement.Children)
{
if
(visiblePoints.ContainsKey(itemElement.LegendItem.Element
as
ChartSeries))
{
itemElement.Visibility = Telerik.WinControls.ElementVisibility.Visible;
}
else
{
itemElement.Visibility = Telerik.WinControls.ElementVisibility.Collapsed;
}
}
}
private
bool
CheckIfDataPointIsVisible(IChartView view, CategoricalDataPoint cdp)
{
double
width = ((ChartSeries)cdp.Presenter).Axes[1].Model.LayoutSlot.Width;
RadRect viewport =
new
RadRect(-view.PlotOriginX + width, -view.PlotOriginY, view.ViewportWidth, view.ViewportHeight);
return
viewport.IntersectsWith(cdp.LayoutSlot);
}
Note that this is just a sample approach and it may not cover all possible cases. Feel free to modify it in a way which suits your requirement best.
I hope this information helps. If you have any additional questions, please let me know.
Regards,
Dess
Progress Telerik
Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.