XYLineChart with a TimeSeries containing only a single point

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
Locked
JenSmith
Posts: 5
Joined: Mon Oct 10, 2016 9:44 pm
antibot: No, of course not.

XYLineChart with a TimeSeries containing only a single point

Post by JenSmith » Mon Oct 10, 2016 10:32 pm

Hello, everyone. I'm currently working on a project that plots data in near real-time on several types of JFreeCharts. I've noticed a problem with my XYLineCharts, however, and I was wondering whether there might be a workaround to get what I want, or if I'm just stuck by the limitations of the chart's fundamental design. Here's my problem:

I have an XYLineChart that gets populated with data which falls into several TimeSeries in its TimeSeriesCollection, as time progresses. When the program receives a new point of data, it adds it to the appropriate TimeSeries (if it exists), or creates a new TimeSeries to put it into, which is then put into the TimeSeriesCollection. After this, the chart is redrawn.

For the most part, this process works just fine. The only hitch is right after the generation of a new TimeSeries - during the time when it only contains one point of data. When the chart is redrawn after having added this single-point TimeSeries, the new point will not appear on the chart. I have a refresh function I use to redraw everything, and the syntax is very similar to the following:

Code: Select all

public void refresh() {
  // the JFreeChart "chart", and TimeSeriesCollection "collect" are created and initialized outside this function's scope. 
  // Also defined are a DateAxis and NumberAxis for the chart, retrievable by calling getDa() and getNa(), respectively.
  // Finally, also defined is a till value, retrievable by calling getTill().
  scale();
  XYLineAndShapeRenderer r = new XYLineAndShapeRenderer();
  final int size = collect.getSeriesCount();

  for (int i = 0; i < size; i++) {
    r.setSeriesLinesVisible(i, false);
    r.setSeriesShapesVisible(i, true);

    // code to determine which color to make the series. Color is stored in the variable "color"

    r.setSeriesPaint(i, color); 
    r.setSeriesShape(i, new Ellipse2D.Double(0, 0, 5, 5);
  }
  chart.getPlot().setRenderer(r);
}

private void scale() {
  Date maxtime = null;
  Date mintime = null;
  double l = 0.0;
  double u = 0.0;

  // I have code here to find the current min and max times, and populate the above values.

  final Date minTime = mintime; // minimum time for this plot
  final Date maxTime = maxtime; // maximum time for this plot
  final double lower = l;  //minimum value for this plot
  final double upper = u; //upper value for this plot

  if (minTime != null && maxTime != null) {
    getDa().setRange(minTime.getTime(), maxTime.getTime());
    if (lower <= upper) {
      getNa().setRange(lower, upper);
    }
  } else {
    if (getDa().isAutoRange()) {
      getDa().setFixedAutoRange(getTill());
    }

    if (lower <= upper) {
      getNa().setRange(lower, upper);
      getNa().setFixedAutoRange(upper - lower);
    }
  }
}
I'm hoping that this is enough for you to be able to tell me what I'm doing wrong (if that's what the problem is), because I work on a project that I'm not at liberty to share in venues like this, so I've had to change a few variable names and omit a few proprietary portions. Let me know if you need more information, and I'll do my best to fill the gaps.

So how about it? What can I do to ensure that when I redraw my chart, any TimeSeries that contains only a single point will be shown on the chart? I thought having this line:

Code: Select all

r.setSeriesShapesVisible(i, true);
would ensure it, but it's not working. The point will only show when the series gets a second data point to go with it. Any ideas?

paradoxoff
Posts: 1634
Joined: Sat Feb 17, 2007 1:51 pm

Re: XYLineChart with a TimeSeries containing only a single p

Post by paradoxoff » Tue Oct 11, 2016 12:01 pm

The point will only show when the series gets a second data point to go with it.
Does that mean that a single point does not show up, but as soon as you add a second one, both points are visible?
Or does it mean that no points are shown, and a line segment only appears after you have added a second point?

JenSmith
Posts: 5
Joined: Mon Oct 10, 2016 9:44 pm
antibot: No, of course not.

Re: XYLineChart with a TimeSeries containing only a single p

Post by JenSmith » Tue Oct 11, 2016 2:43 pm

Does that mean that a single point does not show up, but as soon as you add a second one, both points are visible?
Or does it mean that no points are shown, and a line segment only appears after you have added a second point?
I'm sorry; I should have specified. The chart appears to only be showing points that have preceded other points. After scrutinizing the progression of them, I've determined that even series with multiple points fail to plot the last one, until a new one in that series comes along. The last point is getting left off of the chart each time. That may be why series with only one point aren't showing on the graph.

And I'm not plotting line segments (though I know that's what the graph is for); I've turned the lines off, and I'm only plotting the points.

paradoxoff
Posts: 1634
Joined: Sat Feb 17, 2007 1:51 pm

Re: XYLineChart with a TimeSeries containing only a single p

Post by paradoxoff » Tue Oct 11, 2016 4:37 pm

Then, I suggest to comment the scale() method and turn autoRange on for both axes. If that works, check your minTime/maxTime variables and/or getTill() method to make sure that the resulting date range of the date axis is indeed sufficient to show all data points.

JenSmith
Posts: 5
Joined: Mon Oct 10, 2016 9:44 pm
antibot: No, of course not.

Re: XYLineChart with a TimeSeries containing only a single p

Post by JenSmith » Tue Oct 11, 2016 5:24 pm

paradoxoff wrote:Then, I suggest to comment the scale() method and turn autoRange on for both axes. If that works, check your minTime/maxTime variables and/or getTill() method to make sure that the resulting date range of the date axis is indeed sufficient to show all data points.
Ooh, this is very good advice! I am indeed able to see all points if I turn off my scale method. I'll go reevaluate how I'm calculating scale. I appreciate the help!

JenSmith
Posts: 5
Joined: Mon Oct 10, 2016 9:44 pm
antibot: No, of course not.

Re: XYLineChart with a TimeSeries containing only a single p

Post by JenSmith » Wed Oct 12, 2016 6:06 pm

Okay; I think I've isolated the problem. In my program, I'm always falling into the following condition:

Code: Select all

if (getDa().isAutoRange()) {
      getDa().setFixedAutoRange(getTill());
    }
Whenever I set a fixed auto range on the plot, it always cuts off the last plot point. Always. I'm not sure why this is, and I can't seem to find any documentation online of a known bug with this function. Am I onto something here, or have I made a mistake? When I don't set a fixed auto range (and FYI: the till value is a constant, so it's not changing throughout the course of the program), I can see all the points as they come in, but if I do, then it always lops off the last point in a series as it comes in, and bumps the previous one into appearing on the graph.

