Pergunta

Alguém tem um algoritmo decente para calcular mínimos e máximos dos eixos?

Ao criar um gráfico para um determinado conjunto de itens de dados, gostaria de poder fornecer o algoritmo:

  • o valor máximo (y) no conjunto
  • o valor mínimo (y) no conjunto
  • o número de marcas de escala que aparecerão no eixo
  • um valor opcional que deve aparecer como uma marca (por ex.zero ao mostrar valores +ve e -ve)

O algoritmo deve retornar

  • o maior valor do eixo
  • o menor valor do eixo (embora isso possa ser inferido do maior, o tamanho do intervalo e o número de ticks)
  • o tamanho do intervalo

Os ticks devem estar em intervalos regulares e devem ser de tamanho "razoável" (por exemplo,1, 3, 5, possivelmente até 2,5, mas não há mais figos sig).

A presença do valor opcional distorcerá isso, mas sem esse valor o item maior deverá aparecer entre as duas marcas superiores, e o valor mais baixo entre as duas inferiores.

Esta é uma questão independente de linguagem, mas se houver uma biblioteca C#/.NET por aí, isso seria incrível;)

Foi útil?

Solução

Eu tenho usado o jQuery flutuar biblioteca de gráficos.É de código aberto e gera muito bem eixos/tiques.Eu sugiro olhar seu código e extrair algumas idéias dele.

Outras dicas

OK, aqui está o que eu criei para um de nossos aplicativos.Observe que ele não trata do cenário de "valor opcional" que você mencionou, já que nosso valor opcional é sempre 0, mas não deve ser difícil modificá-lo.

Os dados são continuamente adicionados à série, portanto, apenas mantemos o intervalo de valores de y atualizado, inspecionando cada ponto de dados à medida que é adicionado;isso é muito barato e fácil de controlar.Valores mínimos e máximos iguais são casos especiais:um espaçamento 0 indica que nenhum marcador deve ser desenhado.

Esta solução não é diferente da sugestão de Andrew acima, exceto que ela lida, de uma forma um pouco confusa, com algumas frações arbitrárias do multiplicador de expoentes.

Por último, este exemplo está em C#.Espero que ajude.

    private float GetYMarkerSpacing()
    {
        YValueRange range   = m_ScrollableCanvas.
                    TimelineCanvas.DataModel.CurrentYRange;
        if ( range.RealMinimum == range.RealMaximum )
        {
            return 0;
        }

        float   absolute    = Math.Max(
                    Math.Abs( range.RealMinimum ),
                    Math.Abs( range.RealMaximum ) ),
            spacing     = 0;
        for ( int power = 0; power < 39; ++power )
        {
            float   temp    = ( float ) Math.Pow( 10, power );
            if ( temp <= absolute )
            {
                spacing = temp;
            }
            else if ( temp / 2 <= absolute )
            {
                spacing = temp / 2;
                break;
            }
            else if ( temp / 2.5 <= absolute )
            {
                spacing = temp / 2.5F;
                break;
            }
            else if ( temp / 4 <= absolute )
            {
                spacing = temp / 4;
                break;
            }
            else if ( temp / 5 <= absolute )
            {
                spacing = temp / 5;
                break;
            }
            else
            {
                break;
            }
        }

        return spacing;
    }

Posso recomendar o seguinte:

  • Defina um número mínimo visualmente atraente de linhas principais.Isso dependerá da natureza dos dados que você está apresentando e do tamanho do gráfico que você está fazendo, mas 7 é um número muito bom
  • Escolha o expoente e o multiplicador com base em uma progressão de 1, 2, 5, 10, etc.isso lhe dará pelo menos o número mínimo de linhas principais.(ou seja.(max-min)/(escala x 10 ^ expoente) >= mínimo_tick_marks)
  • Encontre o múltiplo inteiro mínimo do seu expoente e multiplicador que se ajusta ao seu intervalo.Este será o primeiro grande tick.O resto dos ticks são derivados disso.

Isso foi usado para um aplicativo que permitia o dimensionamento arbitrário de dados e parecia funcionar bem.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top