Applying css to LineChart JavaFx chart - java

I am filling a LineChat chart with data and sometimes I need to redraw it. The drawGraph() method is attached to the button click event (we press it to redraw the graph). I want the first data series to have transparent markers and the second data series to have transparent lines. For this I use css. On the first call to the drawGraph() method, everything works fine, and I get this picture:
It should be
I try to make it so that every time I redraw the chart, I get the 1st picture
But from the next redrawings, the following picture starts to be displayed every other time:
It should not be
That is, a graph is displayed every other time without applying css to it, and one data series overlaps another
Style sheet:
/* Removes points from a data series */
.default-color0.chart-line-symbol {
-fx-background-color: transparent;
}
/* Removes lines from a data series */
.default-color1.chart-series-line {
-fx-stroke: transparent;
}
Chart redrawing method (from ApplicationController):
double[] X = new double[] {1,2,3,4,5};
double[] Y = new double[] {1.9,5.5,10,15,21};
public void drawGraph() {
//clear the Chart
lineChart.getData().clear();
//Data series #1
ObservableList<XYChart.Data> datas = FXCollections.observableArrayList();
XYChart.Series series = new XYChart.Series();
//Filling series #1
for(int i=0; i< X.length; i++){
datas.add(new XYChart.Data(X[i],Y[i]));
}
series.setData(datas);
//Data series #2
ObservableList<XYChart.Data> datas1 = FXCollections.observableArrayList();
XYChart.Series series1 = new XYChart.Series();
//Filling series #2
for(int i=0; i< X.length; i++){
datas1.add(new XYChart.Data(X[i],Y[i]));
}
series1.setData(datas1);
//lineChart.setStyle();
lineChart.getStylesheets().add(HelloApplication.class.getResource("style.css")
.toExternalForm());
lineChart.getData().add(series);
lineChart.getData().add(series1);
}

It was bad practice to create new data series and place them on the chart instead of the old ones. Also, it was not worth using a style sheet for each new data redrawing.
What I did was to fill in the graph for the first time, and when it was redrawn, I replaced it in the series as follows.
//We get a series:
XYChart.Series<Number, Number> series = lineChart.getData().get(0);
//Let's remove all elements in the series:
series.getData().clear();
//We add elements to the series like this:
series.getData().add(new LineChart.Data<Number,Number>(1, 2));

Related

How to remove future dates from stacked-bar chart

My current java code generates a stacked-bar chart using Apache POI 4.0.1 as shown in following diagram.
I don't want to print a line for future dates (for example: In following chart, I don't want those zeros from 04/04 date); but I want those dates below X-axis.
My question is how to remove/disable line drawing for Zero ?
Code sample
// line chart
// axis must be there but must not be visible
bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
bottomAxis.setVisible(false);
leftAxis = chart.createValueAxis(AxisPosition.LEFT);
leftAxis.setVisible(false);
// set correct cross axis
bottomAxis.crossAxis(leftAxis);
leftAxis.crossAxis(bottomAxis);
data = chart.createData(ChartTypes.LINE, bottomAxis, leftAxis);
XDDFLineChartData.Series series4 = (XDDFLineChartData.Series)data.addSeries(date, category);
series4.setTitle("Total", null);
series4.setSmooth(false);
series4.setMarkerStyle(MarkerStyle.STAR);
chart.plot(data);
// correct the id and order, must not start 0 again because there are three bar series already
chart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(0).getIdx().setVal(3);
chart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(0).getOrder().setVal(3);
solidLineSeries(data, 0, PresetColor.YELLOW);
// add data labels
chart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(0).addNewDLbls();
chart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(0).getDLbls()
.addNewSpPr().addNewSolidFill().addNewSrgbClr().setVal(new byte[]{(byte)255,(byte)255,0});
chart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(0).getDLbls()
.addNewDLblPos().setVal(org.openxmlformats.schemas.drawingml.x2006.chart.STDLblPos.CTR);
chart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(0).getDLbls().addNewShowVal().setVal(true);
chart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(0).getDLbls().addNewShowLegendKey().setVal(false);
chart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(0).getDLbls().addNewShowCatName().setVal(false);
chart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(0).getDLbls().addNewShowSerName().setVal(false);
First you've to write following lines of code before chart.plot(data);.
This will set blank values as gaps in the chart so you can accurately plot data series of different lengths
CTDispBlanksAs disp = CTDispBlanksAs.Factory.newInstance();
disp.setVal(STDispBlanksAs.GAP);
chart.getCTChart().setDispBlanksAs(disp);
Imports
import org.openxmlformats.schemas.drawingml.x2006.chart.CTDispBlanksAs;
import org.openxmlformats.schemas.drawingml.x2006.chart.STDispBlanksAs;
Then after Drawing code and outside loop, write a code to set those zeros as BLANK.
int rownum = 0;
// loop start
Row rowT = sheetTestcasenBurndown.getRow(rownum);
for (int cellnumStart = 1; cellnumStart <= cellnumEnd; cellnumStart++) {
Cell cell = rowT.getCell(cellnumStart);
cell.setCellType(CellType.BLANK);
}
// loop end
rownum++;
Output

