Charts: Bars not showing bar chart

Created on 29 Oct 2016  ·  24Comments  ·  Source: danielgindi/Charts

Hi,

Ever since upgrading to 3.0, i am having trouble with the bars not showing in the bar chart.

One bar shows when the data has only one point. If i add more than one point then the bars donot show.
This is happening only when the xaxis has dates. if i change the data from dates to say integer then it works fine.
Please see the attached screenshots.

A sample of the data would be similar to this
{
"09/04/2012":"245",
"02/05/2013":"227",
"04/07/2013':"234",
"07/08/2015":"244",
"10/11/2016":"2254"
}

Thanks,
Bob

1

As seen below i dont see the bars at all? what seems to be causing this?
2

bug discussion enhancement ★★★

Most helpful comment

Not sure if this helps anyone, but I had the same problem and solved it by setting my bars to correct size relative to the range of the x-axis:

let data = BarChartData(dataSets: [dataSet])

let dataSetRange = dataSet.xMax - dataSet.xMin
let availableSpacePerBar = dataSetRange / Double(dataSet.entryCount)
data.barWidth = availableSpacePerBar * 0.8 // 80% of available space

chartView.data = data

All 24 comments

Any one has a solution for this?
It seems strange that the bars are missing in 3.0. Looks like i am either missing a call or setting something, it would be super helpful if there is a solution for this.

Thanks,
Bob

How do you set it up? Chart 3.0 has redesigned x axis, so lots of things changed. If you don't update your code, it might be missing. For now, please check ChartsDemo for different bar chart demos.

I will run the Demo charts again and see if i can reproduce the issue, but i believe the issue is similar to the other issue #1716 opened.

Let me get back to you once i make some changes and running the Charts Demo.

It seems certain x-values are causing issues.

Thanks,
Bob

I'm having the same problem. My X-axis correctly shows the date in format YYYY-MM-DD but the bars are invisible.

@liuxuan30 ,
here is what i basically tried ... I made some changes to the ChartsDemo in 3.0 and it is doing exactly the same thing...

I made the following changes. instead of X value being a double, i am adding the datetime since 1970 which is the double value for the dates.
changed the xaxis formatter to a dd/MM .

Also attaching the code for the BarChartViewController.m that way you could check it.

See the screenshot below.
simulator screen shot nov 1 2016 12 22 47 am

BarChartViewController.m.zip

Either i am missing something very simple or this is a bug.

Thanks,
Bob

Hi, I am not sure why this issue is closed, but like everyone who has described the symptoms here and in https://github.com/danielgindi/Charts/issues/1716, I am experiencing the same bug in our project. In short, the X-axis can't seem to handle large values such as time intervals, and it somehow messes up the rendering of the chart.

@sjuvvalapalem the original ChartsDemo works fine right? I don't know the context about your changes. In Chart 3.0, x values are always double. If you changed anything, make sure you change all related field. You screenshot is just missing the bars, so I think you could check drawDataSets in bar chart renderer for more details. It's easier to debug on your side.

BarChartViewController.m.zip
@liuxuan30 i have attached the changes i made in my reply earlier.
All i did was instead of double just added the Nstimeinterval for some dates and for some reason its not showing the bars.

I think this could be a bug. Please look at the attached zip document, you could easily figure out the changes i made and that should make sense.
Looking at the same issue for the other people, i suspect this could be a bug.
Any help on this is greatly appreciated as my project is being halted for this instead of getting pushed to the appstore.

Any solution to this would greatly help.

Thanks,
Bob

@liuxuan30 could you please make this issue Open? so that this gets more traction just like the others mentioned.

Thanks,
Bob

I m sorry that I'm busy with my work recently, so I can't take a look at this very quickly. Will try
NSTimeInterval is double I remember, so it should not impact..

@liuxuan30 yes, it is a double. With the formatter, the dates show up correctly. the values above the bars show correctly.

Everything is working but the bars are not showing.

If you are busy, Is there any one else who could look into this issue/bug?

