I am working on Pie charts using AChartEngine library. Here I want to disable chart values to show on charts, but only those whose content value is 0.If anyone known this please share to me.
Codings:
pchart=ChartFactory.getPieChartView(this,buildCategoryDataset("Daily Basis", values),renderer);
re.addView(pchart);
}
}
BuildCategory Renderer:
protected DefaultRenderer buildCategoryRenderer(int[] colors) {
DefaultRenderer renderer = new DefaultRenderer();
renderer.setLabelsTextSize(10);
renderer.setLegendTextSize(15);
renderer.setShowLegend(true);
renderer.setExternalZoomEnabled(true);
renderer.setZoomEnabled(true);
renderer.setZoomButtonsVisible(true);
renderer.setShowAxes(true);
// renderer.setMargins(new int[] { 20, 30, 15, 0 });
for (int color : colors) {
SimpleSeriesRenderer r = new SimpleSeriesRenderer();
r.setColor(color);
renderer.addSeriesRenderer(r);
}
return renderer;
}
DataSet Here:
protected CategorySeries buildCategoryDataset(String title, double[] values) {
CategorySeries series = new CategorySeries(title);
int k = 0,year;
String str_year;
str_year=String.valueOf(Math.round(values[0]));
Log.i("Invent","Year"+str_year);
year=Integer.parseInt(str_year);
Log.i("Invent","YearInt"+year);
if(flag_val==1)
{
for(k=0;k<tot_yearno-1;k++)
{
if(values[k]==0)
{
series.add(0.0); /// Here some settings for display null value.But **here i Want to display nothing Only.**
}
else
series.add("" + year_first++, values[k]);
}
}
if(flag_val==0)
{
for (double value : values) {
if(value==0)
{
series.add("" + ++k, 0.0);
}
else
series.add("Day " + ++k, value);
}
}
return series;
}
}
What you are doing here:
if(values[k]==0)
{
series.add(0.0); /// Here some settings for display null value.But **here i Want to display nothing Only.**
}
else
series.add("" + year_first++, values[k]);
}
You should do it like this:
if(values[k] != 0) //or possibly (values[k] >= 0) since you cannot show negatives either
{
series.add("" + year_first++, values[k]);
}
EDIT: Try this then:
if(values[k]==0)
{
series.add("" + year_first++, new Double(0.0));
}
else
{
series.add("" + year_first++, new Double(values[k]));
}
If you do not wish to show 0 values, just don't add them to the dataset.
Look at the createDataSet in the PieChartView for an example - there they add the values with the label.
private staticPieDataSet createDataSet(){
DefaultPieDataset dataset = new DefaultPieDataset();
dataset.setValue("One", new Double(43.2));
}
Now when you add your own values (I am not sure how you do it, but I pass them through the bundle datatype and then extract them for the following method), you can just not add based on value:
private staticPieDataSet createDataSet(Double[] values, String[] labels){
DefaultPieDataset dataset = new DefaultPieDataset();
for(int i = 0; i < values.length; i++){
if (value[i] > 0)
dataset.setValue(labels[i], values[i]);
}
}
PS!!! I wouldn't recommend this by the way - your users may become confused as to why some data shows up and others do not - rather put the value in brackets with the label so they can see this value is 0.
Do it something like this way, before showing the Chart View as I have done for TimeChart
for(int i=0;i<selectedCollectionY.size();i++)
{
if(selectedCollectionY.get(i).equalsIgnoreCase("0"))
{
selectedCollectionY.remove(i);
selectedCollectionX.remove(i);
}
}
View mView = null;
mView = ChartFactory.getTimeChartView(GraphActivity.this, Line_Chart
.getLineDemoDataset(mSpinner.getSelectedItem().toString(),
selectedCollectionX, selectedCollectionY), Line_Chart
.getLineDemoRenderer(mSpinner.getSelectedItem().toString()),
"MMM dd");
mView.setLayoutParams(new LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
mLinearLayout.removeAllViews();
mLinearLayout.addView(mView);
Related
I've used the BarChart provided by MPAndroidChart library to display a bar graph.
When there is data for more than one values on the x-axis (in this case the date), the output is shown as expected. However, when there is data for only a single date, for some reason that date is displayed twice on the x-axis.
I would like to prevent one of the values from being displayed. Below is the code that is displayed the results in the image.
private void showBarGraph(List<Object> response) {
barChart.setNoDataText(getResources().getString(R.string.sorry_data_not_available));
barChart.clear();
if(response.size()>0) {
int highestValue = response != null && response.size() > 0 ? response.size() : 0;
barChart.getAxisLeft().setAxisMaximum(highestValue);
barChart.getAxisLeft().setAxisMinimum(0);
barChart.animateY(1000);
List<BarEntry> entries = new ArrayList<>();
List<String> xAxisValues = new ArrayList<>();
if (response != null) {
for (int i = 0; i < respones.size(); i++) {
entries.add(new BarEntry(i, response.get(i).getCount(), ContextCompat.getColor(getActivity(), R.color.graph)));
xAxisValues.add(response.get(i).getTimekey());
}
barChart.getAxisLeft().setLabelCount(highestValue > 10 ? 10 : highestValue, false);
barChart.getXAxis().setLabelCount(response.size() <= 12 ? response.size() : 12, false);
if (response.size() >= 4) {
barChart.getXAxis().setLabelRotationAngle(-45);
} else {
barChart.getXAxis().setLabelRotationAngle(0);
}
}
IndexAxisValueFormatter xAxisValueFormatter = new IndexAxisValueFormatter(xAxisValues);
barChart.getXAxis().setValueFormatter(xAxisValueFormatter);
BarXYMarkerView xymv = new BarXYMarkerView(getActivity(), xAxisValueFormatter);
// Set the marker to the chart
xymv.setChartView(barChart);
barChart.setMarker(xymv);
BarDataSet set = new BarDataSet(entries, null);
set.setDrawValues(false);
List<Integer> graphColors = new ArrayList<>();
graphColors.add(ContextCompat.getColor(getActivity(), R.color.graph));
set.setColors(graphColors);
BarData data = new BarData(set);
barChart.setData(data);
barChart.invalidate();
}
}
The code is good for data with entries on multiple dates. Can someone guide me on how I can prevent the duplicate date value when there is data for only one date.
I am using PhilJay/MPAndroidChart library in my app and I'd like to know if 2 things are possible:
to show the last 14 days and then scroll for previous days?
Can the dates (currently on the top of the graph) be moved to the bottom, along the x axis?
Here is the current pic from the app and where i want to move date
my method:
private void populateGraph(Cursor data) {
ArrayList<Entry> cravingsPoints = new ArrayList<Entry>();
ArrayList<Entry> severityPoints = new ArrayList<Entry>();
ArrayList<String> dates = new ArrayList<String>();
int index = 0;
for (int i = 0; i < data.getCount(); i++) {
if (i == 0) {
// if orientation changed we need to start from the first one again
data.moveToFirst();
} else {
data.moveToNext();
}
try {
String date = data.getString(data.getColumnIndex(SmokeFreeContentProvider.DIARY_DATE));
int cravings = data.getInt(data.getColumnIndex(SmokeFreeContentProvider.DIARY_CRAVINGS_COUNT));
int severity = data.getInt(data.getColumnIndex(SmokeFreeContentProvider.DIARY_CRAVINGS_SEVERITY));
DateTime diaryEntry = DateTimeFormat.forPattern("yyyyMMdd").parseDateTime(date);
String entryLabel = diaryEntry.toString("dd MMM");
cravingsPoints.add(new Entry(cravings, index));
severityPoints.add(new Entry(severity, index));
dates.add(entryLabel);
index++;
} catch (Exception e) {
Log.e("SmokeFreeCravingsGraph", e.getMessage(), e);
}
}
LineDataSet cravingsLineData = new LineDataSet(cravingsPoints, getString(R.string.cravings));
LineDataSet severityLineData = new LineDataSet(severityPoints, getString(R.string.severity));
cravingsLineData.setCircleSize(4f);
cravingsLineData.setLineWidth(6f);
cravingsLineData.setColor(getResources().getColor(R.color.green));
severityLineData.setCircleSize(4f);
severityLineData.setLineWidth(6f);
severityLineData.setColor(getResources().getColor(android.R.color.holo_blue_light));
ArrayList<LineDataSet> dataSets = new ArrayList<LineDataSet>();
dataSets.add(cravingsLineData);
dataSets.add(severityLineData);
Paint infoPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
infoPaint.setTextAlign(Paint.Align.CENTER);
infoPaint.setTextSize(com.github.mikephil.charting.utils.Utils.convertDpToPixel(14f));
infoPaint.setColor(getResources().getColor(R.color.dark_grey));
mChart.setDrawGridBackground(false);
mChart.setDrawYValues(false);
mChart.setDescription("");
mChart.setStartAtZero(true);
mChart.setPaint(infoPaint, Chart.PAINT_INFO);
mChart.setNoDataText(getString(R.string.no_cravings_info));
mChart.setNoDataTextDescription(getString(R.string.no_cravings_full_info));
mChart.setData(new LineData(dates, dataSets));
}
Yes, check the documentation: Modifying the Viewport
Take a look at the setVisibleXRange(float xRange) method.
Yes, check the documentation: XAxis
Take a look at the xAxis.setPosition(...) method.
I'm using the MPAndroidChart and am really enjoying it.
A 'little' need I have is that I can put null values to the 'entrys'. I'm monitoring the apache conections on servers of my system, and I would to see if they is down (where I put the null value) or if they just no conections (0).
I tried, but the Entry class don't accept 'null' as value showing the message: 'The constructor Entry(null, int) is undefined'
Thanks!
A possible solution for you could be to check weather the object you received is null, or not. If the object is null, you don't even create an Entry object instead of just setting it's value to null.
Example:
// array that contains the information you want to display
ConnectionHolder[] connectionHolders = ...;
ArrayList<Entry> entries = new ArrayList<Entry>();
int cnt = 0;
for(ConnectionHolder ch : connectionHolders) {
if(ch != null) entries.add(new Entry(ch.getNrOfConnections(), cnt));
else {
// do nothing
}
cnt++; // always increment
}
This would create e.g. a LineChart where no circles are drawn on indices where the ConnectionHolder object was null.
For a future release of the library, I will try to add the feature so that null values are supported.
My solution is to draw another DataSet with TRANSPARENT (or arbitrary) color:
- chart with fixed number of X values
- Y values are updated periodically
- boolean flag indicate transparent part (or another color)
private static final int SERIES_SIZE = 360;
int xIndex = -1;
float xIndexVal;
private LineChart chart;
private boolean currentFlag;
public void createChart(LineDataSet dataSet) {
LineData chartData = new LineData();
prepareDataSet(dataSet);
chartData.addDataSet(dataSet);
for (int i = 0; i < SERIES_SIZE; i++) {
chartData.addXValue("" /*+ i*/);
}
chart.setData(chartData);
}
private void prepareDataSet(LineDataSet dataSet, YAxis axis, int color) {
// configure set
}
public void update(Float val, boolean flag) {
List<ILineDataSet> dsl = chart.getData().getDataSets();
Log.d("chart", String.format("%s --- %d sets, index %d", descr, dsl.size(), xIndex));
if (xIndex == SERIES_SIZE - 1) {
// remove all entries at X index 0
for (int i = 0; i < chart.getData().getDataSetCount(); i++) {
Entry entry0 = chart.getData().getDataSetByIndex(i).getEntryForIndex(0);
if (entry0 != null && entry0.getXIndex() == 0) {
chart.getData().removeEntry(entry0, i);
Log.d("chart", String.format("entry 0 removed from dataset %d, %d entries in the set", i, chart.getData().getDataSetByIndex(i).getEntryCount()));
}
else {
Log.d("chart", String.format("all %d entries in the set kept", chart.getData().getDataSetByIndex(i).getEntryCount()));
}
}
// remove empty set, if any
for (Iterator<ILineDataSet> mit = dsl.iterator(); mit.hasNext(); ) {
if (mit.next().getEntryCount() == 0) {
mit.remove();
Log.d("chart", String.format("set removed, %d sets", dsl.size()));
}
}
// move all entries by -1
for (ILineDataSet ds : dsl) {
for (Entry entry : ((LineDataSet)ds).getYVals()) {
entry.setXIndex(entry.getXIndex() - 1);
}
}
}
else {
xIndex++;
}
if (currentFlag != flag) {
currentFlag = !currentFlag;
LineDataSet set = new LineDataSet(null, "");
prepareDataSet(set, chart.getAxisLeft(), currentFlag ? Color.TRANSPARENT : Color.BLUE);
chart.getData().addDataSet(set);
if (xIndex != 0) {
chart.getData().addEntry(new Entry(xIndexVal, xIndex - 1), dsl.size() - 1);
}
}
xIndexVal = val;
chart.getData().addEntry(new Entry(val, xIndex), dsl.size() - 1);
chart.notifyDataSetChanged();
chart.invalidate();
}
I am very much new to achartengine (to programming in Java/Android in general), but I need it to display two pie graphs in one activity.
I've got it to work by calling the following code, but now I'd like to know how to display the data I have set previously in the activity. Each chart has to hold its own data (its own array of strings)
My onCreate of the main activity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.rezultati);
...
db.open();
//here I get the values, which are then stored in test1, test2 and test3 for graph 1
//I also get the values for graph 2, which are called test4, test5 and test6
db.close();
//Now I'd like to assign those 'test' values to the pie chart
Here is my PieGraph class which is in the same .java file as my activity
public class PieGraph{
public GraphicalView getView(Context context) {
int[] values; //I'd like to place my values for the first graph here, display the 1st graph and then do the same with the second
CategorySeries series = new CategorySeries("Pie Graph");
//I also need to replace my 'series' to "test1", "test2" and "test3" for the 1st graph
//and "test4", "test5" and "test6 for the 2nd graph
int[] colors = new int[] { Color.BLUE, Color.GREEN, Color.RED };
DefaultRenderer renderer = new DefaultRenderer();
for (int color : colors) {
SimpleSeriesRenderer r = new SimpleSeriesRenderer();
r.setColor(color);
renderer.addSeriesRenderer(r);
}
renderer.setZoomButtonsVisible(false);
renderer.setPanEnabled(false);
renderer.setDisplayValues(true);
renderer.setLabelsTextSize(35);
renderer.setShowLegend(false);
return ChartFactory.getPieChartView(context, series, renderer);
}
}
I now need a method which will get the given 'test' values, put them into the graph and output both graphs in the layout (I've already added two LinearLayouts for the graphs in my .xml).
You can do it by using something like below. But make sure "arrProducts" which is array of Custom objects is filled up before this method is called. Custom object class has get and set methods for "uniquecalls" and "specialty". I've converted uniqueCalls which were string, into the boolean values.
ArrayList<CustomObjectClass> arrProducts;
public void PieChart() {
try {
String uniqueCalls;
String specialtyName;
CategorySeries series = new CategorySeries(" Pie Chart");
for (int i = 0; i < arrProducts.size(); i++) {
uniqueCalls = arrProducts.get(i).getUniqueCalls();
specialtyName = arrProducts.get(i).getSpecialtyName();
double db = Double.parseDouble(uniqueCalls);
Log.v("******", "String : " + uniqueCalls + " Double: " + db);
series.add(specialtyName, db);
}
// Color of each Pie Chart Sections
int[] colors = { Color.rgb(169, 169, 169), Color.rgb(255, 165, 0),
Color.rgb(128, 128, 128), Color.rgb(255, 160, 122),
R.color.BabyBlue,
R.color.BashfulPink, R.color.BasketBallOrange,
R.color.Chocolate,R.color.Khaki, R.color.LimeGreen, R.color.Maroon, };
// Instantiating a renderer for the Pie Chart
DefaultRenderer defaultRenderer = new DefaultRenderer();
for (int i = 0; i < arrProducts.size(); i++) {
specialtyName = arrProducts.get(i).getSpecialtyName();
SimpleSeriesRenderer seriesRenderer = new SimpleSeriesRenderer();
seriesRenderer.setColor(colors[i]);
seriesRenderer.setDisplayChartValues(true);
// Adding a renderer for a slice
defaultRenderer.addSeriesRenderer(seriesRenderer);
}
// defaultRenderer.setChartTitle("Product Wise Calling");
defaultRenderer.setChartTitleTextSize(20);
defaultRenderer.setZoomButtonsVisible(true);
// defaultRenderer.setBackgroundColor(Color.GRAY);
defaultRenderer.setLabelsColor(Color.BLACK);
defaultRenderer.setDisplayValues(true);
defaultRenderer.setClickEnabled(true);
defaultRenderer.setSelectableBuffer(10);
LinearLayout chartContainer = (LinearLayout) findViewById(R.id.chart_container);
// Creating a Line Chart
mChartView = ChartFactory.getPieChartView(getBaseContext(), series,
defaultRenderer);
// Adding the Line Chart to the LinearLayout
chartContainer.addView(mChartView);
mChartView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
SeriesSelection seriesSelection = mChartView
.getCurrentSeriesAndPoint();
if (seriesSelection == null) {
Toast.makeText(
ChartProductCallingSpecialtyWiseActivity.this,
"Please Select the Pie to see the value",
Toast.LENGTH_SHORT).show();
} else {
// display information of the clicked point
Toast.makeText(
ChartProductCallingSpecialtyWiseActivity.this,
" Pie Value : " + seriesSelection.getXValue(),
Toast.LENGTH_SHORT).show();
}
}
});
// ANOTHER INSTANCE EXAMPLE OF PLOTTING THE PIE CHART
// Creating an intent to plot Pie chart using dataset and
// multipleRenderer
// Intent intent = ChartFactory.getPieChartIntent(getBaseContext(),
// series, defaultRenderer, "Pie Chart");
//
// // Start Activity
// startActivity(intent);
} catch (Exception e) {
}
}
I have a lineGraph with float values on both x-axis and y-axis? My question is that how can i set String values on x-axis like date or name of months.I am using GraphView-3.0.jar library.my code is
values_list.add(1.0);
values_list.add(5.0);
values_list.add(9.0);
values_list.add(12.0);
values_list.add(17.0);
values_list.add(1.0);
values_list.add(13.0);
values_list.add(23.0);
graphData = new GraphViewData[(values_list.size())];
double price_copy = 0;
for (int i = 0; i < values_list.size(); i++) {
price_copy = values_list.get(i);
graphData[i] = new GraphViewData(i, price_copy);
}
GraphView graphView;
graphView = new LineGraphView(this // context
, "" );// graphView.addSeries(exampleSeries);// data
graphView.addSeries(new GraphViewSeries("values",
new GraphViewStyle(Color.rgb(00, 00, 128), 3),
graphData));
graphView.setShowLegend(true);
// set view port, start=2, size=40
graphView.setViewPort(0, 10);
graphView.setScalable(true);
graphView.setScrollable(true);
LinearLayout layout = (LinearLayout) findViewById(R.id.LNL_CHART);
layout.addView(graphView);
Also i have no idea about AchartEngine,thanks in advance.
Use achart engine library. you can search for that on google. it helped me.Thanks
Just use the label formatter. You could store your x-labels as string in an array.
For example:
final String[] xLabels = new String[] {
"foo", "bar", "third", "bla", "more"
};
GraphView graphView = new LineGraphView(this, "example") {
#Override
protected String formatLabel(double value, boolean isValueX) {
if (isValueX) {
return xLabels[(int) value];
} else {
// return y label as number
return super.formatLabel(value, isValueX); // let the y-value be normal-formatted
}
}
};