Box and whisper not plotting the lines for some values
Out of 5 lines I see only one sometimes. Please tell me the scenario where I get the far or low triangles
DefaultBoxAndWhiskerCategoryDataset dataset = new DefaultBoxAndWhiskerCategoryDataset();
List<Double> values = new ArrayList();
values.add(14);
values.add(14);
values.add(14);
values.add(14);
dataset.add(values, "","");
BoxAndWhiskerRenderer r = new BoxAndWhiskerRenderer();
CategoryPlot plot = new CategoryPlot(dataset, new CategoryAxis("x"),
new NumberAxis("y"), r);
JFreeChart chart = new JFreeChart(plot);
Mean is same as q1 so it's not coming
Related
Currently I'm working on charts and want to achieve an output.
I wanted to achieve two things.
To display candle stick chart of stocks data. [done]
To display the stock split log above or below the candle. [pending]
I'm using JFreeChart SDK to build the charts.
I'm using OHLCDataItem[] to build data for daily high/low etc of stock. unfortunately jfreechart does not have any extension of OHLCDataItem to show additional information (logo + text metadata) on the candle.
Sample code:
TimeSeries timeSeriesDailyMovingAverage = new TimeSeries("day moving average");
List<OHLCDataItem> dataItems = new ArrayList<OHLCDataItem>(); //to collect High low close prices
OHLCDataItem item = new OHLCDataItem(date, open, high, low, adjClose, volume);//this code is in loop with do that more data can be added for each day
dataItems.add(item);
OHLCDataItem[] data = dataItems.toArray(new OHLCDataItem[dataItems.size()]);
OHLCDataset dataset = new DefaultOHLCDataset(symbol, data);
//now initializing the candleStickRanderer and setting its properties series strock + paint
CandlestickRenderer CandleStickRenderer = new CandlestickRenderer();
XYLineAndShapeRenderer LineRenderer = new XYLineAndShapeRenderer(true, false);
HighLowRenderer OHLCRenderer = new HighLowRenderer();
DateAxis domainAxis = new DateAxis();
NumberAxis rangeAxis = new NumberAxis();
rangeAxis.setStandardTickUnits(NumberAxis.createStandardTickUnits());
XYPlot plot = new XYPlot(dataset, domainAxis, rangeAxis, LineRenderer);//set other properties
JFreeChart chart = new JFreeChart(info, new Font("SansSerif", Font.PLAIN, 15), plot, false);
ChartPanel chartPanel = new ChartPanel(chart);
JPanel panel = new JPanel(new BorderLayout());
panel.add(chartPanel, BorderLayout.CENTER);
getContentPane().add(panel);
XYPlot xyplot = (XYPlot) chart.getPlot();
xyplot.setRenderer(CandleStickRenderer);
This is some rough code which is working fine. I'm getting the desired out of Candle chart.
current output of candle stick
But I cannot figure out how can I add text/logo on XYPlot based on dataset.
What I want to achieve is that, add text/or shape containing text information at the bottom/top of a particular candle.
It would be a great help if someone can guide me how I can do it based on the dataset.
The desired output is like this chart.
desired output
Or
desired output
Is there a way to wrap plot label for Category axis?
I'm facing a problem where these titles merge between the plots. It would be best if they would wrap at least once. Is it possible?
The titles are dynamic.
Here's the classes I use to construct it.
var renderer = new LineAndShapeRenderer();
...
var yAxis = new NumberAxis();
...
var xAxis = new CategoryAxis(title);
...
CategoryPlot plot = new CategoryPlot(dataset, xAxis, yAxis, renderer);
...
var combinedPlot = new CombinedRangeCategoryPlot();
combinedPlot.add(plot, weight);
...
I'm using version 1.0.19 of JFreeChart since newer versions produce some visual artifacts.
I am implementing an application which retrieves CSV data from COVID-19 info web.
I have made a parser which gets the cases per day of an specific place (Canary Island).
String url = "https://cnecovid.isciii.es/covid19/resources/datos_ccaas.csv";
String[] contents = HTTPFileDownloader.downloadFromURL(url).split("\n");
for(String i : contents) {
if(isCanaryIslandData(i)) {
String[] line = i.split(",");
String[] date = line[1].split("-"); // "YYYY-MM-DD"
int cases = Integer.parseInt(line[2]);
casesPerDay.add(cases);
}
}
Now I want to make a chart displaying the data. Something like this:
Currently I am storing the values in an ArrayList (just for testing). I know I will need to store the date and the number of cases, but I don't know which type of dataset should I use.
I want to make a line and a bar chart. I have managed to do it:
But as I have said, I want to find a way to display the dates as the x labels as shown in the example.
I tried with a CategoryDataset, but that prints every single x label so it won't be readable at all. I know XYSeries can do the trick as shown before, but I don't know how to insert a string as label instead of an integer.
Hope I explained it well.
I managed to do it using TimeSeriesCollection
TimeSeries series = new TimeSeries("Cases per Day");
String url = "https://cnecovid.isciii.es/covid19/resources/datos_ccaas.csv";
String[] contents = HTTPFileDownloader.downloadFromURL(url).split("\n");
for(String i : contents) {
if(isCanaryIslandData(i)) {
String[] line = i.split(",");
String[] date = line[1].split("-");
int year = Integer.parseInt(date[0]);
int month = Integer.parseInt(date[1]);
int day = Integer.parseInt(date[2]);
int cases = Integer.parseInt(line[2]);
series.add(new Day(day, month, year), cases);
}
}
Then on the chart class:
TimeSeriesCollection dataset = new TimeSeriesCollection();
dataset.addSeries(series);
JFreeChart chart = ChartFactory.createXYLineChart(
"Line Chart",
"x",
"y",
dataset,
PlotOrientation.VERTICAL,
true,
true,
false);
ChartPanel chartPanel = new ChartPanel(chart);
chartPanel.setMouseWheelEnabled(true);
chartPanel.setPreferredSize(new java.awt.Dimension(560,367));
XYPlot plot = (XYPlot) chart.getPlot();
DateAxis dateAxis = new DateAxis();
dateAxis.setDateFormatOverride(new SimpleDateFormat("dd-MM-yyyy"));
plot.setDomainAxis(dateAxis);
And output:
I don't know if it's the best solution, but it does the work.
I have created one graph which shows strings at x axis and dollars at y axis. I am able to see the values on graph but my data is too much to show on graph.
Graph is scrollable so I want to show minimun number of values on bar like below graph.
But now I am getting too much bars in graph like this:
This is my code:
public void setGraph() {
if (sessionData.getString("graphType", "").equals("d") || sessionData.getString("graphType", "").equals("m"))
{
int index = 0;
String[] dates = new String[totalOrdersList.size()];
mChart.setDrawBarShadow(false);
mChart.setDrawValueAboveBar(false);
mChart.getDescription().setEnabled(false);
mChart.setBackgroundColor(ContextCompat.getColor(getActivity(), R.color.lightGrey));
// mChart.setScaleEnabled(false);
// if more than 60 entries are displayed in the chart, no values will be
// drawn
mChart.setMaxVisibleValueCount(60);
// scaling can now only be done on x- and y-axis separately
mChart.setPinchZoom(false);
mChart.setDrawGridBackground(false);
// mChart.setDrawYLabels(false);
IndexAxisValueFormatter xAxisFormatter = new IndexAxisValueFormatter(dates);
XAxis xAxis = mChart.getXAxis();
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setDrawGridLines(false);
xAxis.setLabelCount(3);
xAxis.setValueFormatter(xAxisFormatter);
xAxis.setGranularity(1f);
com.github.mikephil.charting.formatter.IAxisValueFormatter custom = new MyAxisValueFormatter();
YAxis leftAxis = mChart.getAxisLeft();
leftAxis.setLabelCount(8, false);
leftAxis.setValueFormatter(custom);
leftAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);
leftAxis.setSpaceTop(15f);
leftAxis.setAxisMinimum(0f); // this replaces setStartAtZero(true)
YAxis rightAxis = mChart.getAxisRight();
rightAxis.setDrawGridLines(false);
rightAxis.setLabelCount(8, false);
rightAxis.setValueFormatter(custom);
rightAxis.setSpaceTop(15f);
rightAxis.setAxisMinimum(0f);
rightAxis.setEnabled(false);
// this replaces setStartAtZero(true)
Legend l = mChart.getLegend();
l.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);
l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.LEFT);
l.setOrientation(Legend.LegendOrientation.HORIZONTAL);
l.setDrawInside(false);
l.setForm(Legend.LegendForm.SQUARE);
l.setFormSize(9f);
l.setTextSize(11f);
l.setXEntrySpace(4f);
ArrayList<BarEntry> barEntries = new ArrayList<>();
for (Order o : totalOrdersList) {
dates[index] = o.getDate();
barEntries.add(new BarEntry(index, Float.parseFloat(o.getAmount())));
index++;
}
BarDataSet set1 = new BarDataSet(barEntries, "Months");
set1.setValues(barEntries);
set1.setColor(ContextCompat.getColor(getActivity(), R.color.orange));
ArrayList<IBarDataSet> dataSets = new ArrayList<IBarDataSet>();
dataSets.add(set1);
BarData data = new BarData(dataSets);
data.setValueTextSize(10f);
data.setBarWidth(0.9f);
mChart.setData(data);
mChart.animateXY(3000, 3000);
}
Please help.. Thank you..
I have a Barchart with 4 bars which are grouped into 2 groups using MPAndroidChart library.
This works so far. Now i want to display a title above each group. This is my current output (as you can see, the titles are not showed above each group).
My code:
_overviewBarChart.setPinchZoom(false);
_overviewBarChart.getDescription().setEnabled(false);
_overviewBarChart.setDrawValueAboveBar(true);
_overviewBarChart.getXAxis().setCenterAxisLabels(true);
_overviewBarChart.getXAxis().setAxisMinimum(0);
_overviewBarChart.getXAxis().setDrawGridLines(false);
private void updateOverviewBarChart() {
//Init calorie needs bars
BarEntry todayCalorieNeedsBarEntry = new BarEntry(0, _calorieEntry.getTarget());
BarEntry yesterdayCalorieNeedsBarEntry = new BarEntry(0, 0);
if (_yesterdayCalorieEntry != null)
yesterdayCalorieNeedsBarEntry = new BarEntry(0, _yesterdayCalorieEntry.getTarget());
ArrayList<BarEntry> calorieNeedsBarEntries = new ArrayList<>();
calorieNeedsBarEntries.add(todayCalorieNeedsBarEntry);
calorieNeedsBarEntries.add(yesterdayCalorieNeedsBarEntry);
//Init consumed calories bars
BarEntry todayConsumedCaloriesBarEntry = new BarEntry(1, _calorieEntry.getConsumed());
BarEntry yesterdayConsumedCaloriesBarEntry = new BarEntry(1, 0);
if (_yesterdayCalorieEntry != null)
yesterdayConsumedCaloriesBarEntry = new BarEntry(1, _yesterdayCalorieEntry.getConsumed());
ArrayList<BarEntry> consumedCaloriesBarEntries = new ArrayList<>();
consumedCaloriesBarEntries.add(todayConsumedCaloriesBarEntry);
consumedCaloriesBarEntries.add(yesterdayConsumedCaloriesBarEntry);
//Init BarDataSets
BarDataSet calorieNeedsBarDataSet = new BarDataSet(calorieNeedsBarEntries, getString(R.string.fragment_main_calorieneeds));
calorieNeedsBarDataSet.setColor(Color.parseColor("#26A69A"));
BarDataSet consumedCaloriesBarDataSet = new BarDataSet(consumedCaloriesBarEntries, getString(R.string.fragment_main_consumed));
consumedCaloriesBarDataSet.setColor(Color.parseColor("#E53935"));
//Init BarData, group BarEntrys, set group titles
BarData barData = new BarData(calorieNeedsBarDataSet, consumedCaloriesBarDataSet);
barData.setValueTextSize(14);
barData.setBarWidth(0.2f);
barData.groupBars(0, 0.15f, 0.1f);
ArrayList<String> groupTitles = new ArrayList<String>();
groupTitles.add(getString(R.string.fragment_main_today));
groupTitles.add(getString(R.string.fragment_main_yesterday));
_overviewBarChart.getXAxis().setValueFormatter(new IndexAxisValueFormatter(groupTitles));// new BarChartStringFormatter(groupTitles));
//Set data, redraw BarChart
_overviewBarChart.setData(barData);
_overviewBarChart.invalidate();
}
Can you see what i'm doing wrong?
Finally i found the solution for my problem.
First you have to add this two lines of code (note: The parameters can vary for your requirements):
_overviewBarChart.getXAxis().setGranularity(1f);
_overviewBarChart.getXAxis().setAxisMaximum(2);
My mistake was that the default XAxis is to finely granulated (0.1, 0.2, 0.3 ...). So IndexAxisValueFormatter applies the group title to each XAxis step. setGranularity resolves this. Finally setAxisMaximum is used to restrict the amount of steps on the XAxis (previous was 3 so the title showed 3 times).
And then change...
barData.groupBars(0, 0.15f, 0.1f);
to this (note: The parameters can vary for your requirements)..
barData.groupBars(0, 0.45f, 0.1f);
Result: