JavaFX LineChart showing right result in one computer and wrong in other - java

So, we're doing a home assignment in Java and for UI i used JavaFX. So my program works, draws a linechart like a charm and no problem. When my classmate did the same thing, his didn't. Dude sent me his code, i ran it and in my computer everything was fine. What could cause something like that - linechart showing wrong in one computer and right in other?
The data is added to the chart in the same way, in my computer the data is shown in the way it's entered to the chart but in his computer it's in wrong order (the elements are sorted for some reason).
public LineChart createChart(ArrayList elements) throws PoleValitudErind{
//Elements entered or chosen, in the right order!
ArrayList fixedLst = new ArrayList();
int s = 0;
for (int i = 0; i<elements.size();i++){
s = (int) elements.get(i);
fixedLst.add(s);
}
String strStart = tf2.getText();
int intStart = 0;
try {
intStart = Integer.parseInt(strStart);
}
catch (NumberFormatException j){
throw new PoleValitudErind();
}
final NumberAxis xAxis = new NumberAxis();
final NumberAxis yAxis = new NumberAxis();
final LineChart<Number,Number> lineChart =
new LineChart<Number,Number>(xAxis,yAxis);
XYChart.Series series = new XYChart.Series();
series.setName("Radade vahetus");
//populating the series with data
series.getData().add(new XYChart.Data(intStart,0));
int counter = 1;
for (int j = 0;j<fixedLst.size();j++){
series.getData().add(new XYChart.Data(fixedLst.get(j),counter));
counter += 1;
}
//System.out.println(series.getData());
lineChart.getData().add(series);
lineChart.setMaxHeight(150);
return lineChart;
}

Related

MPAndroidChart BarChart (Grouped DataSets) not showing all bars

