Charts: A linha cúbica vai muito além da parte superior ou inferior. Precisa de nivelamento.

Criado em 22 set. 2015  ·  33Comentários  ·  Fonte: danielgindi/Charts

snip20150922_1

Gosta da foto, às vezes quebrada, alguém pode ajudar?

set1 = [[LineChartDataSet alloc] init WithYVals: yVals label: @ "DataSet 1"];
set1.drawCubicEnabled = YES;
set1.cubicIntensity = 0,5;

Quando eu defino drawCubicEnabled é NO , o gráfico parece ok.

bug feature

Comentários muito úteis

Ok, então eu examinei o código das outras bibliotecas - e parece que elas fazem muitos cálculos estranhos e desnecessários. Consegui deduzir o algoritmo principal para pontos de controle e criar um CodePen:
http://codepen.io/danielgindi/pen/eZGxzr

O código contém métodos bézier quádruplos e cúbicos, pois tive de simplificar e depois construir para pontos de controle cúbicos.
Isso parece suficiente, embora remova a opção de controlar a intensidade do bezier.
Então, acho que o que farei é apresentar um enum para a maneira como o gráfico de linha desenhará sua linha (linear, escalonado, bézier, bézier aparado).

@PhilJay o que você acha?

Todos 33 comentários

você definiu algum customAxisMax / Min? Parece que está sendo cortado?

Não defina qualquer max / min .
Código de teste:

    _lineChartView.delegate = self;
    //_lineChartView.backgroundColor = [UIColor yellowColor];

    _lineChartView.descriptionText = @"";
    _lineChartView.noDataTextDescription = @"You need to provide data for the chart.";

    _lineChartView.drawGridBackgroundEnabled = YES;
    _lineChartView.dragEnabled = NO;
    [_lineChartView setScaleEnabled:NO];
    _lineChartView.pinchZoomEnabled = NO;
    //[_lineChartView setViewPortOffsetsWithLeft:10.0 top:0.0 right:10.0 bottom:0.0];

    _lineChartView.legend.enabled = NO;

    _lineChartView.leftAxis.enabled = NO;
    _lineChartView.rightAxis.enabled = NO;
    _lineChartView.xAxis.enabled = NO;

    NSMutableArray *xVals = [[NSMutableArray alloc] init];

    [xVals addObject:@"1442246400000"];
    [xVals addObject:@"1442419200000"];
    [xVals addObject:@"1442505600000"];
    [xVals addObject:@"1442764800000"];
    [xVals addObject:@"1442851200000"];


    NSMutableArray *yVals = [[NSMutableArray alloc] init];

    [yVals addObject:[[ChartDataEntry alloc] initWithValue:0 xIndex:0]];
    [yVals addObject:[[ChartDataEntry alloc] initWithValue:-1 xIndex:1]];
    [yVals addObject:[[ChartDataEntry alloc] initWithValue:0.01170003414154053 xIndex:2]];
    [yVals addObject:[[ChartDataEntry alloc] initWithValue:0.04190003871917725 xIndex:3]];
    [yVals addObject:[[ChartDataEntry alloc] initWithValue:0.05540001392364502 xIndex:4]];

    LineChartDataSet *set1 = [[LineChartDataSet alloc] initWithYVals:yVals label:@"DataSet 1"];

    set1.lineWidth = 1.75;
    set1.circleRadius = 3.0;
    [set1 setColor:[UIColor orangeColor]]; 
    [set1 setCircleColor:UIColor.whiteColor];
    set1.highlightColor = UIColor.whiteColor;
    set1.drawValuesEnabled = NO;
    set1.drawCubicEnabled = YES;
    set1.cubicIntensity = 0.5;

    _lineChartView.data = [[LineChartData alloc] initWithXVals:xVals dataSet:set1];

Resultado:
snip20150922_3

Acabei de ver uma linha muito plana com seus dados, o que eu perdi
flat

Parece uma linha tracejada ...

O dataSet é muito pequeno:
[yVals addObject: [[ChartDataEntry alloc] init WithValue: 0 xIndex: 0 ]];
[yVals addObject: [[ChartDataEntry alloc] init WithValue: -1 xIndex: 1 ]];
[yVals addObject: [[ChartDataEntry alloc] init WithValue: 0,01170003414154053 xIndex: 2 ]];
[yVals addObject: [[ChartDataEntry alloc] init WithValue: 0.04190003871917725 xIndex: 3 ]];
[yVals addObject: [[ChartDataEntry alloc] init WithValue: 0.05540001392364502 xIndex: 4 ]];
Então, eu só vejo a linha plana. Ignore a linha tracejada, é limitLine do código ChartsDemo.

BTW, # 330 também está falando sobre pontos de dados ausentes, embora seja para drawLinear. Será o mesmo problema?