paradoxoff
Posts: 1634
Joined: Sat Feb 17, 2007 1:51 pm

Re: XYLineChart with a TimeSeries containing only a single p

Post by paradoxoff » Wed Oct 12, 2016 9:25 pm

JenSmith wrote: Whenever I set a fixed auto range on the plot, it always cuts off the last plot point.
Is the "last point" the last one added or the one with a highest/lowest y value?
What is the value of getTill()? Are you aware that it is (at least for a DateAxis) a time range in milliseconds, and that the lower bound of the DateAxis will be adjusted so that the fixed auto range is reached?

JenSmith
Posts: 5
Joined: Mon Oct 10, 2016 9:44 pm
antibot: No, of course not.

Re: XYLineChart with a TimeSeries containing only a single p

Post by JenSmith » Wed Oct 12, 2016 10:08 pm

paradoxoff wrote:Is the "last point" the last one added or the one with a highest/lowest y value?
What is the value of getTill()? Are you aware that it is (at least for a DateAxis) a time range in milliseconds, and that the lower bound of the DateAxis will be adjusted so that the fixed auto range is reached?
By "last point," I mean the last point in any given TImeSeries that's being graphed. And yes, I am aware that the time range is in milliseconds; my till has been set to a static value 360000. When you say "the lower bound of the DateAxis will be adjusted so that the fixed auto range is reached," what do you mean exactly? Are you saying that it will shift to the right on my plot so that the last point in the DataSet is visible on the graph, while showing the time span (360000 ms)? If yes, then yes, I am aware of that.

paradoxoff
Posts: 1634
Joined: Sat Feb 17, 2007 1:51 pm

Re: XYLineChart with a TimeSeries containing only a single p

Post by paradoxoff » Thu Oct 13, 2016 9:22 am

JenSmith wrote:When you say "the lower bound of the DateAxis will be adjusted so that the fixed auto range is reached," what do you mean exactly? Are you saying that it will shift to the right on my plot so that the last point in the DataSet is visible on the graph, while showing the time span (360000 ms)? If yes, then yes, I am aware of that.
Yes, thats what I meant. If autoRange is active, the range of the axis is calculated in a way that all data points should be visible. If a fixedAutoRange is used, the DateAxis will finally have a range between "autoUpperBound" - fixedAutoRange and "autoUpperBound".
Are you seeing the issues both with null and non-null minTime and maxTime?

Locked