To Those Who Use JFreeChart for Dynamic Plotting/Large Sets
Re: To Those Who Use JFreeChart for Dynamic Plotting/Large Sets
The profiler reported it was my tooltip generator that was taking up most of the rendering time. However this was the case for both the Fast and the Normal renderer. So having taken out the tooltip generator, the rendering time has significantly improved, but the Fast renderer (1300ms) is still relatively slower than the Normal renderer (1050ms).
Further investigation ongoing...
Further investigation ongoing...
Re: To Those Who Use JFreeChart for Dynamic Plotting/Large Sets
Okay, after reading through the code, I see that the renderedPixels bitset is cleared after every drawItem() call i.e. after each series is rendered. If this is the case, then I cannot understand where the speed improvements are going to come from since only points from the same series that map to the same pixels will be skipped over. And this will almost never be the case in a time series. It was my impression that it would be better that points from different series that map to the same pixel were going to be skipped as well.
-
- Posts: 1634
- Joined: Sat Feb 17, 2007 1:51 pm
Re: To Those Who Use JFreeChart for Dynamic Plotting/Large Sets
Hi Grimlock,
first of all: thanks for testing! That is really appreciated!
The comment on the patch tracker concerning the output of the FastXYLineAndShapeRenderer should have been better phrased as "close to an XYLineAndShapeRenderer" instead of "indistinguishable". The latter means that both lines and shapes are supported and that the useOutlinePaint, useFillPaint and drawOutlines flags (I forgot to mention the itemShapeFilled flag) are respected. The FastXYLineAndShapeRenderer is thus "closest" to an XYLineAndShapeRenderer.
The fact that lines between invisible points are not drawn is something that could be removed or replaced with a more clever and safer algorithm. However, cases where lines that would at least be partially visible in an XYPlot are skipped are conceivable. Upon initialization, the SamplingXYLineRenderer returns a state object that uses the default true value for the processVisibleItems only flag. It will thus not consider items that are far outside the domain axis range. it is nevertheless possible that a line drawn from such an item would pass through the data area.
You are right that the fast renderer will draw lines of the n+1-th series on top of the shapes of the n-th series. The XYLineAndShapeRenderer will first draw the lines of all series and then draw the shapes of all series. Personally, I prefer the former way as it renders the line and shapes of a given series on an identical "layer". However, that may change, as I want to bring the "architecture" of the fast renderer closer to the XYLineAndShapeRenderer, i.e. override the drawPrimaryLIneXXX and drawSecondaryPass with optimized version, leave the rest of the XYLineAndShapeRenderer as it is and see how that behaves.
I agree that skipping data items which would be covered by data items of a different series would probably be a further improvement. I have not yet implemented this for two reasons: first, I didn´t have a good idead how that could be implemented, and second: if a data item in series n is rendered on the same pixel as an item in series n+1, the former should be dropped because we assume that I will be covered the item from the n+1 series and will thus be invisible anyways. But what if the series shape for series n is larger thatn for the series n+1? With the present approach, the item of series n will be partly visible, using the new approach it will be dropped and thus not appear in the plot. Nevertheless, this is something to think about (maybe as an optional feature that can be switched on and off with a simple flag).
Finally, concerning the performance measurements: I have run a few benchmarks on my own, and in my experience the fast renderer is faster than an XYLineAndShapeRenderer, even for small datasets (for which it wasn´t designed). But I have tested only with one series. How have you organized your 5000 points, i.e. how many datasets and series? Here is the code that I have used (part of it was taken from uvoigts example)
first of all: thanks for testing! That is really appreciated!