I am using MPAndroidChart BarChart (Grouped DataSets) for showing data of two users. It is showing data but the problem is that its not displaying data on x-axis from start due to which all the bars are not visible.
Arrays:
String[] title_list = {"Whatsapp", "Visit", "Callback", "Interested"}
int[] title_values_1 = {50, 15, 25, 36};
int[] title_values_2 = {70, 35, 15, 10};
BarChart:
public void LoadBarChart()
{
List<BarEntry> barEntries1 = new ArrayList<>();
for (int i = 0; i < title_list.length; i++) {
barEntries1.add(new BarEntry(i, title_values_1[i]));
}
List<BarEntry> barEntries2 = new ArrayList<>();
for (int i = 0; i < title_list.length; i++) {
barEntries2.add(new BarEntry(i, title_values_2[i]));
}
BarDataSet dataSet1 = new BarDataSet(barEntries1, "Dataset 1");
dataSet1.setColors(getColor(R.color.pie_chart_blue));
dataSet1.setValueTextSize(10f); /* values size */
dataSet1.setValueTextColor(Color.WHITE);
BarDataSet dataSet2 = new BarDataSet(barEntries2, "Dataset 2");
dataSet2.setColors(getColor(R.color.pie_chart_red));
dataSet2.setValueTextSize(10f); /* values size */
dataSet2.setValueTextColor(Color.WHITE);
float groupSpace = 0.06f;
float barSpace = 0.02f; // x2 dataset
float barWidth = 0.45f; // x2 dataset
BarData data = new BarData(dataSet1, dataSet2);
ValueFormatter vf = new ValueFormatter() {
#Override
public String getFormattedValue(float value) { return ""+(int)value; }
};
data.setValueFormatter(vf);
data.setValueTextSize(12f);
data.setBarWidth(barWidth);
XAxis xAxis = barChart.getXAxis();
xAxis.setValueFormatter(new ValueFormatter() {
#Override
public String getFormattedValue(float value) {
return title_list[(int) value];
}
});
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setDrawGridLines(false);
xAxis.setDrawAxisLine(false);
xAxis.setLabelCount(title_list.length);
barChart.setData(data);
barChart.groupBars(0f, groupSpace, barSpace);
barChart.getDescription().setEnabled(false);
barChart.setDrawValueAboveBar(false);
barChart.setTouchEnabled(false);
barChart.animateY(1000);
barChart.invalidate();
}
I have tried answers on stackoverflow but nothing resolved my issue. Kindly help!
UPDATE:
After Shayan answer all bars are now visible but labels are not centered.
Is it possible to center the lables with the bars?
You have to play with the spacings, I think when its unable to adjust the whole thing in the screen it starts cutting bars.
Add this line so bars may start from the begining
xAxis.setAxisMinimum(0f); // this replaces setStartAtZero(true)
Setting spacing and widths a bit low like this
float groupSpace = 0.06f;
float barSpace = 0.02f; // x2 dataset
float barWidth = 0.40f; // x2 dataset
The complete method will look something like this
public void LoadBarChart()
{
List<BarEntry> barEntries1 = new ArrayList<>();
for (int i = 0; i < title_list.length; i++) {
barEntries1.add(new BarEntry(i, title_values_1[i]));
}
List<BarEntry> barEntries2 = new ArrayList<>();
for (int i = 0; i < title_list.length; i++) {
barEntries2.add(new BarEntry(i, title_values_2[i]));
}
BarDataSet dataSet1 = new BarDataSet(barEntries1, "Dataset 1");
dataSet1.setColors(R.color.colorPrimary);
dataSet1.setValueTextSize(10f); /* values size */
dataSet1.setValueTextColor(Color.WHITE);
BarDataSet dataSet2 = new BarDataSet(barEntries2, "Dataset 2");
dataSet2.setColors(R.color.colorPrimary);
dataSet2.setValueTextSize(10f); /* values size */
dataSet2.setValueTextColor(Color.WHITE);
float groupSpace = 0.06f;
float barSpace = 0.02f; // x2 dataset
float barWidth = 0.40f; // x2 dataset
BarData data = new BarData(dataSet1, dataSet2);
ValueFormatter vf = new ValueFormatter() {
#Override
public String getFormattedValue(float value) { return ""+(int)value; }
};
data.setValueFormatter(vf);
// data.setValueTextSize(12f);
data.setBarWidth(barWidth);
XAxis xAxis = barChart.getXAxis();
xAxis.setValueFormatter(new ValueFormatter() {
#Override
public String getFormattedValue(float value) {
return title_list[(int) value];
}
});
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setDrawGridLines(false);
xAxis.setDrawAxisLine(false);
xAxis.setLabelCount(title_list.length);
xAxis.setAxisMinimum(0f); // this replaces setStartAtZero(true)
barChart.setData(data);
barChart.groupBars(0f,groupSpace,barSpace);
barChart.getDescription().setEnabled(false);
barChart.setDrawValueAboveBar(false);
barChart.setTouchEnabled(false);
barChart.animateY(1000);
barChart.invalidate();
}
Hope this works!
I am able to achieve the desired result by the guidance of Shayan. I have added few attributes in the answer.
Spacing and Bar Width:
float groupSpace = 0.15f;
float barSpace = 0.01f; // x2 dataset
float barWidth = 0.42f; // x2 dataset
Addition at X-Axis:
xAxis.setAxisMinimum(0f);
xAxis.setGranularity(1);
xAxis.setCenterAxisLabels(true);
xAxis.setAxisMaximum(title_list.length);
Formatter:
barChart.getXAxis().setValueFormatter(new IndexAxisValueFormatter(title_list));
So bar chart method now looks like this:
public void LoadBarChart()
{
List<BarEntry> barEntries1 = new ArrayList<>();
for (int i = 0; i < title_list.length; i++) {
barEntries1.add(new BarEntry(i, title_values_1[i]));
}
List<BarEntry> barEntries2 = new ArrayList<>();
for (int i = 0; i < title_list.length; i++) {
barEntries2.add(new BarEntry(i, title_values_2[i]));
}
BarDataSet dataSet1 = new BarDataSet(barEntries1, Global.employeesComparisonList.get(0).getName());
dataSet1.setColors(getColor(R.color.blue));
dataSet1.setValueTextSize(10f); /* values size */
dataSet1.setValueTextColor(Color.WHITE);
BarDataSet dataSet2 = new BarDataSet(barEntries2, Global.employeesComparisonList.get(1).getName());
dataSet2.setColors(getColor(R.color.red));
dataSet2.setValueTextSize(10f); /* values size */
dataSet2.setValueTextColor(Color.WHITE);
float groupSpace = 0.15f;
float barSpace = 0.01f; // x2 dataset
float barWidth = 0.42f; // x2 dataset
BarData data = new BarData(dataSet1, dataSet2);
ValueFormatter vf = new ValueFormatter() {
#Override
public String getFormattedValue(float value) { return ""+(int)value; }
};
data.setValueFormatter(vf);
data.setValueTextSize(12f);
data.setBarWidth(barWidth);
XAxis xAxis = barChart.getXAxis();
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setDrawGridLines(false);
xAxis.setDrawAxisLine(false);
xAxis.setLabelCount(title_list.length);
xAxis.setAxisMinimum(0f); // this replaces setStartAtZero(true)
xAxis.setGranularity(1);
xAxis.setCenterAxisLabels(true);
xAxis.setAxisMaximum(title_list.length);
Legend l = barChart.getLegend();
l.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER);
l.setOrientation(Legend.LegendOrientation.HORIZONTAL);
barChart.setData(data);
barChart.groupBars(0f,groupSpace,barSpace);
barChart.getXAxis().setValueFormatter(new IndexAxisValueFormatter(title_list));
barChart.getDescription().setEnabled(false);
barChart.setDrawValueAboveBar(false);
barChart.setTouchEnabled(false);
barChart.animateY(1000);
barChart.invalidate();
}
Final Result:
Yes, that can be done quite easily.
What you need is a BarChart with multiple BarDataSets where each set (in your case) represents count of each activity.
Here is an example of how to create a BarChart with multiple DataSets
Here is an tutorial of how to use MPAndroidChart with Realm.io
Example code (without realm.io)
List<String> xValues = ...; // "Denmark", "Finland", ...
XAxis xAxis = chart.getXAxis();
xAxis.setValueFormatter(new MyValueFormatter(xValues));
xAxis.setCenterAxisLabels(true);
// create 2 datasets
BarDataSet set1 = new BarDataSet(valuesMen, "Men");
set1.setColor(Color.BLUE);
BarDataSet set2 = new BarDataSet(valuesWomen, "Women");
set2.setColor(Color.RED);
BarData data = new BarData(set1, set2);
chart.setData(data);
chart.groupBars(...); // available since release v3.0.0
chart.invalidate(); // refresh
If you need further assistance, here is a detailed tutorial on grouped BarChart available on the wiki.
If you want to "stack" values in a BarChart above each other, you need to create a stacked-barchart: Android Stacked Bars Chart
**
Result Image
**

