Я выпустил Grafar — JS-библиотеку для визуализации

    Я опенсорснул grafar — свою библиотеку для визуализации. Основная часть кода написана в 2013–2016 годах для моего диплома. Следующие 5 лет проект пролежал в столе — я был не вполне доволен АПИ, было много классных функций, которые я мог добавить, работа засасывала, и ещё тысяча причин не выпускать его пока, ну вы знаете. В конце концов, на свете есть столько людей поумнее меня, и они точно придумают что-то получше, правда же?

    На прошлой неделе мне на глаза снова попался этот прекрасный код, пылящийся на гитхабе — я подумал, что это всё еще выглядит классно, и, уверен, сэкономит кому-нибудь кучу времени. Так что я снабдил проект документацией мирового класса, обновил сборку и запустил хайп-режим.

    Буду честен — это первый публичный релиз графара. В нём, скорее всего, есть баги, и я не могу пообещать полную стабильность АПИ навсегда. Но всё же я уверен, что вам стоит обратить внимание на графар, и вот почему:

    Простое API. Всего 10 строк кода — и вы построили поверхность прямо в браузере. API заточено на работу с математическими объектами — кривыми, поверхностями, точками — и использует остроумную модель топологии объектов, чтобы все работало как ожидается.

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

    У нас еcть 3D и 2D. Спасибо ThreeJS, любой график можно построить в интерактивном 3D — я не знаю других библиотек, в которых это было бы так просто. Но можно строить графики и в 2D, не выходя из привычной модели.

    Реактивная интерактивность. Grafar — библиотека для интерактивной визуализации с реактивными вычислениями (чем-то похоже на MobX). Библиотека сама запоминает зависимости ваших отображений, и при изменении пересчитывает только то, что правда изменилось.

    Строим параметрическую поверхность

    Посмотрим, как просто построить график параметрической поверхности, на примере винтовой поверхности. Можете играть с примером в codesandbox.

    Поверхность — объект с двумя степенями свободы. Создадим по параметру для каждой из них:

    const p = grafar.range(-2, 2, 500).select();
    const q = grafar.range(0, 1, 2).select();

    Каждая из переменных моделирует отрезок ([-2, 2] для p, [0, 1] для q) числовым массивом и знает, что при отрисовке соседние точки нужно соединить.

    Теперь отобразим параметры в декартовы координаты (x,y,z):

    const xp = grafar.map([p, q], (p, q) => Math.cos(8 * p) * q);
    const yp = grafar.map([p, q], (p, q) => Math.sin(8 * p) * q);

    В этот момент происходит две интересных вещи. Во-первых, графар догадывается, что p и q — независимые переменные, и вызывает функцию для каждого сочетания точек в них. Во-вторых, графар запоминает зависимости xp и yp — если мы изменим p или q, xp и yp автоматически обновятся.

    Наконец, остается построить сам график — для этого мы создаём панель и прикрепляем данные на неё:

    const container = document.getElementById("app");
    const panel = grafar.panel(container);
    grafar.pin([xp, yp, p], panel);

    Вот что мы получаем за 7 строк кода:


    Конечно, параметрические поверхности — не всё, что умеет grafar. Вот несколько других примеров:

    Я планирую развивать функции для визуализации данных. Это более широкая ниша, чем математическая визуализация, но библиотеки для нее страдают от тех же проблем. При этом паттерны работы с данными отличаются — нужно будет поддержать динамические размеры таблиц, добавить хелперы для импорта данных и дискретную фильтрацию.

    Если вас заинтересовала библиотека, посмотрите документацию (пока только на английском). На гитхабе доступен полный код библиотеки. В ишьюс можно пожаловаться на баг, запросить фичу или даже поучаствовать в разработке (мне не помешает помощь).

    В любом случае, надеюсь, вам было интересно. Удачи с графиками!

    Комментарии 11

      +1
      Только это вроде не винтовая линия (линия — не поверхность), а винтовая поверхность — геликоид
        0

        И правда, спасибо за внимательность)

        –1
        codesandbox.io/s/grafar-template-h1k66
        TypeError
        Cannot read property 'update' of undefined
        TypeError
        Cannot read property 'getExtension' of null
          +1
          Похоже на ошибку из-за отсутствия WebGL — работает ли get.webgl.org?
            0
            Спасибо, действительно, в одном из браузеров не работал WebGL.
              +3
              Мне кажется, разумно будет сделать более понятное сообщение об отсутствии WebGL
                +1

                Это верно, завёл ишью. Спасибо за идею!

            0
            ---
              0

              Для дипломной работы сойдёт. Но для более серьезных вещей уже надо что-то типа d3.js брать в работу.

                +2

                Очень люблю d3, но у графара немного другой фокус — в первую очередь это библиотека для быстрых реактивных вычислений со специальными примитивами для математики. Кроме того, WebGL рендерится быстрее, чем стандартный dom/svg в д3 и поддерживает 3d из коробки. Скорее уместно сравнивать с deck.gl или numjs, но у нас разные концептуальные модели и мне не жалко попробовать немного другой подход.

                  0

                  ну, three js вроде не имеет каких-то жестких лимитов которые бы отсутcтвовали у d3. Больше API в grafar вероятно позднее добавит по мере спроса.

                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                Самое читаемое