I'm currently making an Excel chart using org.apache.poi and oooxml library. I developed the picture below.
enter image description here
enter image description here
XSSFDrawing drawing = (XSSFDrawing)sheet.createDrawingPatriarch();
ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 35, 20, 57);
XSSFChart chart = drawing.createChart(anchor);
CTChart ctChart = ((XSSFChart)chart).getCTChart();
CTPlotArea ctPlotArea = ctChart.getPlotArea();
//여기까지는 똑같음
//the first bar chart
CTBarChart ctBarChart = ctPlotArea.addNewBarChart();
CTBoolean ctBoolean = ctBarChart.addNewVaryColors();
ctBoolean.setVal(true);
ctBarChart.addNewBarDir().setVal(STBarDir.COL);
//the first chart series
CTBarSer ctBarSer = ctBarChart.addNewSer();
CTSerTx ctSerTx = ctBarSer.addNewTx();
CTStrRef ctStrRef = ctSerTx.addNewStrRef();
ctStrRef.setF("Sheet1!$B$10");
ctBarSer.addNewIdx().setVal(0);
CTAxDataSource ctAxDataSource = ctBarSer.addNewCat();
ctStrRef = ctAxDataSource.addNewStrRef();
ctStrRef.setF("Sheet1!$A$11:$A$34");
CTNumDataSource ctNumDataSource = ctBarSer.addNewVal();
CTNumRef ctNumRef = ctNumDataSource.addNewNumRef();
ctNumRef.setF("Sheet1!$B$11:$B$34");
//the second chart series
CTBarSer ctBarSer1 = ctBarChart.addNewSer();
CTSerTx ctSerTx1 = ctBarSer1.addNewTx();
CTStrRef ctStrRef1 = ctSerTx1.addNewStrRef();
ctStrRef1.setF("Sheet1!$C$10");
ctBarSer1.addNewIdx().setVal(1);
CTAxDataSource ctAxDataSource1 = ctBarSer1.addNewCat();
ctStrRef1 = ctAxDataSource1.addNewStrRef();
ctStrRef1.setF("Sheet1!$A$11:$A$34");
CTNumDataSource ctNumDataSource1 = ctBarSer1.addNewVal();
CTNumRef ctNumRef1 = ctNumDataSource1.addNewNumRef();
ctNumRef1.setF("Sheet1!$C$11:$C$34");
// 3번째
CTBarSer ctBarSer2 = ctBarChart.addNewSer();
CTSerTx ctSerTx2 = ctBarSer2.addNewTx();
CTStrRef ctStrRef2 = ctSerTx2.addNewStrRef();
ctStrRef2.setF("Sheet1!$D$10");
ctBarSer2.addNewIdx().setVal(2);
CTAxDataSource ctAxDataSource2 = ctBarSer2.addNewCat();
ctStrRef2 = ctAxDataSource2.addNewStrRef();
ctStrRef2.setF("Sheet1!$A$11:$A$34");
CTNumDataSource ctNumDataSource2 = ctBarSer2.addNewVal();
CTNumRef ctNumRef2 = ctNumDataSource2.addNewNumRef();
ctNumRef2.setF("Sheet1!$D$11:$D$34");
//at least the border lines in Libreoffice Calc ;-)
ctBarSer.addNewSpPr().addNewLn().addNewSolidFill().addNewSrgbClr().setVal(new byte[] {0,0,0});
ctBarSer1.addNewSpPr().addNewLn().addNewSolidFill().addNewSrgbClr().setVal(new byte[] {0,0,0});
ctBarSer2.addNewSpPr().addNewLn().addNewSolidFill().addNewSrgbClr().setVal(new byte[] {0,0,0});
ctBarChart.addNewAxId().setVal(123456); //cat axis 1 (lines)
ctBarChart.addNewAxId().setVal(123457); //val axis 1 (left)
ctBarChart.addNewAxId().setVal(123458); //val axis 1 (right)
ctBarChart.addNewAxId().setVal(123459); //val axis 1 (right)
//cat axis 1
CTCatAx ctCatAx = ctPlotArea.addNewCatAx();
ctCatAx.addNewAxId().setVal(123456); //id of the cat axis
CTScaling ctScaling = ctCatAx.addNewScaling();
ctScaling.addNewOrientation().setVal(STOrientation.MIN_MAX);
ctCatAx.addNewDelete().setVal(false);
ctCatAx.addNewAxPos().setVal(STAxPos.B);
ctCatAx.addNewCrossAx().setVal(123457); //id of the val axis
ctCatAx.addNewTickLblPos().setVal(STTickLblPos.NEXT_TO);
//val axis 1 (left)
CTValAx ctValAx = ctPlotArea.addNewValAx();
ctValAx.addNewAxId().setVal(123457); //id of the val axis
ctScaling = ctValAx.addNewScaling();
ctScaling.addNewOrientation().setVal(STOrientation.MIN_MAX);
ctValAx.addNewDelete().setVal(false);
ctValAx.addNewAxPos().setVal(STAxPos.L);
ctValAx.addNewCrossAx().setVal(123456); //id of the cat axis
ctValAx.addNewCrosses().setVal(STCrosses.AUTO_ZERO); //this val axis crosses the cat axis at zero
ctValAx.addNewTickLblPos().setVal(STTickLblPos.NEXT_TO);
As for the amount of "transmission= C cell", the unit is large, so I'm trying to make another value axis on the right, but I kept getting errors, so I asked. How can I create a valueaxis on the right, the number of "transmissions" based on the right, and the "user D cell , transfer count B cell" generates a chart based on the left?
From apache poi 4 on you should use the new XDDF classes to create charts. Playing around with the low level CT* classes is very complex and error prone.
Using line charts I have provided an example already here: Second Line in an Apache-POI chart with seperate axis.
But using bar charts there is an additional problem to solve. If one bar chart series is on primary axis and another is on secondary axis, then the bars will overlap each other. This is because each of the series are oriented only on those series using the same axis. In other words the series on primary axis do not respect the series on the secondary axis when it comes to taking space on the chart. For line charts this is not a problem but for bar charts it is.
To solve this additional series having dummy data (all 0) can be used on both the axes. Those additional series lead to invisible bars (height 0) which also take space and so can be used to shift the visible bars.
The following complete example shows this. It is tested and works using apache poi 4.1.2 and apache poi 5.1.0.
import java.io.*;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xddf.usermodel.*;
import org.apache.poi.xddf.usermodel.chart.*;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFDrawing;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class CreateExcelXDDFChart {
public static void main(String[] args) throws Exception {
try (XSSFWorkbook document = new XSSFWorkbook()) {
XSSFSheet chartSheet = document.createSheet("chart");
XSSFSheet dataSheet = document.createSheet("data");
// create the data
String[] categories = new String[] { "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9" };
Double[] values1 = new Double[] { 1d, 2d, 3d, 4d, 5d, 6d, 7d, 8d, 9d };
Double[] values2 = new Double[] { 200d, 300d, 400d, 500d, 600d, 700d, 800d, 900d, 1000d };
int r = 0;
for (String cat : categories) {
dataSheet.createRow(r).createCell(0).setCellValue(cat);
dataSheet.getRow(r).createCell(1).setCellValue(values1[r]);
dataSheet.getRow(r).createCell(2).setCellValue(values2[r]);
r++;
}
// create the chart
XSSFDrawing drawing = chartSheet.createDrawingPatriarch();
XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 0, 16, 22);
XDDFChart chart = drawing.createChart(anchor);
// create data sources
int numOfPoints = categories.length;
// dummy 0-values for the pad data source
Double[] dummyValuesForPad = new Double[numOfPoints];
for (int i = 0; i < numOfPoints; i++) {
dummyValuesForPad[i] = 0d;
}
XDDFDataSource<String> categoriesData = XDDFDataSourcesFactory.fromStringCellRange(dataSheet, new CellRangeAddress(0, numOfPoints-1, 0, 0));
XDDFNumericalDataSource<Double> valuesData1 = XDDFDataSourcesFactory.fromNumericCellRange(dataSheet, new CellRangeAddress(0, numOfPoints-1, 1, 1));
XDDFNumericalDataSource<Double> valuesData2 = XDDFDataSourcesFactory.fromNumericCellRange(dataSheet, new CellRangeAddress(0, numOfPoints-1, 2, 2));
// data source for the pad series
XDDFNumericalDataSource<Double> pad = XDDFDataSourcesFactory.fromArray(dummyValuesForPad);
// first bar chart
XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
leftAxis.setCrossBetween(AxisCrossBetween.BETWEEN);
XDDFChartData data = chart.createData(ChartTypes.BAR, bottomAxis, leftAxis);
XDDFBarChartData bar = (XDDFBarChartData) data;
bar.setBarDirection(BarDirection.COL);
XDDFChartData.Series series = data.addSeries(categoriesData, valuesData1);
series.setTitle("Series 1", null);
// additional pad series - takes space at right side for primary axis
series = data.addSeries(categoriesData, pad);
series.setTitle("pad", null);
chart.plot(data);
// second bar chart
// bottom axis must be there but must not be visible
bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
bottomAxis.setVisible(false);
XDDFValueAxis rightAxis = chart.createValueAxis(AxisPosition.RIGHT);
rightAxis.setCrosses(AxisCrosses.MAX);
rightAxis.setCrossBetween(AxisCrossBetween.BETWEEN);
// set correct cross axis
bottomAxis.crossAxis(rightAxis);
rightAxis.crossAxis(bottomAxis);
data = chart.createData(ChartTypes.BAR, bottomAxis, rightAxis);
bar = (XDDFBarChartData) data;
bar.setBarDirection(BarDirection.COL);
// additional pad series - takes space at left side for secondary axis
series = data.addSeries(categoriesData, pad);
series.setTitle("pad", null);
series = data.addSeries(categoriesData, valuesData2);
series.setTitle("Series 2", null);
chart.plot(data);
// Write the output to a file
try (FileOutputStream fileOut = new FileOutputStream("CreateExcelXDDFChart.xlsx")) {
document.write(fileOut);
}
}
}
}
Above example works when Microsoft Excel is used to show the resulting *.xlsx file. But some other spreadsheet calculation applications are not able to use array literals ({0,0,0,0,0,0,0,0,0}) as data source for chart series. So the more compatible solution will be using a unused cell range as datasource for the additional dummy series. For example use column IV for this as so:
...
// dummy 0-values for the pad data source in column IV
for (int r = 0; r < numOfPoints; r++) {
XSSFRow row = dataSheet.getRow(r); if (row == null) row = dataSheet.createRow(r);
XSSFCell cell = row.createCell(255);
cell.setCellValue(0);
}
// data source for the pad series
XDDFNumericalDataSource<Double> pad = XDDFDataSourcesFactory.fromNumericCellRange(dataSheet, new CellRangeAddress(0, numOfPoints-1, 255, 255));
...
And also for compatibility reasons you should set colors for the bars as done in the apache poi example in BarChart.java which is available in https://svn.apache.org/repos/asf/poi/trunk/poi-examples/src/main/java/org/apache/poi/examples/xssf/usermodel/. Some other spreadsheet calculation applications will not automatically choose color if not given, as Excel does.
If you have more than one series in one of the bar chart, you need more pad series in the other bar chart which uses the other axis. The pad series are needed to shift the visible bar series and to determine the bar width of them. So if you have two visible bar series on the first chart which uses the left axis and one visible bar series on the second chart which uses the right axis, then you need one additional pad series as the last series in the first bar chart and you need two pad series as the first series in the second bar chart. In other words, you need as much pad series that both bar charts have the same count of series to have the same bar width in both. And the position of the invisible pad series determines how the visible bar series are shifted.
If you need a legend, then the pad series will disturb. So you need deleting them from the legend. In remove specific legend apache poi excel graph XDDFChartLegend I have shown how to do that.
I will provide another complete example which shows all this:
import java.io.*;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xddf.usermodel.*;
import org.apache.poi.xddf.usermodel.chart.*;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFDrawing;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class CreateExcelXDDFChart {
public static void main(String[] args) throws Exception {
try (XSSFWorkbook document = new XSSFWorkbook()) {
XSSFSheet chartSheet = document.createSheet("chart");
XSSFSheet dataSheet = document.createSheet("data");
// create the data
String[] categories = new String[] { "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9" };
Double[] values1 = new Double[] { 1d, 2d, 3d, 4d, 5d, 6d, 7d, 8d, 9d };
Double[] values2 = new Double[] { 200d, 300d, 400d, 500d, 600d, 700d, 800d, 900d, 1000d };
Double[] values3 = new Double[] { 4.5d, 4d, 3.5d, 3d, 2.5d, 2d, 1.5d, 1d, 0.5d };
int r = 0;
for (String cat : categories) {
dataSheet.createRow(r).createCell(0).setCellValue(cat);
dataSheet.getRow(r).createCell(1).setCellValue(values1[r]);
dataSheet.getRow(r).createCell(2).setCellValue(values2[r]);
dataSheet.getRow(r).createCell(3).setCellValue(values3[r]);
r++;
}
// create the chart
XSSFDrawing drawing = chartSheet.createDrawingPatriarch();
XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 0, 16, 22);
XDDFChart chart = drawing.createChart(anchor);
// create data sources
int numOfPoints = categories.length;
XDDFDataSource<String> categoriesData = XDDFDataSourcesFactory.fromStringCellRange(dataSheet, new CellRangeAddress(0, numOfPoints-1, 0, 0));
XDDFNumericalDataSource<Double> valuesData1 = XDDFDataSourcesFactory.fromNumericCellRange(dataSheet, new CellRangeAddress(0, numOfPoints-1, 1, 1));
XDDFNumericalDataSource<Double> valuesData2 = XDDFDataSourcesFactory.fromNumericCellRange(dataSheet, new CellRangeAddress(0, numOfPoints-1, 2, 2));
XDDFNumericalDataSource<Double> valuesData3 = XDDFDataSourcesFactory.fromNumericCellRange(dataSheet, new CellRangeAddress(0, numOfPoints-1, 3, 3));
/*
// dummy 0-values for the pad data source
Double[] dummyValuesForPad = new Double[numOfPoints];
for (int i = 0; i < numOfPoints; i++) {
dummyValuesForPad[i] = 0d;
}
*/
// data source for the pad series
//XDDFNumericalDataSource<Double> pad = XDDFDataSourcesFactory.fromArray(dummyValuesForPad);
//XDDFNumericalDataSource<Double> pad = XDDFDataSourcesFactory.fromArray(dummyValuesForPad, null);
// dummy 0-values for the pad data source in column IV
for (int i = 0; i < numOfPoints; i++) {
XSSFRow row = dataSheet.getRow(i); if (row == null) row = dataSheet.createRow(i);
XSSFCell cell = row.createCell(255);
cell.setCellValue(0);
}
// data source for the pad series
XDDFNumericalDataSource<Double> pad = XDDFDataSourcesFactory.fromNumericCellRange(dataSheet, new CellRangeAddress(0, numOfPoints-1, 255, 255));
// first bar chart
XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
leftAxis.setCrossBetween(AxisCrossBetween.BETWEEN);
XDDFChartData data = chart.createData(ChartTypes.BAR, bottomAxis, leftAxis);
XDDFBarChartData bar = (XDDFBarChartData) data;
bar.setBarDirection(BarDirection.COL);
XDDFChartData.Series series = data.addSeries(categoriesData, valuesData1);
series.setTitle("Series 1", null);
series = data.addSeries(categoriesData, valuesData3);
series.setTitle("Series 3", null);
// additional pad series - takes space at right side for primary axis
series = data.addSeries(categoriesData, pad);
series.setTitle("pad", null);
chart.plot(data);
// set bar colors
solidFillSeries(data, 0, PresetColor.GREEN);
solidFillSeries(data, 1, PresetColor.BLUE);
// second bar chart
// bottom axis must be there but must not be visible
bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
bottomAxis.setVisible(false);
XDDFValueAxis rightAxis = chart.createValueAxis(AxisPosition.RIGHT);
rightAxis.setCrosses(AxisCrosses.MAX);
rightAxis.setCrossBetween(AxisCrossBetween.BETWEEN);
// set correct cross axis
bottomAxis.crossAxis(rightAxis);
rightAxis.crossAxis(bottomAxis);
data = chart.createData(ChartTypes.BAR, bottomAxis, rightAxis);
bar = (XDDFBarChartData) data;
bar.setBarDirection(BarDirection.COL);
// additional pad series - takes space at left side for secondary axis
series = data.addSeries(categoriesData, pad);
series.setTitle("pad", null);
series = data.addSeries(categoriesData, pad);
series.setTitle("pad", null);
series = data.addSeries(categoriesData, valuesData2);
series.setTitle("Series 2", null);
chart.plot(data);
// set bar colors
solidFillSeries(data, 2, PresetColor.RED);
// set legend
XDDFChartLegend legend = chart.getOrAddLegend();
legend.setPosition(LegendPosition.BOTTOM);
// set legend entries for pad series deleted
XDDFLegendEntry legendEntry = getOrAddLegendEntry(legend, 2);
legendEntry.setDelete(true);
legendEntry = getOrAddLegendEntry(legend, 3);
legendEntry.setDelete(true);
legendEntry = getOrAddLegendEntry(legend, 4);
legendEntry.setDelete(true);
// Write the output to a file
try (FileOutputStream fileOut = new FileOutputStream("CreateExcelXDDFChart.xlsx")) {
document.write(fileOut);
}
}
}
private static XDDFLegendEntry getOrAddLegendEntry(XDDFChartLegend legend, long index) {
XDDFLegendEntry legendEntry = null;
for (XDDFLegendEntry storedLegendEntry : legend.getEntries()) {
if (storedLegendEntry.getIndex() == index) {
legendEntry = storedLegendEntry;
break;
}
}
if (legendEntry == null) {
legendEntry = legend.addEntry();
legendEntry.setIndex(index);
}
return legendEntry;
}
private static void solidFillSeries(XDDFChartData data, int index, PresetColor color) {
XDDFSolidFillProperties fill = new XDDFSolidFillProperties(XDDFColor.from(color));
XDDFChartData.Series series = data.getSeries(index);
XDDFShapeProperties properties = series.getShapeProperties();
if (properties == null) {
properties = new XDDFShapeProperties();
}
properties.setFillProperties(fill);
series.setShapeProperties(properties);
}
}
I created a program that randomly draws circles,squares,rectangles. My problem is I'm getting the click position with event.getX() and event.getY();
Here is the problem:
Green point is the where I click the Canvas.
↑→ axis must be like this. But in my program it stands like this ↓→
Here is the details:
Getting mouse position with (extending Canvas):
super.setOnMouseClicked(event -> selectFigureContaining(event.getX(),event.getY()));
Initializing part :
#Override
public void start(Stage primaryStage) {
this.color = Color.BLACK;
toggleGroup = new ToggleGroup();
hBox = new HBox();
vBox = new VBox();
label = new Label();
vBox.setPadding(new Insets(5,15,0,15));
vBox.setSpacing(10);
hBox.setPadding(new Insets(5,0,0,0));
//Radio Buttons
red = new RadioButton("Red");
red.setSelected(true);
green = new RadioButton("Green");
blue = new RadioButton("Blue");
red.setToggleGroup(toggleGroup);
green.setToggleGroup(toggleGroup);
blue.setToggleGroup(toggleGroup);
//Buttons
buttonCircle = new Button("Circle");
buttonCircle.setMinSize(70,20);
buttonCircle.setOnMouseClicked(event -> circleButtonClicked());
buttonSquare = new Button("Square");
buttonSquare.setMinSize(70,20);
buttonSquare.setOnMouseClicked(event -> squareButtonClicked());
buttonRectangle = new Button("Rectangle");
buttonRectangle.setMinSize(70,20);
buttonRectangle.setOnMouseClicked(event -> rectangleButtonClicked());
cleanAll = new Button("Clean All");
cleanAll.setMinSize(70,20);
cleanAll.setOnMouseClicked(event -> cleanAllEvent());
figureCanvas = new FigureCanvas(10,400,500, this);
vBox.getChildren().addAll(red,green,blue,buttonCircle,buttonSquare,buttonRectangle,cleanAll,label);
hBox.getChildren().addAll(vBox,figureCanvas);
Scene scene = new Scene(hBox,500,500);
primaryStage.setScene(scene);
primaryStage.setTitle("Draw Figure");
primaryStage.show();
}
I'm really new to JavaFX. I couldn't understand why y axis getting smaller on left upper side. Thanks.
Normally, the coordinate system's origin is at the top left of the screen and positive y is downwards:
. ---> +x
|
v +y
You can transform your y position like this to get expected movement (origin at the bottom left, +y goes up):
y = canvas.getHeight() - y;
I am trying to make a normal distribution graph using the JFreeChart library. I am successful if I try to get one area under the graph. However I did not find a way on how get 2 areas under the graph.
Here is the code for one side :
public GrafHujungKanan() {
Function2D normal = new NormalDistributionFunction2D(0.0, 1.0);
dataset = DatasetUtilities.sampleFunction2D(normal, -4, 4, 100,
"Normal");
XYSeries fLine = new XYSeries("fLine");
fLine.add(nilaiKritikal, 0);
fLine.add(4, 0);
((XYSeriesCollection) dataset).addSeries(fLine);
NumberAxis xAxis = new NumberAxis(null);
NumberAxis yAxis = new NumberAxis(null);
XYDifferenceRenderer renderer = new XYDifferenceRenderer();
xAxis.setRange(0, 5);
plot = new XYPlot(dataset, xAxis, yAxis, renderer);
chart = new JFreeChart(plot);
chart.removeLegend();
ChartPanel cp = new ChartPanel(chart);
this.add(cp);
}
Here is how it looks with the above code
And here is how I need it to look :
I already tried flipping the values with positive and negative. But instead the line of the graph turns green.
This is what I tried
public GrafDuaHujung() {
Function2D normal = new NormalDistributionFunction2D(0.0, 1.0);
dataset = DatasetUtilities.sampleFunction2D(normal, -4, 4, 100,
"Normal");
// line on right side
XYSeries fLine = new XYSeries("fLine");
fLine.add(2, 0);
fLine.add(4, 0);
((XYSeriesCollection) dataset).addSeries(fLine);
// line on left side
XYSeries dLine = new XYSeries("dLine");
dLine.add(-2, 0);
dLine.add(-4, 0);
((XYSeriesCollection) dataset).addSeries(dLine);
NumberAxis xAxis = new NumberAxis(null);
NumberAxis yAxis = new NumberAxis(null);
XYDifferenceRenderer renderer = new XYDifferenceRenderer();
xAxis.setRange(0, 5);
plot = new XYPlot(dataset, xAxis, yAxis, renderer);
chart = new JFreeChart(plot);
chart.removeLegend();
ChartPanel cp = new ChartPanel(chart);
this.add(cp);
}
Thank you for your answer.
You can use multiple datasets.
public GrafDuaHujung() {
Function2D normal = new NormalDistributionFunction2D(0.0, 1.0);
dataset = DatasetUtilities.sampleFunction2D(normal, -4, 4, 100, "Normal");
dataset2 = DatasetUtilities.sampleFunction2D(normal, -4, 4, 100, "Normal"); //New
// line on right side
XYSeries fLine = new XYSeries("fLine");
fLine.add(2, 0);
fLine.add(4, 0);
((XYSeriesCollection) dataset).addSeries(fLine);
// line on left side
XYSeries dLine = new XYSeries("dLine");
dLine.add(-2, 0);
dLine.add(-4, 0);
((XYSeriesCollection) dataset2).addSeries(dLine); //Changed
XYDifferenceRenderer renderer = new XYDifferenceRenderer();
plot = new XYPlot(); //New
plot.setDataset(0, dataset); //New
plot.setDataset(1, dataset2); //New
plot.setRenderer(renderer); //New
chart = new JFreeChart(plot);
chart.removeLegend();
ChartPanel cp = new ChartPanel(chart);
this.add(cp);
}
I am referring to :
Changing the shapes of points in scatter plot
But Am not able to see the shape of my x,y data points:
public void plotHysteresis()
{
s1= new double[6];
s2= new double[6];
s3= new double[6];
s4= new double[6];
int i=0;
for(i=0;i<6;i++)
{
s1[i]=hyst[i];
System.out.println("s1[" +i +"] : " +s1[i] +"\n");
}
for(i=0;i<6;i++)
{
s2[i]=hyst[10-i];
System.out.println("s2[" +i +"] : " +s2[i] +"\n");
}
for(i=0;i<6;i++)
{
s3[i]=hyst[11+i];
System.out.println("s3[" +i +"] : " +s3[i] +"\n");
}
for(i=0;i<6;i++)
{
s4[i]=hyst[21-i];
System.out.println("s4[" +i +"] : " +s4[i] +"\n");
}
// DefaultCategoryDataset dataset = new DefaultCategoryDataset();
XYSeries series3 = new XYSeries("III");
int x=-25;
System.out.println(x +"***\n");
for(i=5;i>=0;i--)
{
series3.add(x,s3[i]);
x=x+5;
}
System.out.println(x +"***\n");
XYSeries series4 = new XYSeries("IV");
for(i=0;i<6;i++)
{
x=x-5;
series4.add(x,s4[i] );
}
System.out.println(x +"###\n");
XYSeries series1 = new XYSeries("I");
x=0;
for(i=0;i<6;i++)
{
series1.add(x,s1[i] );
x=x+5;
}
// x=x-5;
System.out.println(x +"***\n");
XYSeries series2 = new XYSeries("II");
for(i=5;i>=0;i--)
{
x=x-5;
series2.add(x,s2[i] );
}
System.out.println(x +"***\n");
XYSeriesCollection dataset = new XYSeriesCollection();
dataset.addSeries(series3);
dataset.addSeries(series4);
dataset.addSeries(series1);
dataset.addSeries(series2);
JFreeChart chart = ChartFactory.createXYLineChart(
"Hysteresis Plot", // chart title
"Pounds(lb)", // domain axis label
"Movement(inch)", // range axis label
dataset, // data
PlotOrientation.VERTICAL, // orientation
false, // include legend
true, // tooltips
false // urls
);
chart.setBackgroundPaint(Color.white);
//chart.setBackgroundPaint(new Color(249, 231, 236));
/*CategoryPlot plot = (CategoryPlot) chart.getPlot();
plot.setBackgroundPaint(Color.lightGray);
plot.setRangeGridlinePaint(Color.white);
plot.getRenderer().setSeriesPaint(0, Color.BLUE);
plot.getRenderer().setSeriesPaint(1, Color.BLUE);
plot.getRenderer().setSeriesPaint(2, Color.BLUE);
plot.getRenderer().setSeriesPaint(3, Color.BLUE);*/
Shape cross = ShapeUtilities.createRegularCross(4, 3);
XYPlot plot = (XYPlot) chart.getPlot();
XYItemRenderer renderer = plot.getRenderer();
renderer.setSeriesPaint(0, Color.RED);
renderer.setSeriesPaint(1, Color.RED);
renderer.setSeriesPaint(2, Color.RED);
renderer.setSeriesPaint(3, Color.RED);
renderer.setSeriesShape(0, cross);
renderer.setSeriesShape(1, cross);
renderer.setSeriesShape(2, cross);
renderer.setSeriesShape(3, cross);
renderer.setSeriesVisible(0,true);
renderer.setSeriesVisible(1,true);
renderer.setSeriesVisible(2,true);
renderer.setSeriesVisible(3,true);
plot.setDomainCrosshairVisible(true);//Sets Y axis visible blue
plot.setRangeCrosshairVisible(true);//Sets X axis visible blue
/*LineAndShapeRenderer rend
= (LineAndShapeRenderer) plot.getRenderer();
rend.setShapesVisible(true);*/
//renderer.setDrawOutlines(true);
//renderer.setUseFillPaint(true);
//renderer.setFillPaint(Color.white);
ChartPanel frame = new ChartPanel(chart);
frame.setVisible(true);
frame.setSize(plotPanel.getWidth(),plotPanel.getHeight());
plotPanel.add(frame);
plotPanel.repaint();
}
The above code gives me output:
Earlier I was able to see the shape with CategoryPlot and LineChart as shown in commented part of the code, but it is not working for XYLineChart.
Please help
Thanks
Got the solution at:
How to get diamond shape for points in JFreechart
Can I change the color of
plot.setDomainCrosshairVisible(true);//Sets Y axis visible blue
plot.setRangeCrosshairVisible(true);//Sets X axis visible blue
want to make it black instead of it appearing as blue.
Ok got the answer:
How to get diamond shape for points in JFreechart
XYLineAndShapeRenderer r = (XYLineAndShapeRenderer) plot.getRenderer();
r.setSeriesShape(0, ShapeUtilities.createDiamond(5));
r.setSeriesShapesVisible(0, true);
Was not adding XYLineAndShapeRenderer in my code