The comment on the patch tracker concerning the output of the FastXYLineAndShapeRenderer should have been better phrased as "close to an XYLineAndShapeRenderer" instead of "indistinguishable". The latter means that both lines and shapes are supported and that the useOutlinePaint, useFillPaint and drawOutlines flags (I forgot to mention the itemShapeFilled flag) are respected. The FastXYLineAndShapeRenderer is thus "closest" to an XYLineAndShapeRenderer.
The fact that lines between invisible points are not drawn is something that could be removed or replaced with a more clever and safer algorithm. However, cases where lines that would at least be partially visible in an XYPlot are skipped are conceivable. Upon initialization, the SamplingXYLineRenderer returns a state object that uses the default true value for the processVisibleItems only flag. It will thus not consider items that are far outside the domain axis range. it is nevertheless possible that a line drawn from such an item would pass through the data area.
You are right that the fast renderer will draw lines of the n+1-th series on top of the shapes of the n-th series. The XYLineAndShapeRenderer will first draw the lines of all series and then draw the shapes of all series. Personally, I prefer the former way as it renders the line and shapes of a given series on an identical "layer". However, that may change, as I want to bring the "architecture" of the fast renderer closer to the XYLineAndShapeRenderer, i.e. override the drawPrimaryLIneXXX and drawSecondaryPass with optimized version, leave the rest of the XYLineAndShapeRenderer as it is and see how that behaves.
I agree that skipping data items which would be covered by data items of a different series would probably be a further improvement. I have not yet implemented this for two reasons: first, I didn´t have a good idead how that could be implemented, and second: if a data item in series n is rendered on the same pixel as an item in series n+1, the former should be dropped because we assume that I will be covered the item from the n+1 series and will thus be invisible anyways. But what if the series shape for series n is larger thatn for the series n+1? With the present approach, the item of series n will be partly visible, using the new approach it will be dropped and thus not appear in the plot. Nevertheless, this is something to think about (maybe as an optional feature that can be switched on and off with a simple flag).
Finally, concerning the performance measurements: I have run a few benchmarks on my own, and in my experience the fast renderer is faster than an XYLineAndShapeRenderer, even for small datasets (for which it wasn´t designed). But I have tested only with one series. How have you organized your 5000 points, i.e. how many datasets and series? Here is the code that I have used (part of it was taken from uvoigts example)
Code: Select all
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.StandardChartTheme;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.*;
import org.jfree.data.xy.*;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;
public class XYItemRendererBenchmark{
public static void main(String[] args){
DefaultXYDataset dataset = new DefaultXYDataset();
double x = 0.0;
double y = 0.0;
int count = 500000;
double[][] data = new double[2][count];
for (int i = 0; i < count; i++){
double r = Math.random();
if (r < 0.33){
y += Math.random();
}
else if (r < 0.66){
y -= Math.random();
}
if ((int)(r * 100) % 5 == 0){
data[0][i] = x;
data[1][i] = Double.NaN;
}
else{
data[0][i] = x;
data[1][i] = y;
}
x += Math.random();
}
dataset.addSeries("Values",data);
SamplingXYLineRenderer samplingLines = new SamplingXYLineRenderer();
samplingLines.setSeriesPaint(0, Color.BLUE);
samplingLines.setSeriesShape(0, new Ellipse2D.Double(-4, -4, 8, 8));
XYLineAndShapeRenderer standardLines = new XYLineAndShapeRenderer(false, true);
standardLines.setSeriesPaint(0, Color.BLUE);
standardLines.setSeriesShape(0, new Ellipse2D.Double(-4, -4, 8, 8));
FastXYLineAndShapeRenderer fastLines = new FastXYLineAndShapeRenderer(false, true, 1);
fastLines.setSeriesPaint(0, Color.BLUE);
fastLines.setSeriesShape(0, new Ellipse2D.Double(-4, -4, 8, 8));
XYPlot plot = new XYPlot(dataset, new NumberAxis("x"), new NumberAxis("y"), null);
JFreeChart chart = new JFreeChart(plot);
BufferedImage image = new BufferedImage(500, 500, BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D g2 = (Graphics2D)image.getGraphics();
Rectangle2D.Double area = new Rectangle2D.Double(0, 0, 500, 500);
String description = "";
long start = 0;
plot.setRenderer(samplingLines);
description = plot.getRenderer().getClass().getName();
start = System.currentTimeMillis();
for(int i = 0; i < 10; i++){
chart.draw(g2, area);
}
System.out.println(description + " : "+(start - System.currentTimeMillis()));
save(image, description);
plot.setRenderer(standardLines);
description = plot.getRenderer().getClass().getName();
start = System.currentTimeMillis();
for(int i = 0; i < 10; i++){
chart.draw(g2, area);
}
System.out.println(description + " : "+(start - System.currentTimeMillis()));
save(image, description);
plot.setRenderer(fastLines);
description = plot.getRenderer().getClass().getName();
start = System.currentTimeMillis();
for(int i = 0; i < 10; i++){
chart.draw(g2, area);
}
System.out.println(description + " : "+(start - System.currentTimeMillis()));
save(image, description);
}
private static void save(BufferedImage image, String name){
try{
ImageIO.write(image,"PNG", new File(name+".png"));
}
catch(IOException ieo){
ieo.printStackTrace();
}
}
}
Re: To Those Who Use JFreeChart for Dynamic Plotting/Large Sets
Thanks for such an extensive reply.
I have only one dataset but instead of one series with many points as in your example, I have about 4800 serise containing just the 1 point and 200 with multiple points. My test code is an extreme case, but it's a situation that can arise in my application and is the major source of rendering issues in my application. I'll try and create a dataset with a moderate amount of series with a moderate amount of points and see how that goes.
With regards to your example, you have a set of points that are located in close proximity to each other. Hence I can understand the saving that comes with the Fast renderer as many points from the same series will be overlapping. However in a time series this will not be the case, as the points from the same series are spread out with lines connecting them. After reading your explanation, I can see this is another case of me trying to fit a square peg in a round hole.
I have only one dataset but instead of one series with many points as in your example, I have about 4800 serise containing just the 1 point and 200 with multiple points. My test code is an extreme case, but it's a situation that can arise in my application and is the major source of rendering issues in my application. I'll try and create a dataset with a moderate amount of series with a moderate amount of points and see how that goes.
With regards to your example, you have a set of points that are located in close proximity to each other. Hence I can understand the saving that comes with the Fast renderer as many points from the same series will be overlapping. However in a time series this will not be the case, as the points from the same series are spread out with lines connecting them. After reading your explanation, I can see this is another case of me trying to fit a square peg in a round hole.
-
- Posts: 1634
- Joined: Sat Feb 17, 2007 1:51 pm
Re: To Those Who Use JFreeChart for Dynamic Plotting/Large Sets
Hi Grimlock,
your last point explains a lot.
Since the fast renderer skips data items on a per-series basis, there is no improvement for series with non-superimposed items. And since the renderedPixels BitSet is cleared for every series, the time to do this will be quite high for a large number of series. Given the very unfavourable combination of lots of series and only a few items per series, I am pleasantly surprised that the fast renderer does not lag further behind (clearing the BitSet several thousand times seems to be quite fast!).
The savings from the fast renderer are noteable even for a small item count (the series count of the dataset should of course not be high, as explained above). The benefit is small for a small item count (< 10 k), but the fast renderer scales much better and can do 100k or 1M data points with decent performance while an XYLineAndShapeRenderer becomes slower and slower. Your remark concerning TimeSeries that "the points from the same series are spread out" is probably not valid if we have indeed 1M items, provided that the items are lined up with reasonable order (a condition that should be fulfilled for most cases).
It is possible to construct a scenario where the optimizations of the fast renderer will be useless. E. g. if you plot a sine function with 1000 oscillations (i.e. ~ 1 oscillation per "pixel along the x axis") you will probably fill the entire data area with non-superimposed points. But if the data is really spread out in this way, the resulting chart will not be informative any more.
In order to introduce the skipping of points on a per-dataset basis, the following approach should do the job:
1) In the initialize-method of the renderer, check the SeriesRenderingOrder of the provided XYPlot parameter.
2) Go through the series of the dataset in an order that is reverse to that used by the XYPlot.
3) Determine the first and last visible item of each series, and go through the series from the last to the first visible item (presently, the renderer goes through all items of series and checks whether it is within the visible range, which seems to be less efficient).
4) Calculate the pixel that the data item will occupy, and mark the pixel as "occupied" in the renderedPixel-BitSet. In order to store the index of this data item, one could use a BitSet for each series. Mark the item as visible in the BitSet.
5) The renderedPixel BitSet can be thrown away after we have gone though this cycle, we just need to keep the BitSets that store the "visibility status" of the data items. In the drawItem method, one would then have to check, whether the given item of the given series is visible and then draw it. I will try to code that and see how that works.
your last point explains a lot.
Since the fast renderer skips data items on a per-series basis, there is no improvement for series with non-superimposed items. And since the renderedPixels BitSet is cleared for every series, the time to do this will be quite high for a large number of series. Given the very unfavourable combination of lots of series and only a few items per series, I am pleasantly surprised that the fast renderer does not lag further behind (clearing the BitSet several thousand times seems to be quite fast!).
The savings from the fast renderer are noteable even for a small item count (the series count of the dataset should of course not be high, as explained above). The benefit is small for a small item count (< 10 k), but the fast renderer scales much better and can do 100k or 1M data points with decent performance while an XYLineAndShapeRenderer becomes slower and slower. Your remark concerning TimeSeries that "the points from the same series are spread out" is probably not valid if we have indeed 1M items, provided that the items are lined up with reasonable order (a condition that should be fulfilled for most cases).
It is possible to construct a scenario where the optimizations of the fast renderer will be useless. E. g. if you plot a sine function with 1000 oscillations (i.e. ~ 1 oscillation per "pixel along the x axis") you will probably fill the entire data area with non-superimposed points. But if the data is really spread out in this way, the resulting chart will not be informative any more.
In order to introduce the skipping of points on a per-dataset basis, the following approach should do the job:
1) In the initialize-method of the renderer, check the SeriesRenderingOrder of the provided XYPlot parameter.
2) Go through the series of the dataset in an order that is reverse to that used by the XYPlot.
3) Determine the first and last visible item of each series, and go through the series from the last to the first visible item (presently, the renderer goes through all items of series and checks whether it is within the visible range, which seems to be less efficient).
4) Calculate the pixel that the data item will occupy, and mark the pixel as "occupied" in the renderedPixel-BitSet. In order to store the index of this data item, one could use a BitSet for each series. Mark the item as visible in the BitSet.
5) The renderedPixel BitSet can be thrown away after we have gone though this cycle, we just need to keep the BitSets that store the "visibility status" of the data items. In the drawItem method, one would then have to check, whether the given item of the given series is visible and then draw it. I will try to code that and see how that works.
Re: To Those Who Use JFreeChart for Dynamic Plotting/Large Sets
paradoxoff,
I probably should have qualified my statement about the points being spread out. I was (selfishly) referring to my own situation where the database limts the maximum number of points to 30000, and these are spread over a number of series, so in my experience I have never encountered a time series chart close to 1M points. I am curious though, if the points are so 'squashed up' that they overlap, why is there a need for lines to connect these points?
I have read your proposed algorithm a number of times. I think there is an issue with trying to omit point(s) from a series that are overlapped by point(s) from another series. The lines that are drawn for that particular series will look different if a point is omitted. I really cannot see a way around this restriction.
I probably should have qualified my statement about the points being spread out. I was (selfishly) referring to my own situation where the database limts the maximum number of points to 30000, and these are spread over a number of series, so in my experience I have never encountered a time series chart close to 1M points. I am curious though, if the points are so 'squashed up' that they overlap, why is there a need for lines to connect these points?
I have read your proposed algorithm a number of times. I think there is an issue with trying to omit point(s) from a series that are overlapped by point(s) from another series. The lines that are drawn for that particular series will look different if a point is omitted. I really cannot see a way around this restriction.
-
- Posts: 1634
- Joined: Sat Feb 17, 2007 1:51 pm
Re: To Those Who Use JFreeChart for Dynamic Plotting/Large Sets
Hi Grimlock,
the fast renderer aims to be a general purpose renderer that shows all details of a small number of data points (like an XYLineAndShapeRenderer) but that is also useful to render a large number of data points.
I agree that for a large number of data points, additional lines between severly overlapping and squeezed shapes can be omitted (they won´t be visible anyways, unless the shape is very small and the line stroke very thick). But if you zoom in on such a chart, the details will become more and more visible. Thus, a renderer that can handle both extremes is desired.
The algorithm that I have described (skip data items that will be covered by data items from another series) will not be used to draw the series line, but just for the shapes!
As stated a few posts further up, line charts and scatter charts that different criteria for data points that can be omitted which will make it difficult to place any logic for skipping points in the plot. IMHO such a logic is better placed in the renderer.
The approach to find points that do not contribute to the visual appearance is easy for a scatter chart: just drop the points that are outside the data area or that will be covered by other data items from the same series (already implemented) or a different series (to be implemented as an optional feature). For a line chart, things are more complicated, and additional situations need to be considered: lines between visible and invisible points (i.e. inside or outside the data area) may run off or run in the chart, and lines between two invisible items may pass through the chart. I agree that the latter case isn´t handled properly.
[edit] Just re-read my code.
If the predecessor of a given data point was valid (i.e. a non-NaN) the seriesPath is lined to the current point, regardless of whether the current point is visible or not. The current implementation should thus not produce any artifacts stemming from improper treatment of invisible points, but it could probably be changed to avoid unneccessary moveTo´s or lineTo´s of the seriesPath
If the data is reasonably ordered along the domain axis and is kind of regularly spaced (as for a time series), the mentioned case will probably not show up. If the data ordering is more and more chaotic, finding these items could probably pay off, but if the data is more and more chaotic, a line chart is less and less informative anyways (finally looking like a ball of wool). Anyways, a safer approach could be the following: skip lines between data points that are both located below or both above or both to the right or to both the left of the data area.
the fast renderer aims to be a general purpose renderer that shows all details of a small number of data points (like an XYLineAndShapeRenderer) but that is also useful to render a large number of data points.
I agree that for a large number of data points, additional lines between severly overlapping and squeezed shapes can be omitted (they won´t be visible anyways, unless the shape is very small and the line stroke very thick). But if you zoom in on such a chart, the details will become more and more visible. Thus, a renderer that can handle both extremes is desired.
The algorithm that I have described (skip data items that will be covered by data items from another series) will not be used to draw the series line, but just for the shapes!
As stated a few posts further up, line charts and scatter charts that different criteria for data points that can be omitted which will make it difficult to place any logic for skipping points in the plot. IMHO such a logic is better placed in the renderer.
The approach to find points that do not contribute to the visual appearance is easy for a scatter chart: just drop the points that are outside the data area or that will be covered by other data items from the same series (already implemented) or a different series (to be implemented as an optional feature). For a line chart, things are more complicated, and additional situations need to be considered: lines between visible and invisible points (i.e. inside or outside the data area) may run off or run in the chart, and lines between two invisible items may pass through the chart. I agree that the latter case isn´t handled properly.
[edit] Just re-read my code.

