How could I add to a plot an OHLCSeriesCollection and a TimeSeriesCollection , in order to represent their values in the same chart ?
Both OHLCSeriesCollection and TimeSeriesCollection are based on XYDataset so you should be able to add them both to an XYPlot with something like the following:
JFreeChart chart = // create your XY chart here.
XYPlot plot = chart.getXYPlot();
OHLCSeriesCollection ohlsSeriesDataset = // create you ohlc dataset here.
TimeSeriesCollection timeSeriesDataset = // create you time dataset here.
AbstractXYItemRenderer olhsSeriesRenderer = // create your ohlc renderer here.
AbstractXYItemRenderer timeSeriesRenderer = // create your time renderer here.
plot.setDataset(0, ohlsSeriesDataset);
plot.setDataset(1, timeSeriesDataset);
plot.setRenderer(0, olhsSeriesRenderer);
plot.setRenderer(1, timeSeriesRenderer);
The type of renderer to use for olhsSeriesRenderer and timeSeriesRenderer really depends on the type of chart you want to generate so I cannot give you specifics here.
I have not tried this myself with XY datasets, but I have been able to do combine CategoryDatasets using this.
Related
I am creating JFreeChart as follows (see below). On the x axis I need to show around 1000 ticks. So, that's why I am putting JFreeChart into the JScrollPane. When I try to set the WIDTH of a chart panel to 2000, the plot is not sized proportionally. Is there any way to define the WIDTH of a plot (XYPlot).
XYDataset dataset = createData(data);
JFreeChart chart = createChart(dataset);
final ChartPanel chartPanel = new ChartPanel(chart);
chartPanel.setPreferredSize(new Dimension(2000, this.height));
JScrollPane scrl = new JScrollPane(chartPanel);
scrl.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scrl.setViewportView(chartPanel);
scrl.setPreferredSize(new Dimension(this.width, this.height));
this.add(scrl);
So far I found an answer that helped solving the problem. However, maybe there is a better solution:
// The first step is to avoid scaling up a small chart.
// The value of "MaximumDrawWidth" should be large, for instance 4000
chartPanel.setMaximumDrawWidth(4000);
// The second step is to set the width of a chart panel.
chartPanel.setPreferredSize(new Dimension(2000,this.height));
I am using JFreeChart library to create Chart on website (library integrated with my application according to this tutorial). Everything looks great except one thing: for some reason, for some data line chart is not completly visible (please see screen).
I don't know why is it happening. I'm posting code responsible for configuration:
public JFreeChart createChart()
{
NumberAxis numberaxis = new NumberAxis("X");
numberaxis.setAutoRangeIncludesZero(false);
NumberAxis numberaxis1 = new NumberAxis("Y");
numberaxis1.setAutoRangeIncludesZero(false);
XYSplineRenderer xysplinerenderer = new XYSplineRenderer();
XYPlot xyplot = new XYPlot(createSampleData(), numberaxis, numberaxis1, xysplinerenderer);
xyplot.setBackgroundPaint(new Color(238, 242, 250));//
xyplot.setDomainGridlinePaint(new Color(238, 242, 250));
xyplot.setRangeGridlinePaint(new Color(238, 242, 250));
xyplot.getRenderer().setSeriesPaint(0, Color.BLUE);
xyplot.setAxisOffset(new RectangleInsets(4D, 4D, 4D, 4D));
XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) xyplot.getRenderer();
renderer.setSeriesShapesVisible(0, true);//FIXME Dots
xyplot.getDomainAxis().setStandardTickUnits(NumberAxis.createIntegerTickUnits());
JFreeChart jfreechart = new JFreeChart("", JFreeChart.DEFAULT_TITLE_FONT, xyplot, true);
jfreechart.setBackgroundPaint(Color.white);
return jfreechart;
}
The link provided by Richard describes the problem well; but, ultimately, it looks like you need to manually set the upper bound of your range axis to account for the upper curve of the spline produced by XYSplineRenderer. For your example above, this might be:
xyplot.getRangeAxis().setUpperBound(22.5);
For practical purposes, you would probably want to calculate the maximum Y value, and either add a percentage to it, or more complicated, calculate a ceiling based on its surrounding points. I would start by adding 10% and see how that goes:
// Iterate data values; use Math.max() to determine maxYValue; then:
xyplot.getRangeAxis().setUpperBound( maxYValue + maxYValue * 0.1);
It's at patch, but it should provide the result you want, depending on the nature of your data and the curves produced connecting data points.
I'm trying to make a pretty simple chart which graphs measured forces over the period of a second. I have plain-jane example which is outputting the following graph:
Here's my code:
TimeSeries series1 = new TimeSeries("Force", "Domain", "Range");
//generate values
for (int i = 0; i < 1000; i++) {
series1.add(new TimeSeriesDataItem(new Millisecond(i, 0, 0, 0, 1, 1, 2012), i));
}
TimeSeriesCollection dataset = new TimeSeriesCollection();
dataset.addSeries(series1);
JFreeChart chart = ChartFactory.createXYLineChart("Measured Forces",
"Time", "Force in Pounds", dataset, PlotOrientation.VERTICAL,
false, false, false);
ChartUtilities.saveChartAsPNG(new File("/home/rfkrocktk/Desktop/chart.png"), chart, 1280, 720);
How can I transform those ugly 1,325,404,800,000 values into simple 0-1,000 values representing the overall time measured instead of the exact system time?
I've been looking for constructors that match my requirements, but I can't seem to find them.
ChartFactory.createXYLineChart() creates two instances of NumberAxis, one for each of the domain and range. As an alternative, consider ChartFactory.createTimeSeriesChart(), which uses a DateAxis for the domain. In either case, you can use setXxxFormatOverride() on the axis to get any desired format. The example shown here specifies a factory DateFormat.
As far as I know, TimeSeries does not support the concept of 'relative time' - all of the x value types (like Millisecond) are based on java.util.Date, which yields an absolute time.
I think you might be better off using XYSeries instead of TimeSeries. Then the x values can be integers.
The trick is to use RelativeDateFormat for the domain axis formatting with ChartFactory.createTimeSeriesChart(). This prints labels in the format of #h#m#.###s. For example, you might see "0h0m2.529s".
JFreeChart chart;
XYPlot plot;
DateAxis axis;
TimeSeriesCollection dataset;
TimeSeries series;
RelativeDateFormat format;
long startTime;
series = new TimeSeries("Time");
dataset = new TimeSeriesCollection(series);
chart = ChartFactory.createTimeSeriesChart("Relative", "Elapsed Time", "Value", dataset, true, true, true);
plot = chart.getXYPlot();
axis = (DateAxis) plot.getDomainAxis();
format = new RelativeDateFormat();
startTime = System.currentTimeMillis();
axis.setDateFormatOverride(format);
format.setBaseMillis(startTime);
I have created XY line chart using JFreeChart, having two datasets, I want both the lines to be in different colors. I tried using following code-
XYPlot plot = chart.getXYPlot();
XYItemRenderer xyir = plot.getRenderer();
xyir.setSeriesPaint(0, Color.GREEN);
plot.setDataset(0, xyDataset1);
xyir.setSeriesPaint(1, Color.blue);
plot.setDataset(1, xyDataset2);
Also I have tried using following code, where I am using different renderer (don't know whether this is correct way to do it)-
XYPlot plot1 = chart.getXYPlot();
XYPlot plot2 = chart.getXYPlot();
XYItemRenderer xyir1 = plot1.getRenderer();
xyir1.setSeriesPaint(0, Color.GREEN);
plot1.setDataset(0, xyDataset1);
XYItemRenderer xyir2 = plot2.getRenderer();
xyir2.setSeriesPaint(1, Color.blue);
plot2.setDataset(1, xyDataset2);
In both the cases its printing both the lines in blue color.
What's wrong?? Any suggestions??
Found the solution, it works for me, using two different Renderer, earlier i was not doing it properly--
XYPlot plot = chart.getXYPlot();
plot.setDataset(0, xyDataset1);
plot.setDataset(1, xyDataset2);
XYLineAndShapeRenderer renderer0 = new XYLineAndShapeRenderer();
XYLineAndShapeRenderer renderer1 = new XYLineAndShapeRenderer();
plot.setRenderer(0, renderer0);
plot.setRenderer(1, renderer1);
plot.getRendererForDataset(plot.getDataset(0)).setSeriesPaint(0, Color.red);
plot.getRendererForDataset(plot.getDataset(1)).setSeriesPaint(0, Color.blue);
The approach shown works in this example, and a single renderer should be sufficient. An sscce may help isolate the problem.
To control individual items, you can override getItemPaint(), shown here.
Try to set the Series paint to null in the renderer setSeriesPaint(null);
If you take a look at the source it first checks to see if the paint is !null, then uses the base color.
If null it uses the colors associated with the time serie from a lookup table.
Is it possible to draw a 3D chart using JfreeChart like in the following link.If possible can anyone give some hints and some snippets of code on what parameters of Plot can be used to do this.
link text
It's possible though it won't look exactly the same. The easiest way is to create a dataset (descendant of org.jfree.data.general.PieDataset) and use one of org.jfree.chart.ChartFactory methods:
PieDataset data = new DefaultPieDataset();
data.setValue("Section1", 30);
data.setValue("Section2", 60);
data.setValue("Section3", 120);
JFreeChart pieChart = ChartFactory.createPieChart3D(
"My Pie Chart", // title
data, // data set
true, // draw a legend
true, // show tooltips over sections
false); // do not generate image map with URLs
You can then further customize your chart through pieChart methods. For example, here's how to explode one pie section:
PiePlot plot = (PiePlot) pieChart.getPlot();
plot.setExplodePercent("Section2", 0.25);