How to getTileProperty while using multi-layer map?

I'm new to Slick2D, and I'm using Tiled to make .tmx map.
for (int xAxis = 0; xAxis < map.getWidth(); xAxis++) {
for (int yAxis = 0; yAxis < map.getHeight(); yAxis++) {
int tileID = map.getTileId(xAxis, yAxis, 0);
String value = map.getTileProperty(tileID, "blocked", "0");
int valueInInt = Integer.parseInt(value);
if (valueInInt == 1) {
blocked[xAxis][yAxis] = true;
}
}
}
This works fine when the blocks are on the same layer with others, however, if I put the blocks on a different Tile layer, I can't get the right TileProperty anymore.
Why did it happen? What can I do with that or any ideals?
Thanks a lot.
The third parameter to TiledMap.getTileId() is the layerIndex. You would have to use that to select the layer where you're searching for tiles with the "blocked" property set to "1".

How can I plot points on a graph from function in another class which returns an array filled with values to plot

I have my first class
public class GetResults{
public double[] tableOfresults() {
double[] outputArray = new double[100];
double time;
double results
for(time = 0; time<outputArray.length; i++) {
//Some values are calculated and then stored in an array as below
outputArray[(int)Time] = Results
}
return outputarray;
This class just calculates some values I want to plot on a graph and stores them in the array.
This next class is what actually plots the points on my graph. I am unsure of a simple way to get points to plot on my X axis which are the Values of time(Time being the array index 0,1,2,3 ect) and my Y axis which are my Results. I am currently having to put all the positions in myself.
public class graph{
GetResults gr = new GetResuts();
public XYSeries inputOutputGraph() {
XYSeries graph = new XYSeries("My graph");
XYDataset xyDataset = new XYSeriesCollection(graph);
graph.add(1, gr.tableOfResults()[1]);
graph.add(2, gr.tableOfResults()[2]);
graph.add(3, gr.tableOfResults()[3]);
graph.add(4, gr.tableOfResults()[4]);
Here I am having to add the values myself(I have 1000 to do). I need something that looks like this graph.add(gr.tableOfResults()[gr.Time], gr.tableOfResults()[gr.Results]);
So that as my time goes up 0,1,2,3 it will plot my Results which is stored at index 0,1,2,3 at that position. How could I do this?? I have tried that code^^ and I got an array index out of bounds with the vaue my array size was set to
JFreeChart chart = ChartFactory.createXYLineChart(
"Graph", "Time", "results",
xyDataset, PlotOrientation.VERTICAL, true, true, false);
ChartFrame graphFrame = new ChartFrame("XYLine Chart", chart);
graphFrame.setVisible(true);
graphFrame.setSize(300, 300);
return graph;
}
}
You could just put your calculated values directly in an XYSeries and then let GetResults have a method that returns that series.
class GetResults {
public XYSeries getSeries() {
XYSeries series = new XYSeries("Series");
for (int i = 0; i < 10; i++) {
series.add(i, Math.pow(2, i));
}
return series;
}
}
Here's how you would use getSeries() in this example.
dataset.addSeries(new GetResults().getSeries());

Image histogram generated by JFreeChart

I want to display histogram of image color channels.
At first my reading of pixels looks like:
for(int i=0; i<width; i++)
for(int j=0; j<height; j++) {
data=writeableRaster.getDataElements(i, j, null);
red=colorModel.getRed(data);
green=colorModel.getGreen(data);
blue=colorModel.getBlue(data);
rgb=(red+green+blue)/3;
++redL[red];
++greenL[green];
++blueL[blue];
++rgbL[rgb];
}
}
I also have additional method for creating chart with given channel colors table:
int number = channelHistogram.length;
HistogramDataset dataset = new HistogramDataset();
dataset.setType(HistogramType.RELATIVE_FREQUENCY);
dataset.addSeries("Hist",channelHistogram,number);
String plotTitle = "Hist";
String xaxis = "number";
String yaxis = "value";
PlotOrientation orientation = PlotOrientation.VERTICAL;
boolean show = false;
boolean toolTips = false;
boolean urls = false;
JFreeChart chart = ChartFactory.createHistogram( plotTitle, xaxis, yaxis,
dataset, orientation, show, toolTips, urls);
But chart is wrong displayed. It means at Y axis there are "low" values (from ~ 0 - 0.09) and at X axis there aren't values from scope 0 - 255.
Any help?
dataset.setType(HistogramType.RELATIVE_FREQUENCY);
Can you try setting different options here and see if it helps? Also if you can show what channelHistogram field contains that may be helpful to debug.

JFreeChart - CategoryAxis step

I have a method for generating dataset:
private CategoryDataset createDataset(double[] arr,
String seriesName) {
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
for (int i = 0; i < arr.length; i++) {
dataset.addValue(arr[i], "mySeries", new Integer(i));
}
return dataset;
}
and create BarChart:
JFreeChart chart = ChartFactory.createBarChart(chartTitle,
xaxis, // domain axis label
yaxis, // range axis label
dataset, // data
orientation, // orientation
true, // include legend
true, // tooltips?
false // URLs?
);
Array of doubles hold histogram data, so there are 255 values.
When I display chart there are labels for
all values from 0 - 255 on x axis. I want display only labels for several indexes (for example: 0, 10, 20, 30). I saw that in RangeAxis there is setStandardTickUnits method. But in CategoryAxis:
CategoryAxis domainAxis = plot.getDomainAxis();
I didn't find this.
Any help?
You can try as follows,
NumberAxis vn = (NumberAxis) plot.getRangeAxis();
vn.setTickUnit(new NumberTickUnit(10d));
vn.setRange(0D, Math.ceil(factor * MAX_VALUE));
--that is you just need cast plot.getRangeAxis() to NumberAxis type.
I had same problem. I created new class implementing 'Comparable', and use it as last parameter in addValue(...). You can create something like
class MyCategory implements Comparable<MyCategory> {
Integer value;
String stValue;
MyCategory(int val) {
value = val;
stValue = val%10==0?""+val:"";}
public int compareTo(MyCategory key) { return value.compareTo(key.value); }
public String toString() { return stValue; }
}
And then instead of
dataset.addValue(arr[i], "mySeries", new Integer(i));
use
dataset.addValue(arr[i], "mySeries", new MyCategory(i));

Categories