Achartengine display values inside the series areas and horizontal legend

I have tried the following with the default renderer
CategorySeries series = new CategorySeries("First test");
int numSlide = portions.length;
for (int i = 0; i < numSlide; i++){
series.add(seriesNames[i]+" ("+portions[i]+" %)", portions[i]);
}
DefaultRenderer defaultRenderer = new DefaultRenderer();
SimpleSeriesRenderer simpleSeriesRenderer = null;
for (int i = 0; i < numSlide; i++){
simpleSeriesRenderer = new SimpleSeriesRenderer();
simpleSeriesRenderer.setColor(colors[i]);
simpleSeriesRenderer.setChartValuesFormat(new DecimalFormat("###,###,##0.0"));
defaultRenderer.addSeriesRenderer(simpleSeriesRenderer);
}
defaultRenderer.setInScroll(true);
defaultRenderer.setZoomButtonsVisible(false);
defaultRenderer.setZoomEnabled(true);
defaultRenderer.setLabelsTextSize(18); //value size
defaultRenderer.setLabelsColor(R.color.primary_dark);
defaultRenderer.setShowLegend(false);
defaultRenderer.setClickEnabled(true);
defaultRenderer.setPanEnabled(true);
defaultRenderer.setShowLabels(true);
defaultRenderer.setShowLegend(true);
//return the pie chart view
return ChartFactory.getPieChartView(context, series, defaultRenderer);
Now the above produces
What am looking forward to get is to have the percentage values eg: 2% inside the chart area something which looks like this
How do i get the percentage values to be displayed inside the charts?
You want to display values and hide labels. Do that like so in your renderer:
defaultRenderer.setShowLabels(false);
defaultRenderer.setDisplayValues(true);
Also, your series names should probably not contain the values, so change the following line
series.add(seriesNames[i]+" ("+portions[i]+" %)", portions[i]);
to
series.add(seriesNames[i], portions[i]);

Graphing scientific data in LineChart from MPAndroidChart

I am using MPAndroidChart library to draw graphs (especially LineCharts) in my App.
To draw a LineChart with the mentioned library first we need to create entries and labels as follow:
// Getting LineChart
LineChart lineChart = (LineChart) rootView.findViewById(R.id.chart);
// Creating list of entry
ArrayList<Entry> entries = new ArrayList<>();
// Creating labels
ArrayList<String> labels = new ArrayList<String>();
// Fill entries and lables
entries.add(new Entry(326.422f, 0));
entries.add(new Entry(8.36f, 1));
entries.add(new Entry(6.5f, 2));
entries.add(new Entry(2.37f, 3));
entries.add(new Entry(18.13f, 4));
entries.add(new Entry(9f, 5));
labels.add("0");
labels.add("1");
labels.add("2");
labels.add("3");
labels.add("4");
labels.add("5");
// Create dataset
final LineDataSet dataset = new LineDataSet(entries, "Legend description");
// Create LineData with labels and dataset prepared previously
LineData data = new LineData(labels, dataset);
// Set the data and list of labels into chart
lineChart.setData(data);
Ok this is working, but the point is what if I want to graph a set of coordinates like this: X = {(35.3, 22.9), (69.39, 27.36), (66.37, 31.697), (58.36, 36.32), (45.336, 38.296), (25.39, 40), (67.396, 43.633)}.
The constructor of Entry accepts a float number as first parameter and an integer as second parameter, so how can I give the above X set to the LineChart?
Someone could say that I can set the labels accordingly, for example the first label could be labeled as "22.9", the second as "27.36", and so on... But this is mathematically wrong as the graph is not scaled properly.
In the documentation I found classes like Entry, BarEntry, BubbleEntry, CandleEntry but there is nothing something like LineEntry.
Can anyone point me to the right direction on how to achieve this goal?
Thank you,
HSB
Currently only integers are supported for the x-axis. The reason therefore is that each string on the x-axis should correspond to a value on the y-axis.
This will change in the next release of the library, where both values will be changed to double.
The new version should be released in April.

