Loop over DataSeriesItems selected by RangeSelector

Hi!
I’m using Vaadin charts 4.0.0 and especially the timeline component.
The displayed values are limited by a RangeSelector:

RangeSelector rangeSelector = new RangeSelector();
rangeSelector.setSelected(1);
configuration.setRangeSelector(rangeSelector);

Is it possible to loop over only those elements within my DataSeries, that are in the RangeSelector’s range?
Thanks for your help in advance and I hope I didn’t overlook an obvious solution.

33001.png

I’m trying to grasp more clearer what you are trying to achieve. Do I understand correctly that when the user selects a range, let’s say 2017-02-01 - 2017-05-01, then you wan the following:

  1. A listener is triggered that the selected range is changed, along with the start and end valiues
  2. A way to get all the data points that are between the two dates

Did I get your requirement correctly? What kind of DataSeries do you have in use? Plain DataSeries or ListSeries?

Thanks for your quick reply!

I use plain series:
DataSeries dataSeries = new DataSeries();

Your requirement 2) fits perfect. Concerning point 1) it would be great if I could access the data points without a previous RangeEvent, so I can work time independently.

I browsed the APIs and it seems like we have nothing such in place right now. I guess you have to build it in yourself to be able to iterate over a certain range. If we go with the assumption that the points are in date order, then it shouldn’t be too hard to do. I see two options:

  1. Manage a separate map of <Date, DataSeriesItem>. When you have a start date and end date, you can get references to them easily from the map with the date. When you have fetched start and end data points you can get their index positions in the DataSeries and iterate from start index to end index.

  2. If you don’t want to maintain an own list, you can do the first part with an own lookup method like private int findIndex(Date) which then returns the index for the start and end points. It can be a devide and conquer kind of alghoritm or something similar to find the points faster compared to iterating though the whole list.

Sorry for not having ready made API points to point to, but hopefully you get forward with these. :slight_smile:

Ok. Thanks for browsing the API.

Here is my workaround. I consider that there might be several DataSeries and some of them could be made of FlagItems, which I intend to ignore.

First: Get the range from changes on the chart

Date rangeMinDate; Date rangeMaxDate; chart.addXAxesExtremesChangeListener(new XAxesExtremesChangeListener() { @Override public void onXAxesExtremesChange(XAxesExtremesChangeEvent event) { rangeMinDate = Util.toServerDate(event.getMinimum().doubleValue()); rangeMaxDate = Util.toServerDate(event.getMaximum().doubleValue()); } }); Afterwards loop over all Series and their items. Ignore if further plot options indicate a List of flags public void getAllSensorValuesInRange() { Configuration configuration = chart.getConfiguration(); List<Series> seriesList = configuration.getSeries(); for (int i = 0; i < seriesList.size(); i++) { DataSeries currentList = (DataSeries) seriesList.get(i); if (currentList.getPlotOptions() != null) { // In my case: List with FlagItems } else { for (int j = 0; j < currentList.size(); j++) { Date currentDate = new Date(currentList.get(j).getX().longValue()); if (currentDate.after(rangeMinDate) && currentDate.before(rangeMaxDate)) { //These are all Values within the range of the RangeSelector currentList.get(j).getY()); } } } } } Comments and improvements are very welcome :slight_smile:

Nice. I guess the loop on rows 9-15 you could optimize a bit as it now loops all the items through instead of effectively finding first and last relevant item. If you’d do that, then it would become something like: int startIndex = findIndex(rangeMinDate); int endIndex = findIndex(rangeMaxDate)+1; for (int j = startIndex; j < endIndex; j++) { //These are all Values within the range of the RangeSelector currentList.get(j).getY(); } But the question stands if this is worth doing. Do you have performance issues or something similar? If not, let it be like it is without spending too much time overoptimizing.

I like your solution. :slight_smile:
So far, there are no performance issues. Though, I might deal with larger timelines in the future.