I am obviously not understanding the documentation for the getSeriesPaint method. I have the TimeSeries object and I want to get the color being used to render it. However, it seems like I am in a catch-22. I need to know the series index (getIndex), but to find that I need to know the series time period. However, to find the series time period, I need to know the index. I'm looking to do something like this:
Color color=(Color) r1.getSeriesPaint(arg0);
where r1 is the XYLineAndShapeRenderer. What do I use for arg0 given the TimeSeries object?
Because XYLineAndShapeRenderer is an XYItemRenderer, it invokes the AbstractRenderer method getItemPaint(), which "Returns the paint used to color data items as they are drawn." Note that "The default implementation passes control to the lookupSeriesPaint() method." Starting from this example, the following fragment obtains the dataset and renderer from the chart. It then enumerates the series paints—shades of red and blue seen in the image:
JFreeChart chart = chartPanel.getChart();
XYPlot plot = (XYPlot) chart.getPlot();
TimeSeriesCollection tsc = (TimeSeriesCollection) plot.getDataset();
XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) plot.getRenderer();
for (int i = 0; i < tsc.getSeriesCount(); i++) {
System.out.println(renderer.lookupSeriesPaint(i));
}
Console:
java.awt.Color[r=255,g=85,b=85]
java.awt.Color[r=85,g=85,b=255]
Alternatively, consider a custom DrawingSupplier, mentioned here.
Related
I am doing a lineal graph in java with JFreeChart, i was checking in internet and this is that i have at the moment:
DefaultKeyedValues data = new DefaultKeyedValues();
data.addValue("01/04/2012",7);
data.addValue("01/05/2012",5);
data.addValue("01/06/2012",6);
data.addValue("01/07/2012",2);
CategoryDataset dataset = DatasetUtilities.createCategoryDataset("Population", data);
JFreeChart chart = ChartFactory.createBarChart("Population","Date","Population",dataset,PlotOrientation.VERTICAL,true,true,false);
LineAndShapeRenderer renderer = new LineAndShapeRenderer();
renderer.setBaseLinesVisible(true);
CategoryPlot plot = (CategoryPlot) chart.getPlot();
plot.setRenderer(0, renderer);
NumberAxis numberAxis = (NumberAxis)plot.getRangeAxis();
numberAxis.setRange(new Range(0,10));
CategoryAxis axis = plot.getDomainAxis();
axis.setCategoryLabelPositions(CategoryLabelPositions.UP_45);
The problem comes when I try to insert more categories in the linear graph, I don't know how to do it. I need to do 3 categories more.
actual graph
I need use DefaultKeyedValues or some series collection that let me use String param with double/int param. I want to make a generalized method that passes different formats of dates, and the method always draw a graph. In the photo of the example I am passing a date range 'dd-MM-yyyy' but later I will pass a format 'MM-yyyy'.
Edit: Okey i find this example in internet that solves my problem.
enter link description here
I am using JasperReports to create a line chart for my webapps.
I have successfully passed the dataset to the compiled report (created in iReport) and can see the data correctly.
However, I want to do some customization on the margin.
The value shown on the line chart is trimming for the highest value as there is no margin.
The X-Axis label is coming after few empty space from Y-Axis 0 value. I want to remove that margin and start the X-Axis from very close to the meeting point of X & Y.
Please see the picture:
I am using customized class which is defined in my webspps. I am able to change the font size and rotation of the label but don't know how to adjust margin.
public class LineChartCustomizer implements JRChartCustomizer {
#Override
public void customize(JFreeChart jFreeChart, JRChart jrChart) {
CategoryPlot plot = jFreeChart.getCategoryPlot();
DecimalFormat dfKey = new DecimalFormat("###,###");
StandardCategoryItemLabelGenerator labelGenerator = new StandardCategoryItemLabelGenerator("{2}", dfKey);
LineAndShapeRenderer renderer = new LineAndShapeRenderer();
renderer.setBaseItemLabelsVisible(true);
renderer.setBaseItemLabelGenerator(labelGenerator);
renderer.setBaseItemLabelFont(new java.awt.Font("SansSerif", java.awt.Font.PLAIN, 4));
renderer.setSeriesShape(0, ShapeUtilities.createDiamond(1F));
plot.setRenderer(renderer);
}
}
I think* you're looking for ValueAxis#setUpperMargin(double) and CategoryAxis#setLowerMargin(double). You can get the CategoryAxis and ValueAxis from plot.getDomainAxis() and plot.getRangeAxis(). Note that the margins are a percentage of the axis length and not pixel values.
* I'm not familiar with JasperReports, but it seems a little strange that you have a CategoryPlot in hand as opposed to an XYPlot. I would have expected the chart in your picture to have used an xy time series. I have only ever tested this with an XYPlot, so I'm not entirely sure how it will behave with a CategoryPlot.
I have been trying for the last week to find a way to make JFreeChart display something similar to the image below. Basically you are looking at three series (upper, middle, lower) with a fill inbetween. And underneath there is a (light green) fill color, or an area chart as some would perhaps call it - no meaning, just for looks.
The only thing really missing from what I have come up with is the last part: the fill underneath / area chart:
I even tried to subclass XYDifferenceRenderer and combine it with the renderer for Areachart, but I could not control the height of the areachart, basically filling up the plot to the top. So that was a no-go. Having created as simple rendererer to create rounded bar charts earlier, I thought that I might be able to change the code for XYDifferenceRenderer. But the code for XYDifferenceRenderer is quite a handful of geometry and inner workings of JFree chart, and the task was a bit overwhelming. So any tips on how to achieve this effect in any "normal" way (that does not involve hacking JFreeChart's inner workings)?
Found an old post describing how to use two renderers in the same plot, which was just the thing in this case.
To get a fill underneath you need to
create two new series
one is the lower bound of the difference plot
the other is the values at the bottom of the plot - often just zero. Easily got by calling plot.getRangeAxis().getLowerBound()
add them to a new dataset and add this to the plot
I was unaware that a plot could have several datasets. Turns out one can just use an index to access them.
create a new renderer for the "fill" dataset
create a new renderer
set the right fill paint
set the rendererer for the new dataset to be the new renderer
The code is something akin to the following, where the fill Paint obviously is up to you:
static void addFill(Plot plot) {
XYSeries lowerLimitSeries = ((XYSeriesCollection) (plot.getDataset())).getSeries(1);
XYSeriesCollection fillSet = new XYSeriesCollection();
double lowerBound = plot.getRangeAxis().getLowerBound();
fillSet.addSeries(lowerLimitSeries);
fillSet.addSeries(createLowerFillSeries(lowerLimitSeries, lowerBound));
plot.setDataset(1, fillSet);
Paint fillPaint = Color.GREEN;
XYDifferenceRenderer fillRenderer = new XYDifferenceRenderer(fillPaint, fillPaint, false);
fillRenderer.setSeriesStroke(0, new BasicStroke(0)); //do not show
fillRenderer.setSeriesStroke(1, new BasicStroke(0)); //do not show
plot.setRenderer(1, fillRenderer);
...
}
static XYSeries createLowerFillSeries(XYSeries lowerLimitSeries, double lowerLimit) {
int size = lowerLimitSeries.getItems().size();
XYSeries res = new XYSeries("lowerFillSeries");
for (int i = 0; i < size; i++) res.add(new XYDataItem(lowerLimitSeries.getX(i), lowerLimit));
return res;
}
I'm drawing within a servlet a ScatterPlot and serve it to the browser.
The user can now click somewhere on the plot and I want to determine what
datapoint of the scatter plot the user has pointed. From the mouse click of the
user I can determine on which pixel of the image he has clicked, but how can
I get from this info to the coordinates on the domain and range axis?
I found tipps how to do it, which uses the ChartPanel. But for serving it directly
to the browser I only use an instance of a JFreeChar object.
Anybody has a clue or an example how to do it?
Thanks,
Dieter
I think I have found a solution. For the solution I need to get my chart again,
so I either have to create it a new or to save it somehow. But when I have a reference
to that chart the solution is as following:
JFreeChart chart = functionWhichRetrievesTheChart();
ChartRenderingInfo info = new ChartRenderingInfo();
// PLOT_SIZE is the size if the graph and has to be the same size as the original drawn chart.createBufferedImage(PLOT_SIZE, PLOT_SIZE, info);
graph, otherwise the pixel position points to somewhere else
PlotRenderingInfo plotInfo = info.getPlotInfo();
XYPlot plot = (XYPlot)chart.getPlot();
Point p = new Point(x,y); // x and y are the pixel positions
// this is the domain value which belongs to the pixel position x
double domain = plot.getDomainAxis().java2DToValue(p.getX(), plotInfo.getDataArea(), plot.getDomainAxisEdge());
// this is the range value which belongs to the pixel position y
double range = plot.getRangeAxis().java2DToValue(p.getY(), plotInfo.getDataArea(), plot.getRangeAxisEdge());
I want to display some dates in the X axis of a chart, and here it is said that i have to use a TimeSeriesCollections object
It seems that i have to add a TimeSeries to the TimeSeriesCollections, and that the TimeSeries has to be constructed using a RegularTimePeriod...
I am a bit confused...
Can you please explain me what i have to do?
If possible can you provide some example code?
Thanks
TimeSeriesCollections are made up of TimeSeries objects
Use this method to add series to the dataset: addSeries(TimeSeries series)
When creating TimeSeries objects. Fill them with the time and values. Here is a rough example:
TimeSeries ts= new TimeSeries("Name of Series");
ts.addOrUpdate(new Year(2008), 42);
ts.addOrUpdate(new Year(2009), 51);
ts.addOrUpdate(new Year(2010), 97);
ts.addOrUpdate(new Year(2011), 45);
For getting the Axis to display the dates nicely, you will have to do something like this:
XYPlot plot = chart.getXYPlot();
DateAxis axis = new DateAxis();
plot.setDomainAxis(axis);
axis.setDateFormatOverride(new SimpleDateFormat("yyyy"));