Javafx the UI freezes when my application tries to display a large amount of data

I have a GUI that contains a Line chart and I have 6 series each series has a very big number of samples e.g the first serie has 9000 points.
I tried to add the serie to my lineChart and then to display it.
When I start my app I can see the 6 plotted series but the GUI freezes/hangs
That's why i tried to use multi threading :) but i don't really know how I use it in this case
Has Someone an Idea how to prevent this freezing by adding a large amount of data
Here is my code:
// listOfSensortDataArrays is a List of 1d arrays it contains 6 1d arrays and each array has the length 9150
for (int j = 0; j <6; j++) {
// I create an empty serie
XYChart.Series<Number, Number> series = newXYChart.Series<Number,Number>();
for (int i = 0; i < listOfSensorDataArrays.get(j).length; i++) {
// I fill the serie with the data from listOfSensorDataArrays
series.add(new XYChart.Data<Number, Number>(i,listOfSensorDataArrays.get(j)[i]));
}
// and here I add the serie to my LineChart
lineChart.getData().add(series);}

JfreeChart - How to hide item from legend - Problem of colors

I would like to hide items from legend in Jfreechart and I've tried this code
jFreeChart: How to hide items from legend?
It works but something strange happened : the colors of the legend items do not match to the right data anymore. In other words, in the graph, a piece of data appears in yellow for example but the legend corresponding to this item appears in another color. In fact, the colors in the legend have been mixed.
Besides, when I try to display both old and new legends, there is no problem of colors but when I make the old legend invisible, the problem of mixed color appears. Obviously, I would like not to display the old legend.
Working code =>
LegendItemCollection legendItemsOld = localCombinedDomainXYPlot.getLegendItems();
final LegendItemCollection legendItemsNew = new LegendItemCollection();
for(int i = 0; i<4; i++){
legendItemsNew.add(legendItemsOld.get(i));
}
LegendItemSource source = new LegendItemSource() {
LegendItemCollection lic = new LegendItemCollection();
{lic.addAll(legendItemsNew);}
public LegendItemCollection getLegendItems() {
return lic;
}
};
localJFreeChart.addLegend(new LegendTitle(source));
ChartUtilities.applyCurrentTheme(localJFreeChart);
localJFreeChart.getLegend().setVisible(true); ///////////////////
Not working code =>
LegendItemCollection legendItemsOld = localCombinedDomainXYPlot.getLegendItems();
final LegendItemCollection legendItemsNew = new LegendItemCollection();
for(int i = 0; i<4; i++){
legendItemsNew.add(legendItemsOld.get(i));
}
LegendItemSource source = new LegendItemSource() {
LegendItemCollection lic = new LegendItemCollection();
{lic.addAll(legendItemsNew);}
public LegendItemCollection getLegendItems() {
return lic;
}
};
localJFreeChart.addLegend(new LegendTitle(source));
ChartUtilities.applyCurrentTheme(localJFreeChart);
localJFreeChart.getLegend().setVisible(false); ///////////////////
Based on this thread, you might try adding a null element to replace the unwanted legend item. The other approach appears to elide unwanted items, but I'm not sure if you're doing the same. To clarify, consider posting an sscce that demonstrates the problem. One of the org.jfree.chart.demo classes may be a suitable starting point.

Categories

Resources