Трогательный интерфейс

Алексей Распопов

Трогательный интерфейс

In Soviet Union interface touches you

Visualization — constructing visual representations of abstract data to
amplify cognition.

Берём абстрактные величины и бережно переносим их в визуальные величины, которые понимает машина.

Есть две формулы...

        (x - b) / k
        k * x + b
      
Introducing D3 scale article by mike Bostock

Шкала — функция, которая принимает абстрактное значение и возвращает визуальное.

        function scaleLinear(domain, range) {
          return x => interpolate(range, normalize(domain, x));
        }
      
        // [N, N] -> [0, 1]
        function normalize(range, x) {
          let k = range[1] - range[0];
          let b = range[0];
          return (x - b) / k;
        }
      
        // [0, 1] -> [N, N]
        function interpolate(range, t) {
          let k = range[1] - range[0];
          let b = range[0];
          return b + k * t;
        }
      
        function scale([d0, d1], [r0, r1], x) {
          return r0 + (r1 - r0) * (x - d0) / (d1 - d0);
        }
      
Data viz dimensions table
        let datapoints = [0.7300683106640126, -0.4606999589484973,
          0.0810442791570592, 1.264658107394293, -0.3999839805247,
          0.73774975545273, 1.181487753486226, -0.444039268800015,
          0.738077186476263, 0.0268356600561, -0.4351210367944046,
          0.2615460040301957, -0.560046949247555, 1.1022347693372,
          -2.7468864731377, -0.647799719212206, 1.550835553230532,
          1.312599295229566, -0.6733235254171, -0.502827667037121,
          -0.373466838991289, 0.0364248070202155, ...];
sample data plotted as a line
        let domainX = [0, datapoints.length - 1];
        let scaleX = scaleLinear(domainX, [0, width]);
        let domainY = [Math.min(...datapoints), Math.max(...datapoints)];
        let scaleY = scaleLinear(domainY, [height, 0])
      
        let getX = (d, i) => scaleX(i);
        let getY = (d) => scaleY(d);
        return <path d={line(datapoints, getX, getY)} />
      
        function line(data, x, y) {
          return data.reduce((curve, d, i) => {
            let prefix = i === 0 ? 'M' : 'L';
            let point = prefix + x(d, i) + ',' + y(d, i);
            return curve + point;
          }, '');
        }
      

M0,149.6283711248115L0.80080080800807,158.4719886183878L1.60161601606015,160.7229895999148L2.40402402402402,136.7026041695307L3.20320203203203,172.5591461581857L4.00404004004004,123.4183330530276L4.80804804804805,135.0474115675488L5.65605605605605,162.1072718749057L6.40606406406406,166.7711007103693L7.207272072072007,145.88920391649837...

Не видно же ничего!

sample data plotted as a line, scaled x32

Масштабируем величины данных,
а не машин

sample data plotted as a line, scaled x32

Возможность пользователя взаимодействовать с данными, дает свободу исследования и поиска новых ответов 🙏

        let domainX = [0, datapoints.length - 1];
        let scaleX = scaleLinear(domainX, [0, width]);
        
        let rescaledX = scaleLinear(window, [0, width]);
        
      
        render = (Data) => UI;
        update = (State, Action) => NewState;
        Actions = [Update Thing, Add Thing, Delete Thing, ...];
        State = Actions.reduce(update, InitialState);
        State.subscribe(render);
      

The holy grail
of state reduction 👏

        let transform = { k: 1, x: 0 };
        
      

Динамически изменяя window все зависимые от него детали интерфейса высчитывают свое новое состояние.

Они не хранят его отдельно потому нет проблемы с синхронизацией отдельных элементов.

        function handleWheelEvent(event) {
          let action = {
            type: 'wheel',
            deltaY: event.deltaY,
            pointerX: event.layerX,
          };
          transform = reduce(transform, action);
          // ...
        }
      
        function reduce(transform, action) {
        
        
          return { k, x };
        }
      

Что я сейчас вообще читаю? 😨

Использовать D3 и другие — нормально, но не помешает понимать математику под капотом

Интерактивные визуализации делают ваше приложение эффективным для пользователя

Лайк, шейр, сабскрайб

alexeyraspopov.github.io/touchy-things