I'd like to ask if it is possible to have a time series chart with dual x-axis (or y-axis but because it is a time series dataset I focus on dual x-axis). I have two data files in which the measurements were made during a minute or a whole day. As a result I can't have one x-axis. So, one solution is to transmorm one data file to the format of the other or to have two different x-axis. The second solution is it possible to be done?
I found JFreeChartDualAxisDemo
but it isn't what I want.
Thanks in advance for any help!!!
EDIT:
I have the following code and I'm trying to create a Time Series Chart with two datasets which belong to a specific x-axes (As you can see I created two x-axes). I tried to execute this code but the chart that creates isn't right and in fact it has only the x-axes and y-axis. Can someone tell me where is the fault?
int year1 = 2004;
int year2 = 2005;
int year3 = 2006;
int year4 = 2007;
int month1 = 1;
int month2 = 5;
int month3 = 8;
int month4 = 12;
int day1 = 3;
int day2 = 10;
int day3 = 15;
int day4 = 30;
TimeSeries ts= new TimeSeries("Metrisi", Day.class);
ts.add(new Day(day1, month1, year1), 100);
ts.add(new Day(day2, month2, year2), 150);
ts.add(new Day(day3, month3, year3), 250);
ts.add(new Day(day4, month4, year4), 275);
TimeSeriesCollection dataset = new TimeSeriesCollection();
dataset.addSeries(ts);
int year1_2 = 2004;
int year2_2 = 2005;
int year3_2 = 2006;
int year4_2 = 2007;
int month1_2 = 2;
int month2_2 = 7;
int month3_2 = 9;
int month4_2 = 11;
int day1_2 = 23;
int day2_2 = 14;
int day3_2 = 19;
int day4_2 = 22;
TimeSeries ts2= new TimeSeries("Metrisi", Day.class);
ts.add(new Day(day1_2, month1_2, year1_2), 100);
ts.add(new Day(day2_2, month2_2, year2_2), 150);
ts.add(new Day(day3_2, month3_2, year3_2), 250);
ts.add(new Day(day4_2, month4_2, year4_2), 275);
TimeSeriesCollection dataset2 = new TimeSeriesCollection();
dataset.addSeries(ts2);
JFreeChart chart = ChartFactory.createTimeSeriesChart(
"Measurement",
"Date",
"Measurement",
dataset,
true,
true,
false);
final XYPlot plot = chart.getXYPlot();
plot.setBackgroundPaint(Color.lightGray);
plot.setDomainGridlinePaint(Color.white);
plot.setRangeGridlinePaint(Color.white);
plot.setDomainCrosshairVisible(true);
plot.setRangeCrosshairVisible(false);
final DateAxis axis2 = new DateAxis("Secondary");
//xAxis2.setAutoRangeIncludesZero(false);
//plot.setDomainAxis(1, axis );
plot.setRangeAxis(1, axis2);
plot.setDataset(1, dataset2);
plot.mapDatasetToRangeAxis(1, 1);
final XYItemRenderer renderer = plot.getRenderer();
renderer.setToolTipGenerator(StandardXYToolTipGenerator.getTimeSeriesInstance());
if (renderer instanceof StandardXYItemRenderer) {
final StandardXYItemRenderer rr = (StandardXYItemRenderer) renderer;
//rr.setPlotShapes(true);
rr.setShapesFilled(true);
//renderer.setSeriesStroke(0, new BasicStroke(2.0f));
//renderer.setSeriesStroke(1, new BasicStroke(2.0f));
}
final StandardXYItemRenderer renderer2 = new StandardXYItemRenderer();
renderer2.setSeriesPaint(0, Color.black);
//renderer2.setPlotShapes(true);
renderer.setToolTipGenerator(StandardXYToolTipGenerator.getTimeSeriesInstance());
plot.setRenderer(1, renderer2);
final DateAxis axis = (DateAxis) plot.getDomainAxis();
This is what I'am trying to do. As you can see I have two x-axes but only one dataset and that it's the problem. I have done the example that is shown in the image with the following code:
final XYPlot plot = chart.getXYPlot();
plot.setBackgroundPaint(Color.lightGray);
plot.setDomainGridlinePaint(Color.white);
plot.setRangeGridlinePaint(Color.white);
plot.setDomainCrosshairVisible(true);
plot.setRangeCrosshairVisible(false);
final XYItemRenderer renderer = plot.getRenderer();
if (renderer instanceof StandardXYItemRenderer) {
final StandardXYItemRenderer rr = (StandardXYItemRenderer) renderer;
//rr.setPlotShapes(true);
rr.setShapesFilled(true);
renderer.setSeriesStroke(0, new BasicStroke(2.0f));
renderer.setSeriesStroke(1, new BasicStroke(2.0f));
}
final DateAxis axis = (DateAxis) plot.getDomainAxis();
final DateAxis xAxis2 = (DateAxis) plot.getDomainAxis();
plot.setDomainAxis(1, xAxis2 );
plot.mapDatasetToDomainAxis(1, 1);
Yes you can add a secondary X (Domain) axis. To add a secondary Domain axis to the demo you linked to add the following code:
final NumberAxis xAxis2 = new NumberAxis("Secondary X Axis");
plot.setDomainAxis(1, xAxis2 );
plot.mapDatasetToDomainAxis(1, 1);
to the constructor after you have a referance to the Plot (plot)
This will allow you to show both datasets thus:
With the code I posted before what I get is something like this
Related
I'm having a Problem constructing a combined Candlestick Chart and Line Chart (both on the same plot). For the Candlesticks I use OHLCDataset and for the "moving average" linechart I use TimeSeries. However the Linecharts get drawn at the wrong timepoint along the axis. I have printed all DateTime Elements to make shure I did not set the wrong time or date but when printed they show exactly the date times they are supposed to. In the Chart however they start 6 hours too early. I first thought this would be a Timezone Issue but I'm setting the timezone on both to EST.
Here are the code snippets that create the dataset and assign it to the XYPlot
The OHLCDataset retrieving method (time[i] is a Date Object):
public OHLCDataset getOHLCDataset(){
OHLCSeries ohlcSeries = new OHLCSeries("Candlesticks");
for(int i=0; i<close.length; i++){
ohlcSeries.add(RegularTimePeriod.createInstance(Minute.class, time[i], TimeZone.getTimeZone("EST")), open[i], max[i], min[i], close[i]);
}
OHLCSeriesCollection ohlcCollection = new OHLCSeriesCollection();
ohlcCollection.addSeries(ohlcSeries);
return ohlcCollection;
}
The TimeSeries retrieving method (time[i] is a Date Object - the same as above):
public XYDataset getAverageXYDataset(int periods, int frame){
TimeSeries x = new TimeSeries("moving average " + periods + " periods");
if(frame>60){
for(int i=periods-1; i<close.length; i++){
double sum = 0;
for(int j=i; j>i-periods; j--){
sum += close[j];
}
x.add(RegularTimePeriod.createInstance(Hour.class, time[i], TimeZone.getTimeZone("EST")), sum/periods);
}
}else{
for(int i=periods-1; i<close.length; i++){
double sum = 0;
for(int j=i; j>i-periods; j--){
sum += close[j];
}
x.add(RegularTimePeriod.createInstance(Minute.class, time[i], TimeZone.getTimeZone("EST")), sum/periods);
}
}
return new TimeSeriesCollection(x);
}
The code that adds the datasets to the plot:
OHLCDataset dataset1 = dataset.getOHLCDataset();
XYDataset smallAverageDataset = dataset.getAverageXYDataset(20, period);
XYDataset bigAverageDataset = dataset.getAverageXYDataset(50, period);
// create the jfreechart - add candlestickdataset first
String title2 = dataset.getTime()[0] + " - " + dataset.getTime()[dataset.getTime().length-1];
JFreeChart chart = createChart(dataset1, title2);
// get the xyplot and set other datasets
chart.getXYPlot().setDataset(1, smallAverageDataset);
chart.getXYPlot().setDataset(2, bigAverageDataset);
Here is the method createChart:
private static JFreeChart createChart(final OHLCDataset dataset, String title) {
DateAxis xAxis = createXAxis();
NumberAxis yAxis = createYAxis();
MyCandlestickRenderer candlestickRenderer = createCandlestickRenderer();
plot = new XYPlot(dataset, xAxis, yAxis, candlestickRenderer);
JFreeChart chart = new JFreeChart(
title,
new Font("SansSerif", Font.BOLD, 24),
plot,
false
);
return chart;
}
And here is the createXAxis method:
private static DateAxis createXAxis(){
DateAxis domainAxis = new DateAxis();
domainAxis.setAutoRange(true);
domainAxis.setTickLabelsVisible(true);
domainAxis.setAutoTickUnitSelection(true);
return domainAxis;
}
I cannot figure out why there is such an offset on the linecharts but as you see I set the same Timezones for all Datasets.
Thanks in advance for the Help.
In JFreeChart's TimeSeries class, the x-values are time periods rather than specific points in time. The TimeSeriesCollection class presents this data via the XYDataset interface and has to choose a specific x-value for each data item. The setXPosition method (in TimeSeriesCollection) sets a flag that determines which point in the time period is used (start, middle or end).
I am using Visual Studio 2010 along with Syncfusion Essential Studio 10.2.0.56.
I want to change the shape of open close symbols from horizontal lines to circle in hi low open close charttype in essential chart of syncfusion.
Can someone help me in achieving this????
I want to finally get this type of chart
Thanks
You can achieve this requirement by combination of Hilo and Scatter type chart. Please set the desired symbol in Hilo and scatter chart type for your requirements. Please refer the below code snippet to achieve this,
[C#]
// chart series for Hilo.
ChartSeries series1 = new ChartSeries("Series 1", ChartSeriesType.HiLo);
series1.Points.Add(1, new double[] { 8, 3 });
series1.Points.Add(2, new double[] { 10, 2 });
series1.Points.Add(3, new double[] { 16, 2 });
series1.Points.Add(4, new double[] { 7, 3 });
series1.Points.Add(5, new double[] { 12, 3 });
this.chartControl1.Series.Add(series1);
// symbol for Hilo chart type
series1.Style.Symbol.Shape = ChartSymbolShape.HorizLine;
series1.Style.Symbol.Color = Color.CadetBlue;
series1.Style.Interior = new BrushInfo(Color.Black);
// chart series for scatter.
ChartSeries series2 = new ChartSeries("Series 2", ChartSeriesType.Scatter);
for (int i = 0; i < 5; i++)
series2.Points.Add(i+1, (series1.Points[i].YValues[0] + series1.Points[i].YValues[1]) / 2);
this.chartControl1.Series.Add(series2);
// symbol for scatter chart type
series2.Style.Interior = new BrushInfo(Color.LightGreen);
series2.ZOrder = 0;
// chart series for scatter.
ChartSeries series3 = new ChartSeries("Series 3", ChartSeriesType.Scatter);
for (int i = 0; i < 5; i++)
series3.Points.Add(i + 1, (series1.Points[i].YValues[1]));
this.chartControl1.Series.Add(series3);
// symbol for scatter chart type
series3.Style.Symbol.Shape = ChartSymbolShape.HorizLine;
series3.Style.Symbol.Color = Color.Red;
Regards,
M. Balaji
I am trying to make a chart of ohlc bars invisible so that I can leave the window with only the moving average.
Here is the code with the two series (ohlc bars and moving average) :
private static JFreeChart createChart(OHLCDataset dataset)
{
JFreeChart chart = ChartFactory.createHighLowChart(
"HighLowChartDemo2",
"Time",
"Value",
dataset,
true);
XYPlot plot = (XYPlot)chart.getPlot();
DateAxis axis = (DateAxis)plot.getDomainAxis();
axis.setTickMarkPosition(DateTickMarkPosition.MIDDLE);
NumberAxis yAxis = (NumberAxis)plot.getRangeAxis();
yAxis.setNumberFormatOverride(new DecimalFormat("$0.00"));
//overlay the moving average dataset...
XYDataset dataset2 = MovingAverage.createMovingAverage(dataset, "-MAVG", 3 * 24 * 60 * 60 * 1000L, 0L);
plot.setDataset(1, dataset2);
plot.setRenderer(1, new StandardXYItemRenderer());
XYItemRenderer theRenderer = plot.getRenderer(0);
theRenderer.setSeriesVisible(0, false);
return chart;
}
For some reason setSeriesVisible function is not working.
Any ideas?
Thank you.
HighLowRenderer ignores getSeriesVisible() and getBaseSeriesVisible(), although it does check getDrawOpenTicks() and getDrawCloseTicks(). You can replace the OHLCDataset:
plot.setDataset(0, null);
Alternatively, don't add the OHLCDataset in the first place; just use it to create the MovingAverage.
I have been trying to get current Mouse Co-ordinates in a JfreeChart and found that the following solution was working partially
JFreeChart get mouse coordinates
I have been using OHLC Dataset to draw the chart and while I could get the RangeAxis properly (meaning in the subplot values), I couldn't make anything out of the value recieved for the X-Axis from the above example.
I am sure that I am receiving the values in some other format (not the displayed date format), anyone could point out what I am doing wrong?
Got it solved after few hours of experiment. Here is the code for a complete MouseMotionListener. Just added this to the chartPanel and voila! - it works!
The chartY returns proper value of Y-Axis and the dateString returns complete date. Tried it in an OHLC Chart and seems proper.
MouseMotionListener mouselisten = new MouseMotionListener() {
public void mouseDragged(MouseEvent e) {
//
}
public void mouseMoved(MouseEvent e) {
Point2D p = e.getPoint();
Rectangle2D plotArea = chartPanel.getScreenDataArea();
XYPlot plot = (XYPlot) chart.getPlot(); // your plot
double chartX = plot.getDomainAxis().java2DToValue(p.getX(), plotArea, plot.getDomainAxisEdge());
double chartY = plot.getRangeAxis().java2DToValue(p.getY(), plotArea, plot.getRangeAxisEdge());
DecimalFormat dfT = new DecimalFormat("00");
GregorianCalendar gc = new GregorianCalendar();
long lDte = (long)chartX;
Date dtXX = new Date(lDte);
gc.setTime(dtXX);
String sDD = dfT.format(Double.valueOf(String.valueOf(gc.get(GregorianCalendar.DAY_OF_MONTH))));
String sMM = dfT.format(Double.valueOf(String.valueOf(gc.get(GregorianCalendar.MONTH)+1)));
String sYY = dfT.format(Double.valueOf(String.valueOf(gc.get(GregorianCalendar.YEAR))));
String dateString = sDD +"/"+ sMM +"/"+ sYY;
}
};
I have drawn a jfreechart using DefaultCategoryDataset. The problem is even I have added around 150 values (as columns and rows) it only shows only the last 11 x values in the graph. Is there a way to make the graph to show all the x values in the range?
Thanks a lot.
My createDataset() method is as below.
public CategoryDataset createDataset() {
final String series1 = "Type1";
final DefaultCategoryDataset dataset = new DefaultCategoryDataset();
String pattern = "\\s";
Pattern splitter = Pattern.compile(pattern);
String[] myResult = splitter.split(resultText);
for (String str : myResult) {
String head = str.substring(0, str.indexOf('('));
for(int j = 0; j < str.length(); j++) {
dataset.addValue(parse(str), series1, head);
}
}
return dataset;
}
And I have created the JFreechart as LineChart.
Thanks a lot.
Without your code it's hard to spot the problem. You might compare your createDataset() method to this BarChartDemo. A new category and values may be added, as shown.
String category6 = "Category 6";
...
dataset.addValue(1.0, series1, category6);
dataset.addValue(2.0, series2, category6);
dataset.addValue(3.0, series3, category6);
Addendum:
I need to add a scrollbar to the x axis as well.
I've never had to do this but I see there is a horizontal scrolling example named SlidingCategoryDatasetDemo2.