Thanks,
Bob

alright, I did a quick check.
The x axis range is

(lldb) po max - min
34041601.0

When rendering, barRect width is too small:

▿ (30.7373051480045, 132.310035326087, 8.28906013339292e-06, 257.842777173913)
  ▿ origin : (30.7373051480045, 132.310035326087)
    - x : 30.7373051480045
    - y : 132.310035326087
  ▿ size : (8.28906013339292e-06, 257.842777173913)
    - width : 8.28906013339292e-06 //  <-- you won't see it
    - height : 257.842777173913

So you don't see it.
The reason is, the x val is too big, so in prepareBuffer(),

let barWidthHalf = barData.barWidth / 2.0 // barWidth is 0.9

then

let left = CGFloat(x - barWidthHalf)
let right = CGFloat(x + barWidthHalf)
barRect.size.width = right - left

it's trivial.

@danielgindi seems like we need to handlebarWidth to cope with big values? Or it's by design.

The x range is very large, but just a few bars, however we use a hard coded number to present the bar width, which causes trouble. I tried to "normalize" the barWidth, buggy.

The temporary workaround is to uses bigger day units, not seconds for x values. Or you just turn it into 1,2,3,4,.. and let the formatter to format. In your data, your x vals are over one year, even in days, it's 365 bars and the bar would be thin too.

Another way is to change barWidth that fit your value range. However, there is no clear shot how to find the right number yet.

Hi,
I have the exact same problem, but the issue seems to be closed without giving any solution ...
If I use a line chart, the chart is drawing correctly but if I chose vertical bar chart, no bar appears.
To me, that is NOT an enhancement, it's a bug.

Thanks

setting BarChartData.barWidth to huge value (~10 000) solved problem for me

I got around this issue by setting a border
chartDataSet.barBorderColor = UIColor.blue
chartDataSet.barBorderWidth = 30
Hope that helps

Setting barBorderWidth seems to fix the issue.

Any solution for this issue? Setting barBorderWidth seems to work but it doesnt really work the right way because if there is only one or 2 data points the lines are too thin (assuming you set it the barBorderWidth to 1). If set to a higher number then all the bars are joined and mingled together and doesnt look good.

Any work on this is greatly appreciated.

Work Like A Charm !

bars not displaying

My Analysis:
This is a bug ... Date in long data type has value 1542039314621, it means 12 November 2018 After formatted using SimpleDateFormat. But x Axis takes its long value first, that causing trouble. My solution is xHelper, instead input big value, xHelper doing index long data type implicitly using counter counter++, beside xValue hold big long value. and this code work like a charm

this is wrong code:

String[] month = new String[] {"Jan", "Feb", "Mar", "Aprl"};     
xAxis.setValueFormatter(new MyXAxisValueFormatter(month)); 

