Charts: Barras não exibem gráfico de barras

Criado em 29 out. 2016  ·  24Comentários  ·  Fonte: danielgindi/Charts

Oi,

Desde a atualização para o 3.0, estou tendo problemas com as barras que não aparecem no gráfico de barras.

Uma barra mostra quando os dados têm apenas um ponto. Se eu adicionar mais de um ponto, as barras não serão exibidas.
Isso está acontecendo apenas quando o xaxis tem datas. se eu alterar os dados de datas para dizer inteiro, então funciona bem.
Por favor, veja as imagens em anexo.

Uma amostra dos dados seria semelhante a este
{
"09/04/2012": "245",
"05/02/2013": "227",
"04/07/2013 ':" 234 ",
"07/08/2015": "244",
"11/10/2016": "2254"
}

Obrigado,
Prumo

1

Como pode ser visto abaixo, eu não vejo as barras? o que parece estar causando isso?
2

bug discussion enhancement ★★★

Comentários muito úteis

Não tenho certeza se isso ajuda alguém, mas tive o mesmo problema e resolvi definindo minhas barras para corrigir o tamanho em relação ao intervalo do eixo 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

Todos 24 comentários

Alguém tem uma solução para isso?
Parece estranho que as barras estejam faltando no 3.0. Parece que estou perdendo uma chamada ou configurando algo. Seria muito útil se houver uma solução para isso.

Obrigado,
Prumo

Como você configura? O gráfico 3.0 reprojetou o eixo x, então muitas coisas mudaram. Se você não atualizar seu código, ele pode estar faltando. Por enquanto, verifique o ChartsDemo para obter diferentes demonstrações de gráfico de barras.

Vou rodar os gráficos de demonstração novamente e ver se consigo reproduzir o problema, mas acredito que o problema é semelhante ao outro número 1716 aberto.

Deixe-me responder assim que eu fizer algumas alterações e executar a demonstração de gráficos.

Parece que certos valores x estão causando problemas.

Obrigado,
Prumo

Estou tendo o mesmo problema. Meu eixo X mostra corretamente a data no formato AAAA-MM-DD, mas as barras são invisíveis.

@ liuxuan30 ,
aqui está o que eu tentei basicamente ... Fiz algumas alterações no ChartsDemo no 3.0 e ele está fazendo exatamente a mesma coisa ...

Eu fiz as seguintes alterações. em vez de o valor X ser um dobro, estou adicionando a data e hora desde 1970, que é o valor duplo das datas.
alterou o formatador xaxis para um dd / MM.

Anexe também o código do BarChartViewController.m para que você possa verificá-lo.

Veja a imagem abaixo.
simulator screen shot nov 1 2016 12 22 47 am

BarChartViewController.m.zip

Ou estou perdendo algo muito simples ou isso é um bug.

Obrigado,
Prumo

Olá, não sei por que esse problema foi resolvido, mas como todos que descreveram os sintomas aqui e em https://github.com/danielgindi/Charts/issues/1716 , estou enfrentando o mesmo bug em nosso projeto. Resumindo, o eixo X não consegue lidar com grandes valores, como intervalos de tempo, e de alguma forma bagunça a renderização do gráfico.

@sjuvvalapalem o drawDataSets no renderizador de gráfico de barras para obter mais detalhes. É mais fácil depurar do seu lado.

BarChartViewController.m.zip
@ liuxuan30 anexei as alterações que fiz na minha resposta anterior.
Tudo o que fiz foi, em vez de dobrar, apenas adicionar o intervalo Nstime para algumas datas e por algum motivo ele não está mostrando as barras.

Acho que isso pode ser um bug. Por favor, olhe o documento compactado em anexo, você pode facilmente descobrir as alterações que fiz e que devem fazer sentido.
Olhando para o mesmo problema para as outras pessoas, suspeito que isso possa ser um bug.
Qualquer ajuda sobre isso é muito apreciada, pois meu projeto está sendo interrompido por causa disso, em vez de ser enviado para a appstore.

Qualquer solução para isso ajudaria muito.

Obrigado,
Prumo

@ liuxuan30 poderia deixar este problema aberto? para que este tenha mais tração como os outros mencionados.

Obrigado,
Prumo

Lamento estar ocupado com meu trabalho recentemente, então não posso dar uma olhada nisso muito rapidamente. Vou tentar
NSTimeInterval é o dobro, eu me lembro, então não deve impactar.

@ liuxuan30 sim, é um duplo. Com o formatador, as datas aparecem corretamente. os valores acima das barras são exibidos corretamente.

Tudo está funcionando, mas as barras não estão aparecendo.

Se você estiver ocupado, há mais alguém que possa investigar este problema / bug?

Obrigado,
Prumo

tudo bem, eu fiz uma verificação rápida.
O intervalo do eixo x é

(lldb) po max - min
34041601.0

Ao renderizar, a largura barRect é muito pequena:

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

