Charts: Полосы не отображаются на гистограмме

Созданный на 29 окт. 2016  ·  24Комментарии  ·  Источник: danielgindi/Charts

Привет,

С момента обновления до 3.0 у меня возникли проблемы с полосами, которые не отображаются на гистограмме.

Одна полоса показывает, когда данные имеют только одну точку. Если я добавлю более одной точки, столбцы не будут отображаться.
Это происходит только тогда, когда на оси x есть даты. если я изменю данные с дат на целое число, тогда он будет работать нормально.
См. Приложенные скриншоты.

Образец данных будет похож на этот
{
«04.09.2012»: «245»,
«05.02.2013»: «227»,
«07.04.2013»: «234»,
«07.08.2015»: «244»,
«10.11.2016»: «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 нет полосок. Похоже, я либо пропускаю звонок, либо что-то настраиваю, было бы очень полезно, если бы для этого было решение.

Спасибо,
Боб

Как вы его настраиваете? В диаграмме 3.0 была переработана ось x, поэтому многое изменилось. Если вы не обновите свой код, он может отсутствовать. На данный момент, пожалуйста, проверьте ChartsDemo для различных демонстраций гистограмм.

Я снова запущу демонстрационные диаграммы и посмотрю, смогу ли я воспроизвести проблему, но я считаю, что проблема аналогична другой открытой проблеме № 1716.

Позвольте мне вернуться к вам, когда я внесу некоторые изменения и запустю демонстрацию графиков.

Похоже, некоторые значения x вызывают проблемы.

Спасибо,
Боб

У меня такая же проблема. Моя ось X правильно показывает дату в формате ГГГГ-ММ-ДД, но полосы не видны.

@ liuxuan30 ,
вот что я в основном пробовал ... Я внес некоторые изменения в ChartsDemo в версии 3.0, и он делает то же самое ...

Я внес следующие изменения. вместо значения X, являющегося двойным, я добавляю дату и время с 1970 года, что является двойным значением для дат.
изменил форматировщик 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 на огромное значение (~ 10 000) решила проблему для меня

Я обошел эту проблему, установив границу
chartDataSet.barBorderColor = UIColor.blue
chartDataSet.barBorderWidth = 30
надеюсь, это поможет

Кажется, что установка barBorderWidth решает проблему.

Любое решение этой проблемы? Кажется, что установка barBorderWidth работает, но на самом деле она не работает должным образом, потому что, если есть только одна или две точки данных, линии слишком тонкие (при условии, что вы установили barBorderWidth на 1). Если установлено большее число, все полосы соединяются и смешиваются вместе, и это выглядит не очень хорошо.

Мы очень ценим любую работу над этим.

Работайте как шарм!

bars not displaying

Мой анализ:
Это ошибка ... Дата в типе данных long имеет значение 1542039314621, это означает 12 ноября 2018 г. После форматирования с использованием SimpleDateFormat. Но ось x сначала принимает значение long , что вызывает проблемы. Мое решение - xHelper, вместо этого введите большое значение, xHelper выполняет index long тип данных неявно с использованием счетчика counter++ , рядом с 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;}
}

затем сделайте этот класс и спасибо Филиппу Джахода

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

потому что эти value взяты из оси x, которые вызывают исчезновение ваших баров. мое решение - 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

И в этом секрет:
вы не вводите Date используя это -> String[] month = new String[]{...}; но myDateList

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

@sjuvvalapalem @avitus нашли ли вы какое-либо решение для этого.

Прошло 2 года с тех пор, как было сообщено об этой ошибке, и все еще нет исправления?

вы можете подать 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 на огромное значение (~ 10 000) решила проблему для меня

Этот работает лучше, чем 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 на огромное значение (~ 10 000) выглядит как
Screenshot 2020-05-16 at 12 52 40 PM

Но оба отлично работают, когда у вас есть все достаточные непрерывные значения
IMG_81DD4290AE1B-1

Я только что потерял на это 3 часа, так что следите за этим. Заканчивается с помощью индексов.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги