Charts: 条形图未显示

创建于 2016-10-29  ·  24评论  ·  资料来源: danielgindi/Charts

你好,

自从升级到3.0之后,我一直在遇到条形图中没有显示的条形的麻烦。

一栏显示数据何时只有一点。 如果我添加多个点,则条形图不会显示。
仅当xaxis有日期时才会发生这种情况。 如果我将日期中的数据更改为整数,则可以正常工作。
请参阅所附的屏幕截图。

数据样本将与此类似
{
“ 09/04/2012”:“ 245”,
“ 02/05/2013”​​:“ 227”,
“ 04/07/2013':” 234“,
“ 07/08/2015”:“ 244”,
“ 2016年10月11日”:“ 2254”
}

谢谢,
鲍勃

1

如下所示,我根本看不到酒吧吗? 似乎是什么原因造成的?
2

bug discussion enhancement ★★★

最有用的评论

不确定是否对任何人有帮助,但是我遇到了同样的问题,并通过将条形图设置为相对于x轴范围的正确大小来解决了这个问题:

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

所有24条评论

有人对此有解决方案吗?
3.0中缺少这些条似乎很奇怪。 看起来我或者错过了电话或正在设置某些东西,如果有解决方案,这将是非常有帮助的。

谢谢,
鲍勃

您如何设置? Chart 3.0重新设计了x轴,因此发生了很多变化。 如果您不更新代码,则可能会丢失。 现在,请查看ChartsDemo以获得不同的条形图演示。

我将再次运行演示图表,看看是否可以重现该问题,但我认为该问题与打开的其他问题#1716相似。

在我进行了一些更改并运行Charts Demo后,请立即与您联系。

似乎某些x值引起了问题。

谢谢,
鲍勃

我有同样的问题。 我的X轴正确显示了日期,格式为YYYY-MM-DD,但条形图不可见。

@ liuxuan30
这是我基本上尝试过的...我在3.0中对ChartsDemo进行了一些更改,并且它所做的完全相同...

我进行了以下更改。 而不是X值是双精度值,我要添加自1970年以来的datetime,它是日期的双精度值。
将xaxis格式化程序更改为dd / MM。

还要以这种方式附加BarChartViewController.m的代码。

请参见下面的屏幕截图。
simulator screen shot nov 1 2016 12 22 47 am

BarChartViewController.m.zip

我错过了一些非常简单的东西,或者这是一个错误。

谢谢,
鲍勃

嗨,我不确定为什么这个问题已经解决,但是像在这里和https://github.com/danielgindi/Charts/issues/1716中描述症状的每个人一样,我在项目中也遇到了相同的错误。 简而言之,X轴似乎无法处理较大的值(例如时间间隔),并且以某种方式使图表的显示变得混乱。

@sjuvvalapalem原始ChartsDemo可以正常工作吗? 我不知道您所做更改的背景。 在图表3.0中,x值始终为两倍。 如果您更改了任何内容,请确保更改所有相关字段。 您的屏幕截图只是缺少条形图,因此我认为您可以在条形图渲染器中查看drawDataSets以获得更多详细信息。 在您这边进行调试更容易。

BarChartViewController.m.zip
@ liuxuan30我已附上我之前在回复中所做的更改。
我所做的只是代替了Double,只是添加了Nstimeinterval某些日期,并且由于某种原因未显示条形图。

我认为这可能是一个错误。 请查看随附的zip文档,您可以轻松找出我所做的更改,这应该是有道理的。
在为其他人看同样的问题时,我怀疑这可能是一个错误。
对此的任何帮助将不胜感激,因为我的项目为此而被暂停,而不是被推送到应用商店。

任何对此的解决方案将极大地帮助您。

谢谢,
鲍勃

@ liuxuan30您能否将此问题

谢谢,
鲍勃

对不起,我最近忙于工作,因此无法很快查看。 会尝试
我记得NSTimeInterval是两倍,所以应该不会有影响。

@ liuxuan30是的,它是一个双。 使用格式化程序,日期可以正确显示。 条形上方的值正确显示。

一切正常,但栏未显示。

如果您很忙,还有其他人可以调查此问题/错误吗?

谢谢,
鲍勃

好吧,我做了一个快速检查。
x轴范围是

(lldb) po max - min
34041601.0

渲染时,barRect宽度太小:

▿ (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

所以你看不到。
原因是x val太大,因此在prepareBuffer()

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

然后

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

这是微不足道的。

@danielgindi似乎我们需要处理barWidth以应对大价值? 或者是设计使然。

x范围很大,但是只有几个小节,但是我们使用一个硬编码数字来表示小节的宽度,这会造成麻烦。 我试图“规范化” barWidth,越野车。

临时解决方法是使用更大的天单位,而不是x值以秒为单位。 或者,您只需将其变成1,2,3,4,..,然后让格式化程序进行格式化。 在您的数据中,您的x值超过一年,甚至几天也是如此,它是365条,并且条也很薄。

另一种方法是更改​​适合您的值范围的barWidth 。 但是,目前尚不清楚如何找到正确的号码。

你好,
我有完全相同的问题,但该问题似乎已经关闭,没有给出任何解决方案...
如果使用折线图,则该图表可以正确绘制,但是如果选择垂直条形图,则不会显示任何条形图。
对我而言,这不是增强功能,而是错误。

谢谢

将BarChartData.barWidth设置为巨大的值(〜10000)为我解决了问题

我通过设置边界解决了这个问题
chartDataSet.barBorderColor = UIColor.blue
chartDataSet.barBorderWidth = 30
希望能有所帮助

设置barBorderWidth似乎可以解决此问题。

这个问题有解决方案吗? 设置barBorderWidth似乎可以工作,但实际上并不能以正确的方式工作,因为如果只有一个或两个数据点,则行太细(假设将barBorderWidth设置为1)。 如果将其设置为更高的数字,则所有条形图都将合并并混合在一起,看起来并不好。

非常感谢对此所做的任何工作。

像魅力一样工作!

bars not displaying

我的分析:
这是一个错误... long数据类型中的日期值为1542039314621,表示2018年11月12日使用SimpleDateFormat进行格式化之后。 但是x Axis首先采用其long值,这会引起麻烦。 我的解决方案是xHelper,而不是输入大值,xHelper使用计数器counter++隐式地执行索引long数据类型,在xValue旁边保留大long值。 这个代码就像一个魅力

这是错误的代码:

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

这是错误的代码:

 xAxis.setValueFormatter(new IAxisValueFormatter() {
         <strong i="20">@override</strong>
         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);
              }
}

这是不正确的代码:

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

这是错误的代码:

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

这段代码就像一个魅力:

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));

这是我的完整代码,并介绍有关xValue和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;}
}

接下来参加本节课,感谢Phillip Jahoda

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

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

         <strong i="9">@override</strong>
         public String getFormattedValue(float value, AxisBase axis) {
              return mValues[(int) value];
         }
}

最后制作MainActivity类:

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;

<strong i="13">@override</strong>
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() {
                   <strong i="14">@override</strong>
                    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);
           });
     }

    <strong i="15">@override</strong>
    protected void onStart {
    super.onStart();

                   reference.addValueEventListener(new ValueEventListener() {
                            <strong i="16">@override</strong>
                            public void onDataChange(<strong i="17">@NonNull</strong> 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();


                             }
                             <strong i="18">@override</strong>
                             public void onCancelled(<strong i="19">@NonNull</strong> DatabaseError databaseError){
                            }
                   });
    }
} 

一切都完成了。 这是我的描述:

我不使用此代码:

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

因为我需要动态输入,并且不想写“ jan”,“ feb”等等。 我的解决方案:
String[] month = (String[]) myDateList.toArray(new String[xHelper.length]);

myDateList.toArray允许您获取ArrayList并将其插入到数组中。

而且我不使用此代码,因为->

xAxis.setValueFormatter(new IXAxisValueFormatter {

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

因为从x轴上获取的value会导致条形消失。 我的解决方案是xHelper像这样:

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

关键是, xHelper必须包含较小的值来索引Date

这就是秘密:
您不会使用此-> String[] month = new String[]{...};输入Date String[] month = new String[]{...};而是myDateList

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

@sjuvvalapalem @avitus您是否找到任何解决方案。

自从这个错误被报告以来已经两年了,仍然没有修复程序?

您可以提出PR来解决此问题吗? 我最初将其标记为added this to To do in 4.0 Release

不确定是否对任何人有帮助,但是我遇到了同样的问题,并通过将条形图设置为相对于x轴范围的正确大小来解决了这个问题:

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

将BarChartData.barWidth设置为巨大的值(〜10000)为我解决了问题

如果您在您的数据范围之间有一些缺失值,即https://github.com/danielgindi/Charts/issues/1742#issuecomment -519056482,则此方法效果更好。 非连续和周期性的数据源。

如果您之间缺少值,
在评论之后https://github.com/danielgindi/Charts/issues/1742#issuecomment -519056482
Screenshot 2020-05-16 at 12 52 11 PM

将BarChartData.barWidth设置为巨大的值(〜10000)看起来像
Screenshot 2020-05-16 at 12 52 40 PM

但是当你有足够的连续值时,两者都很好
IMG_81DD4290AE1B-1

我只丢了3个小时,这一点,因此保持它的眼睛。 通过使用索引结束。

此页面是否有帮助?
0 / 5 - 0 等级