This is wrong code:

 xAxis.setValueFormatter(new IAxisValueFormatter() {
         @override
         public String getFormattedValue (float value, AxisBase axis){
              Date dates = new Date((long) value); //take your long value from BarEntry 
              SimpleDateFormat sdf = new SimpleDateFormat("dd/MM");
              return  sdf.format(dates);
              }
}

This is incorrect code:

for (int i = 0; i < xValues.length; i++)
Date date = new Date(xValues[i]);

this is wrong code :

List<Date> dates = new ArrayList<Date>();
for (int i = 0; i< xHelper.length; i++)
dates.add(new Date(xValues[i]));

this code work like a charm:

SimpleDateFormat sdf = new SimpleDateFormat("dd/MM"); // as you seen on the picture 
String[] xDates = new String[xHelper.length];
for (int m = 0; m < xHelper.length; m++) 
      xDates[m] = sdf.format(new Date(xValues[m]));

List<String> myDateList = new ArrayList<String>();
for (int n = 0; n < xHelper.length; n++)
      myDateList.add(xDates[n]);

//convert your ArrayList into array
String[] month = (String[]) myDateList.toArray(new String[xHelper.length]);

xAxis.setValueFormatter(new YourXAxisValueFormatter(month));

This is my full code and tell everything about xValue and xHelper.

public class MyDatabaseHelper {
long xValue
int xHelper, yValues;

//empty constructor
public MyDatabaseHelper(){
}

//constructor
public MyDatabaseHelper(long xValue, int yValues, int xHelper){
         this.xValue = xValue;
         this.yValue = yValue;
         this.xHelper = xHelper;
}

//Method
public long getxValue() {return xValues;}

public int getyValue() {return yValues;}

public int getxHelper() {return xHelper;}
}

next make this class and thanks to Phillip Jahoda

 public class MyXAxisValueFormatter implements IXAxisValueFormatter {
          private String[] mValues;`

          //constructor with array parameter
         public MyAxisValueFormatter(String[] values) {
                this.mValues = values;
          }

         @override
         public String getFormattedValue(float value, AxisBase axis) {
              return mValues[(int) value];
         }
}

finally make MainActivity class:

public class MainActivity extends AppCompatActivity {

EditText yInput;
Button buttonInsert;
FirebaseDatabase firebaseDatabase;
DatabaseReference reference;
BarChart barChart;
//this is xHelper as counter for indexing x values
int counter = 0;

@override
protected void onCreate (Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        yInput = (EditText) findViewById(R.id.editText);
        insertButton = (Button) findViewById(R.id.buttonInsert);
        firebaseDatabase = FirebaseDatabase.getInstance();
        reference = firebaseDatabase.getReference("ChartTable");
        insert();
  }
     public void insert() {
           buttonInsert.setOnClickListener(new View.OnClickListener() {
                   @override
                    public void onClick (View v)
                    String id = reference.push().getKey();
                    long x = new Date().getTime();  //this is big value
                    int y = yInput.getText().toString();

                    // when you click button this counter increase
                    //note: using this counter will make your app being crash on 5 step Granularity
                    //my granularity is setGranularity(5);
                    //this is my problem and i don't know why. so, i have to make the counter start from zero
                    //like this                
                    counter++
                    int c = counter - 1;

                    // input value into class
                    MyDatabaseHelper db = new MyDatabaseHelper(x, y, c);
                    //input method into Firebase Database
                    reference.child(id).setValue(db);
           });
     }

    @override
    protected void onStart {
    super.onStart();

                   reference.addValueEventListener(new ValueEventListener() {
                            @override
                            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

                                    int count = (int) dataSnapshot.getChildrenCount();
                                    long[] xValues = new long[count];
                                    int[] yValues = new int[count];
                                    int[] xHelper = new int[count];

                                    int index = 0;
                                    for (DataSnapshot myDataSnapshot : dataSnapshot.getChildren()){
                                    MyDatabaseHelper db = myDataSnapshot.getValue(MyDatabaseHelper.class);
                                    xValues[index] = db.getxValue();
                                    yValues[index] = db.getyValue();
                                    xHelper[index] = db.getxHelper();
                                    index++
                                   }

                                   ArrayList<BarEntry> barEntry = new ArrayList<BarEntry>();
                                   for (int i = 0; i < xHelper.length; i++)
                                         barEntry.add(new BarEntry(xHelper[i], yValues[i]));

                                   BarDataSet set1 = new BarDataSet(barEntry, "Project Progress");
                                   set1.setColors(ColorTemplate.VORDIPLOM_COLORS);
                                   set1.setDrawValues(false);                              

                                   ArrayList<IBarDataSet> dataSets =  new ArrayList<>();
                                   dataSets.add(set1);

                                   BarData data = new BarData(dataSets);

                                   XAxis xAxis = barChart.getXAxis();
                                   xAxis.setGranularity(5f);
                                   xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);

                                   // input xValues[] into Date using List
                                   SimpleDateFormat sdf = new SimpleDateFormat("dd/MM");
                                   String[] xDates = new String[count];
                                   for (int m =0; m < xValues.length; m++)
                                         xDates[m] = sdf.format(new Date(xValues[m]));

                                  List<String> xDatesList = new ArrayList<String>();
                                  for (int n = 0; n < xDates.length; n++)
                                         xDatesList.add(xDates[n]);

                                  // you cannot insert xDatesList directly into setValueFormatter
                                  //so convert ArrayList into array
                                  String[] month = (String[]) xDatesList.toArray(new String[count]);

                                 //finally
                                 xAxis.setValueFormatter(new MyXAxisValueFormatter(month));
                                //done
                                barChart.getAxisRight().setEnabled(false);
                                barChart.setDragEnabled(true);
                                barChart.setScaleEnabled(true);
                                barChart.setPinchZoom(true);
                                barChart.setDoubleTapToZoomEnabled(false);
                                barChart.setDrawGridBackground(false);
                                barChart.setDragEnabled(true);

                                barChart.setData(data);
                                barChart.invalidate();


                             }
                             @override
                             public void onCancelled(@NonNull DatabaseError databaseError){
                            }
                   });
    }
} 

Everything is done. And this is my Description:

I don't use this code:

String[] month = new String[] {"Jan", "Feb", "Mar", "Aprl"};     
xAxis.setValueFormatter(new MyXAxisValueFormatter(month)); 

because i need dynamic input and don't want write "jan", "feb" and so forth. my solution:
String[] month = (String[]) myDateList.toArray(new String[xHelper.length]);

myDateList.toArray allow you to take ArrayList and insert it into array.

And i don't use this code because -->

xAxis.setValueFormatter(new IXAxisValueFormatter {

         @override
         public String getFormattedValue(float value, AxisBase axis) {
              Date dates = new Date((long) value)
              SimpleDateFormat sdf = new SimpleDateFormat("dd/MM");
              return sdf.format(dates);
         }
}

because that value taken from x Axis that cause your Bars dissapear. my solution is xHelper like this:

ArrayList<BarEntry> barEntry = new ArrayList<BarEntry>();
for (int i=0; i<xHelper.length; i++)
    barEntry.add(new BarEnry(xHelper[i], yValues[i]));

the point is, xHelper must contain small value for indexing Date

And this is the secret:
you don't input Date using this --> String[] month = new String[]{...}; but myDateList

String[] month = (String[]) myDateList.toArray(new String[xHelper.length]);
xAxis.setValueFormatter(new YourXAxisValueFormatter(month));

@sjuvvalapalem @avitus did you find any solution for this.

It's been 2 years now since this bug was reported, and there's still not a fix?

can you file a PR to fix this? I originally marked it added this to To do in 4.0 Release

Not sure if this helps anyone, but I had the same problem and solved it by setting my bars to correct size relative to the range of the x-axis:

let data = BarChartData(dataSets: [dataSet])

let dataSetRange = dataSet.xMax - dataSet.xMin
let availableSpacePerBar = dataSetRange / Double(dataSet.entryCount)
data.barWidth = availableSpacePerBar * 0.8 // 80% of available space

chartView.data = data

setting BarChartData.barWidth to huge value (~10 000) solved problem for me

This one works better then https://github.com/danielgindi/Charts/issues/1742#issuecomment-519056482 when u have some missing values in between your data range, ie. non continuous and periodic data source.

If you have missing values in between,
Following the comment https://github.com/danielgindi/Charts/issues/1742#issuecomment-519056482
Screenshot 2020-05-16 at 12 52 11 PM

setting BarChartData.barWidth to huge value (~10 000) looks like
Screenshot 2020-05-16 at 12 52 40 PM

But both works great when u have all sufficient continuous values
IMG_81DD4290AE1B-1

I just lost 3 hours for this, so keeping an eye on it. Ended by using indexes.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

guoyutaog picture guoyutaog  ·  3Comments

heumn picture heumn  ·  3Comments

cilasgimenez picture cilasgimenez  ·  4Comments

Bharati555 picture Bharati555  ·  4Comments

Aungbandlab picture Aungbandlab  ·  4Comments