If the data is reasonably ordered along the domain axis and is kind of regularly spaced (as for a time series), the mentioned case will probably not show up. If the data ordering is more and more chaotic, finding these items could probably pay off, but if the data is more and more chaotic, a line chart is less and less informative anyways (finally looking like a ball of wool). Anyways, a safer approach could be the following: skip lines between data points that are both located below or both above or both to the right or to both the left of the data area.
Re: To Those Who Use JFreeChart for Dynamic Plotting/Large Sets
This may sound like a stupid question but I was wondering how do you incorporate these fast classes into the existing jfreechart package? Whats in the zip file are a bunch of java files. I'm using eclipse IDE. I'm thinking that I have to load the entire existing jfreechart package as a project in eclipse and then replace some of the java source files with the fast classes and then compile the whole thing to get the .class files, then paste those .class files for the fast classes back into the jfreechart origional jar file because thats what I'm including right now. If any of you who have used these fast classes, if you don't mind can you give me a brief explanation of how to use them in terms of where do I need to copy the files and compile the classes?
Thanks! Sorry for being a java noob.
Thanks! Sorry for being a java noob.
-
- Posts: 1634
- Joined: Sat Feb 17, 2007 1:51 pm
Re: To Those Who Use JFreeChart for Dynamic Plotting/Large Sets
I have uploaded a new version of the renderer (now called "SamplingXYLineAndShapeRenderer"). Now, it is possible to skip data items that would be covered by data items of other series.
The new renderer is as fast as the old one regarding shapes, but half as fast concerning rendering as lines (but it is still fast enough for my purposes).
The new renderer is as fast as the old one regarding shapes, but half as fast concerning rendering as lines (but it is still fast enough for my purposes).
Re: To Those Who Use JFreeChart for Dynamic Plotting/Large Sets
Hi Peter, I tried your new renderer. No hard numbers but by the feel of it is is definitely faster.paradoxoff wrote:I have uploaded a new version of the renderer (now called "SamplingXYLineAndShapeRenderer").
One problem though, it never renders the last item in the dataset. Not the shape nor the line to it.
I pinpointed the problem to three separate places where the items are looped.
I have to admit that I am not that familiar with using the SourceForge (I had trouble locating your code in the first place) so I think it is safest if I post my findings here... sorry about that.
1. State.findVisiblePointsInSeries now has
Code: Select all
for (int itemIndex = itemBounds[1][series] - 1; itemIndex >= itemBounds[0][series]; itemIndex--) {
Code: Select all
for (int itemIndex = itemBounds[1][series]; itemIndex >= itemBounds[0][series]; itemIndex--) {
3. drawSeriesLine
both have
Code: Select all
for (int itemIndex = state.getFirstItemIndex(); itemIndex < state.getLastItemIndex(); itemIndex++) {
Code: Select all
for (int itemIndex = state.getFirstItemIndex(); itemIndex <= state.getLastItemIndex(); itemIndex++) {
An additional bonus (side-effect?) is that now if I zoom into my plot the rendered line continues to the edge of the visible area instead of stopping at the last totally visible point.
I hope you agree on the modifications? And if you agree, maybe you could also patch your code at SourceForge...
-
- Posts: 1634
- Joined: Sat Feb 17, 2007 1:51 pm
Re: To Those Who Use JFreeChart for Dynamic Plotting/Large Sets
Hi mkivinie,
thanks a lot for testing the renderer and tracking down the reason for its misbehaviour!
I totally agree with your changes and have uploaded a corrected version. Obviously I have focused too much on the large dataset and did not check whether really all what should be rendered is renderer.
Thanks again!
Peter
thanks a lot for testing the renderer and tracking down the reason for its misbehaviour!
I totally agree with your changes and have uploaded a corrected version. Obviously I have focused too much on the large dataset and did not check whether really all what should be rendered is renderer.
Thanks again!
Peter
Re: To Those Who Use JFreeChart for Dynamic Plotting/Large Sets
I had some big performance problems with the "XYLineAndShapeRenderer" on my dynamic dataset so I just tried the "SamplingXYLineAndShapeRenderer", and what a difference! Before my application was very visible in the windows task manager, and with the new renderer it is working smoothly. Thanks alot for this new renderer. I give thumbs up for integrating this into the next release.
Re: To Those Who Use JFreeChart for Dynamic Plotting/Large Sets
I have discovered a possible bug in SamplingXYLineAndShapeRenderer. Sometimes I get an exception when calling the JFreeChart.draw(Graphics2D g2, Rectangle2D area, ChartRenderingInfo info) method:
I tracked this in my debugger, and in the findVisiblePointsInSeries method, this line produces a negative number, which causes the exception:
The variable values in my debugger are:
If this is not enough to, I will try to create a simple test-environment to reproduce this behavior. I will even try to fix it myself if you could give me some pointers. If you are able to help, I would appreciate it very much, since I cannot live without this renderer at the moment 
Code: Select all
java.lang.IndexOutOfBoundsException: bitIndex < 0: -4
at java.util.BitSet.get(BitSet.java:441)
at org.jfree.chart.renderer.xy.SamplingXYLineAndShapeRenderer$State.findVisiblePointsInSeries(SamplingXYLineAndShapeRenderer.java:292)
at org.jfree.chart.renderer.xy.SamplingXYLineAndShapeRenderer$State.startSeriesPass(SamplingXYLineAndShapeRenderer.java:371)
at org.jfree.chart.plot.XYPlot.render(XYPlot.java:3761)
at org.jfree.chart.plot.XYPlot.draw(XYPlot.java:3310)
at org.jfree.chart.JFreeChart.draw(JFreeChart.java:1235)
at org.jfree.chart.JFreeChart.draw(JFreeChart.java:1129)
Code: Select all
int itemPosition = transY * xPixels + transX;
Code: Select all
// Local variables
x = 376.6
y = 6.0
transX = -4
transY = 0
itemPosition = -4
// Fields
highDataX = 780.0
highDataY = 15999.8
java2DHeight = 293.6875
java2DWidth = 491.90625
lowDataX = 380.0
lowDataY = -0.2
rangeX = 400.0
rangeY = 16000.0
xPixels = 492
shapeSize = 1

Re: To Those Who Use JFreeChart for Dynamic Plotting/Large Sets
I naively changed the code from this:
to this:
I don't get the exception anymore and the graphic looks ok. Is tweak ok, or have I overlooked something?
Code: Select all
int itemPosition = transY * xPixels + transX;
if(!pixels.get(itemPosition)){
pixels.set(itemPosition);
markedPoints.set(itemIndex);
}
Code: Select all
int itemPosition = transY * xPixels + transX;
if (itemPosition >= 0) {
if (!pixels.get(itemPosition)) {
pixels.set(itemPosition);
markedPoints.set(itemIndex);
}
}
-
- Posts: 1634
- Joined: Sat Feb 17, 2007 1:51 pm
Re: To Those Who Use JFreeChart for Dynamic Plotting/Large Sets
Thanks for using the renderer!
You have discovered a bug that was probably introduced with the change mentioned above. The error occurs when the item index of an item outside the axis range is determined.
One "design goal" of the renderer was to reduce calculations to a minimum. I would thus suggest to make the necessary check whether an item is inside the axis range further up in the code, and change the line in the findVisiblePointsInSeries-method
to
You might save a few calculations, though these savings are probably not really noteable.

You have discovered a bug that was probably introduced with the change mentioned above. The error occurs when the item index of an item outside the axis range is determined.
One "design goal" of the renderer was to reduce calculations to a minimum. I would thus suggest to make the necessary check whether an item is inside the axis range further up in the code, and change the line in the findVisiblePointsInSeries-method
Code: Select all
if(!Double.isNaN(x)){ //already checked whether value is in range with RendererUtilities.findLiveItems
Code: Select all
if(!Double.isNaN(x) && x > lowDataX && x < highDataX ){ //already checked whether value is in range with RendererUtilities.findLiveItems