Então você não vê.
O motivo é que o x val é muito grande, então em prepareBuffer() ,

let barWidthHalf = barData.barWidth / 2.0 // barWidth é 0,9

então

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

é trivial.

@danielgindi parece que precisamos lidar com barWidth para lidar com grandes valores? Ou é por design.

O intervalo x é muito grande, mas apenas algumas barras; no entanto, usamos um número codificado para apresentar a largura da barra, o que causa problemas. Tentei "normalizar" o barWidth, com erros.

A solução temporária é usar unidades de dias maiores, não segundos para valores x. Ou basta transformá-lo em 1,2,3,4, .. e deixar o formatador formatar. Em seus dados, seus x vals têm mais de um ano, mesmo em dias, são 365 barras e a barra também seria fina.

Outra maneira é alterar barWidth que se encaixam em sua faixa de valor. No entanto, ainda não há uma ideia clara de como encontrar o número certo.

Oi,
Eu tenho exatamente o mesmo problema, mas o problema parece ter sido resolvido sem dar qualquer solução ...
Se eu usar um gráfico de linhas, o gráfico está desenhando corretamente, mas se eu escolher gráfico de barras verticais, nenhuma barra aparecerá.
Para mim, isso NÃO é um aprimoramento, é um bug.

Obrigado

definir BarChartData.barWidth para um valor enorme (~ 10.000) resolveu o problema para mim

Eu contornei esse problema definindo uma borda
chartDataSet.barBorderColor = UIColor.blue
chartDataSet.barBorderWidth = 30
espero que ajude

A configuração de barBorderWidth parece corrigir o problema.

Alguma solução para este problema? Definir barBorderWidth parece funcionar, mas realmente não funciona da maneira certa porque se houver apenas um ou 2 pontos de dados, as linhas são muito finas (assumindo que você definiu barBorderWidth como 1). Se definido com um número mais alto, todas as barras são unidas e mescladas e não têm uma boa aparência.

Qualquer trabalho sobre isso é muito apreciado.

Trabalho como um encanto!

bars not displaying

Minha análise:
Este é um bug ... A data no tipo de dados long tem valor 1542039314621, significa 12 de novembro de 2018 Depois de formatado usando SimpleDateFormat. Mas o eixo x assume seu long primeiro, que está causando problemas. Minha solução é xHelper, em vez disso insira um grande valor, xHelper fazendo o índice long tipo de dados implicitamente usando o contador counter++ , ao lado de xValue contém o grande long valor. e este código funciona como um encanto

este é o código errado:

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

Este é o código errado:

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

Este é o código incorreto:

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

este é o código errado:

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

este código funciona perfeitamente:

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

Este é meu código completo e conta tudo sobre xValue e 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;}
}

próximo faça esta classe e graças a 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];
         }
}

finalmente faça a classe 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){
                            }
                   });
    }
} 

Tudo está feito. E esta é a minha descrição:

Eu não uso este código:

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

porque preciso de uma entrada dinâmica e não quero escrever "jan", "fev" e assim por diante. minha solução:
String[] month = (String[]) myDateList.toArray(new String[xHelper.length]);

myDateList.toArray permitem que você pegue ArrayList e insira-o no array.

E eu não uso este código porque ->

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

porque aquele value retirado do eixo x que faz com que suas barras desapareçam. minha solução é xHelper assim:

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

o que quero dizer é que xHelper deve conter um pequeno valor para indexar Date

E este é o segredo:
você não insere Date usando isto -> String[] month = new String[]{...}; mas myDateList

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

@sjuvvalapalem @avitus encontrou alguma solução para isto.

Já se passaram 2 anos desde que esse bug foi relatado e ainda não há uma correção?

você pode registrar um PR para corrigir isso? Eu originalmente marquei added this to To do in 4.0 Release

Não tenho certeza se isso ajuda alguém, mas tive o mesmo problema e resolvi definindo minhas barras para corrigir o tamanho em relação ao intervalo do eixo 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

definir BarChartData.barWidth para um valor enorme (~ 10.000) resolveu o problema para mim

Este funciona melhor do que https://github.com/danielgindi/Charts/issues/1742#issuecomment -519056482 quando você tem alguns valores ausentes entre o seu intervalo de dados, ou seja, fonte de dados não contínua e periódica.

Se você tem valores ausentes entre eles,
Seguindo o comentário https://github.com/danielgindi/Charts/issues/1742#issuecomment -519056482
Screenshot 2020-05-16 at 12 52 11 PM

definir BarChartData.barWidth para um valor enorme (~ 10 000) parece
Screenshot 2020-05-16 at 12 52 40 PM

Mas ambos funcionam muito bem quando você tem todos os valores contínuos suficientes
IMG_81DD4290AE1B-1

Acabei de perder 3 horas com isso, então fico de olho nisso. Terminado usando índices.

Esta página foi útil?
0 / 5 - 0 avaliações