@ zxy198717 alguma informação nova?

@danielgindi @ liuxuan30 Criei um projeto de teste (https://github.com/zxy198717/iOS-Chart-Test), talvez ele possa ajudá-lo a encontrar a causa raiz.

OK, mas acho que ninguém sobrou para investigar isso agora. Marcar como bug

Eu tenho o mesmo problema aqui.

Aqui está o mesmo gráfico com linhas cúbicas desativadas e ativadas:

captura de tela 2015-11-18 as 03 15 52

captura de tela 2015-11-18 as 03 13 06

No começo eu pensei que era apenas uma questão de mudar o preenchimento do gráfico ou algo parecido, é como se a renderização cúbica fizesse alguns pedaços da linha caírem abaixo da parte visível do gráfico, mas não consegui encontrar nada que ajudasse me resolver isso, e então me deparei com este post.

Por que não definir um mínimo de y personalizado para o gráfico, para evitar o corte?

Isso foi rápido, obrigado. Eu sou novo nisso, vou tentar descobrir como fazer isso então ... mas para evitar muitos espaços em branco abaixo do gráfico dependendo dos dados dos usuários, terei que encontrar o valor mínimo em seus conjuntos de dados e sempre definir aquele mínimo Y personalizado um pouco abaixo disso, certo? Vou servir por enquanto se eu conseguir fazer funcionar, mas não é muito elegante.

Ok, isso resolveu o primeiro problema, mas agora tenho outro:

captura de tela 2015-11-18 as 04 20 02

Parece que os dados caem abaixo de zero às vezes, o que não faz sentido para meu aplicativo ... ou talvez pareça que os dados são mais do que zero com aqueles solavancos quando deveriam ser linhas retas.

Bem, isso é porque é uma linha Bézier Cúbica, não uma linha reta. Isso é
como Beziers funciona ...

Talvez alguém com mais experiência em gráficos com linhas Bezier pudesse oferecer
algumas dicas aqui.

Na quarta-feira, 18 de novembro de 2015 às 8h24, danielbmarques [email protected]
escrevi:

Ok, isso resolveu o primeiro problema, mas agora tenho outro:

[imagem: captura de tela 2015-11-18 as 04 20 02]
https://cloud.githubusercontent.com/assets/15813674/11234080/b4dba5b8-8dab-11e5-9619-6b5a12b68bc8.png

Parece que os dados caem abaixo de zero às vezes, o que não faz sentido
para meu aplicativo ... ou talvez pareça que os dados são mais do que zero com aqueles
incha quando deveriam ser linhas retas.

-
Responda a este e-mail diretamente ou visualize-o no GitHub
https://github.com/danielgindi/ios-charts/issues/407#issuecomment -157616020
.

Eu também experimentei esta biblioteca e as linhas bezier parecem ótimas, então certamente é possível:

captura de tela 2015-11-18 as 04 34 14

Prefiro usar sua biblioteca para os recursos, no entanto. :(

Vamos olhar para isso

@PhilJay ?

Muito obrigado!
Ótimo trabalho, por falar nisso. :)

Bem, isso parece que os valores zero são simplesmente renderizados como linhas normais?

Sim, como quando os valores atingem o valor mínimo real (não o valor mínimo personalizado) - precisamos apará-los em linhas retas.
Mas então temos um problema com a linha sendo parte bézier parte reta ...
Presumo que haja algum tipo de truque, talvez a duplicação de pontos para forçar o bezier a desenhar em linha reta.

Acho que provavelmente é o caso, duplicando pontos.
Se você comparar os dois exemplos que postei, você pode ver que no último a linha é mais curva em seus extremos ... como se estivesse vindo de uma linha reta e indo para uma linha reta, e podemos ver as curvas no gráfico prepare-se para fazer isso. Portanto, os valores zero não são apenas linhas normais, o resto do gráfico também se ajusta para compensar isso.
E isso não deve acontecer apenas quando os pontos estão próximos do mínimo ... se você tem uma linha curva entre dois pontos, a curva nunca deve ficar acima ou abaixo de qualquer um desses dois pontos, não importa quais são seus valores.

Veja este exemplo daquela outra biblioteca:
image

A linha entre "sab" e "dom" não vai acima nem abaixo dos valores de "sab" e "dom", embora o enorme relevo em "sexo" deva fazer isso. Portanto, alguns pontos devem ser duplicados para contabilizar isso, independentemente de estar no valor mínimo ou máximo ou nenhum.

Alguém resolveu esse problema? Meu gráfico está caindo abaixo de zero também, e é tão feio. @danielbmarques você acabou usando uma biblioteca melhor?

Vamos resolver isso em breve. Estamos trabalhando muito em outras coisas.
Você é muito bem-vindo para tentar resolvê-lo e criar um PR também!

Na terça-feira, 24 de novembro de 2015 às 13h34, Hannah Carney [email protected]
escrevi:

Alguém resolveu esse problema? Meu gráfico está caindo abaixo de zero também, e é tão
feio. @danielbmarques https://github.com/danielbmarques você acabou
usando uma biblioteca melhor?

-
Responda a este e-mail diretamente ou visualize-o no GitHub
https://github.com/danielgindi/ios-charts/issues/407#issuecomment -159237756
.

@HannahCarney Se você só se interessa pela linha em si, acho que a melhor opção é essa , mas você nem vai conseguir rótulos para os eixos, você mesmo tem que configurá-los. Por enquanto, apenas recorri a isso:

simulator screen shot 23 de nov de 2015 20 19 46

@danielgindi Aparentemente, duplicar pontos não é a melhor maneira de fazer isso, afinal. Acho que o caminho a percorrer é usar UIBezierPath e pontos de controle em vez de CGPathCreateMutable. Parece bastante simples, mas não terei tempo para descobrir como adicioná-lo ao resto do código por agora.

Você pode verificar isso se não se importa em trapacear.

@danielbmarques IMHO UIBezierPath não é relevante, funciona quase exatamente como CGPathCreateMutable. O problema é que não existe (pelo menos eu não conheço nenhum) método de interpolação de spline que leve em consideração as restrições relevantes. Eu não estudei a abordagem JBChartView, mas a biblioteca BEMSimpleLineGraph atenua o erro por não usar nenhuma interpolação, ela simplesmente desenha curvas de Bezier entre os pontos. Funciona com dados muito simples, mas na maioria dos casos cria gráficos "irregulares" feios.

Alguém pode confirmar que JBChartView não tem o mesmo problema? Vou testar no meu tempo livre, mas AFAIK deve ter exatamente os mesmos problemas.

@mslazynski Seja usando CGPathCreateMutable ou UIBezierPath , acho que o ponto principal é usar pontos de controle. Eu realmente não sei muito sobre algo assim, então posso estar completamente errado. Eu mal sei o que é interpolação, por exemplo, haha ​​... mas pelo que eu reuni, não acho que JBChartView use segmentos discretos independentes, se é o que você quer dizer. O link que postei antes estava quebrado, acho que a parte relevante é essa .

O aplicativo iTunes Connect da Apple tem gráficos que não têm esse problema, eu me pergunto como eles fazem isso:
img_7208

@danielbmarques BEMSimpleLineGraph usa segmentos separados. O JBChartView usa algum tipo de interpolação com certeza (basta olhar o código ao qual você vinculou), porém não tive tempo de testar se seu método de interpolação atenua o problema. Se for confirmado que o JBCharView resolveu o problema, portar seu código deve ser um trabalho de 1h :) Tenho certeza que existe uma maneira adequada de escolher os pontos de controle -> Tentei alguns métodos ingênuos, porém o enredo resultante sempre foi feio :(

@mslazynski Um tempo atrás, quando mencionei o JBChartView pela primeira vez, tentei com meu código e ele corrigiu o problema. Eu não testei muito extensivamente, no entanto; meus gráficos são relativamente simples.

Ok, então eu examinei o código das outras bibliotecas - e parece que elas fazem muitos cálculos estranhos e desnecessários. Consegui deduzir o algoritmo principal para pontos de controle e criar um CodePen:
http://codepen.io/danielgindi/pen/eZGxzr

O código contém métodos bézier quádruplos e cúbicos, pois tive de simplificar e depois construir para pontos de controle cúbicos.
Isso parece suficiente, embora remova a opção de controlar a intensidade do bezier.
Então, acho que o que farei é apresentar um enum para a maneira como o gráfico de linha desenhará sua linha (linear, escalonado, bézier, bézier aparado).

@PhilJay o que você acha?

Parece bom. Que tal desempenho? Essa nova maneira de desenhar, por exemplo, o cúbico, também melhora o desempenho? (parece que sim)

Não acho muito ruim se você não consegue mais controlar a intensidade, mas se ainda quisermos esse recurso, um enum ou sinalizador pode ser suficiente.

Dos meus testes, sim. Se eu usar o método cúbico final, então estou fazendo a mesma quantidade de chamadas AddCurveTo, mas com menos matemática.

Eu acho que cubicIntensity é uma boa propriedade de se ter, e algumas pessoas podem realmente querer desenhar uma cúbica real, não aparada :)

@danielgindi Incrível, obrigado!

Incrível, muito obrigado!

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

Questões relacionadas

cilasgimenez picture cilasgimenez  ·  4Comentários

guanyanlin picture guanyanlin  ·  3Comentários

valeIT picture valeIT  ·  3Comentários

brytnvmg picture brytnvmg  ·  4Comentários

guoyutaog picture guoyutaog  ·  3Comentários