Как сделать так, чтобы GD :: Graph не отображал точки за пределами области графика?

Я делаю несколько графиков в Perl, используя GD :: Graph, и некоторые данные находятся за пределами области, которую я хотел бы отобразить, но вместо того, чтобы обрезать диаграмму за пределами области графика, они рисуются над заголовком, легендой и метками оси . Кто-нибудь знает, как этого не допустить?

Я предполагаю, что это ошибка или отсутствует функция. Если вам просто нужен быстрый сюжет, вы можете использовать gnuplot.

Svante 16.11.2008 16:00
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
1
713
2

Ответы 2

Если вы знаете свои границы, отфильтруйте данные и не включайте эти точки в данные, которые вы отправляете в GD :: Graph.

Чтобы уточнить: вы объявляете высоту y_max_value, и ваши данные выходят за пределы этой границы? Или GD :: Graph неправильно рассчитывает верхний предел?

Если вы устанавливаете значение, вам необходимо зафиксировать ваши значения на этой верхней границе. GD :: Graph делает только то, что вы ему говорите. (Это примерно то, что сказал Брайан).

OTOH, я обнаружил, что GD :: Graph не всегда хорошо справляется с кумулятивными (сложенными) графиками и имеет тенденцию переоценивать y_max_value в этих обстоятельствах. Он также может выдавать некоторые непривлекательные значения по оси Y с числами с плавающей запятой в значениях галочки. Это то, что вы действительно пытаетесь решить?

Имея обе эти проблемы, мы нашли решение, использующее Tie :: RangeHash для создания «аккуратных» приращений, которые всегда производят 5 целых точек деления.

use Tie::RangeHash ;
my $y_ranges = new Tie::RangeHash Type => Tie::RangeHash::TYPE_NUMBER;
$y_ranges->add(' -500,  -101', '-25');
$y_ranges->add(' -100,   -26', '-10');
$y_ranges->add('  -25,    -1',  '-5');
$y_ranges->add('    0,    25',   '5');
$y_ranges->add('   26,   100',  '10');
$y_ranges->add('  101,   500',  '25');
$y_ranges->add('  501,  1000', '100');
$y_ranges->add(' 1001,  5000', '250');
$y_ranges->add(' 5001, 10000','1000');
$y_ranges->add('10001, 50000','2500');
$y_ranges->add('50001,'      ,'5000');

sub set_y_axis {
    # This routine over-rides the y_max_value calculation in GD::Graph, which produces double the
    # required limit, and therefore a lot of white-space...
    return 1 unless @_ ;            #no point going any further if no arguments were provided, however result has to be
                                    #non-zero to avoid /0 errors in GD::Graph
    my @a = map { $_ || 0 } @_ ;    #array may have undefs in it. Set null to zero for calc of max
    my ($y_max) = sort { $b <=> $a } @a ; # Get largest total for y-axis
    my $y_range = $y_ranges->fetch($y_max);
    my $y_axis = ($y_max%$y_range==0) ? $y_max+$y_range : ($y_max - ($y_max%$y_range) + $y_range);
    sprintf("%d", $y_axis);
}

sub my_graph {
    my @ymax;
    # generate data... foreach loop etc
        push(@ymax, $this_y_value); # append y-value or cumulative y-value as appropriate
    # etc.
    my $graph = GD::Graph::lines->new(750, 280);
    $graph->set(
        y_max_value         => set_y_axis(@ymax),
        x_labels_vertical   => 1,
        transparent         => 1,
        # etc
    );
    # etc
}

Надеюсь, это полезно для вас.

Я устанавливаю высоту y_max_value, и данные выходят за пределы этой границы. Я думаю, что это немного противоречит интуиции, что область графика не будет усекать все, что находится за ее пределами, но я думаю, что предварительная фильтрация данных - лучшее, что я могу сделать.

Dan Littlejohn 18.11.2008 02:10

y_max_value полезно для обеспечения того, чтобы серия графиков имела одинаковую высоту, или для объявления ограничения бизнес-правил. Но если вы это сделаете, вам необходимо убедиться, что ваши точки данных соответствуют этому правилу. Вот почему я написал приведенный выше код. Графики выглядят «правильно».

RET 18.11.2008 10:05

Другие вопросы по теме