Desenvolvimento

5 jun, 2018

Aumentando a comunidade de visualização de dados com deck.gl v5

Publicidade

No dia 25 de maio, a equipe de visualização da Uber abriu o código do deck.gl 5.3, a versão final do deck.gl v5 do nosso software de visualização de dados. As versões v5 representam um grande esforço dedicados a tornar o deck.gl mais fácil de usar do que nunca, e esperamos que compartilhando a história por trás dessas melhorias, possamos deixar os usuários animados para experimentar as novas APIs e recursos simplificados do deck.gl v5.

A API multi-view deck.gl v5 oferece novas perspectivas.

Quando lançamos o deck.gl v1 em 2016, estávamos pensando na crescente comunidade de pessoas que queriam fazer uma visualização de grandes volumes de dados na web. Em particular, ao abrir o código do deck.gl, convidamos outras pessoas a usar e construir o framework. Cultivamos a esperança de criar uma comunidade colaborativa de visualização WebGL que se estendesse para além da própria organização de engenharia da Uber, permitindo que nos envolvêssemos com outras pessoas que compartilham nossa paixão pela visualização.

O deck.gl v4 seguiu uma fase de desenvolvimento rápido de recursos, durante a qual introduzimos o suporte para exploração geoespacial avançada, juntamente com novos recursos de visualização não-espacial. Mas, enquanto trabalhamos na adição de recursos, ouvimos a crescente comunidade para entender o que torna a adoção do deck.gl atraente e o que se impede de usá-la. Logo percebemos que, para continuar crescendo na comunidade do deck.gl, precisávamos remover o maior número possível de barreiras à adoção.

Na v4, apresentamos uma série de novas demos e exemplos que visam facilitar o uso do framework por outras pessoas. Com base nisso, o principal objetivo do deck.gl v5 é tornar o uso do framework mais fácil e permitir um desenvolvimento mais rápido e uniforme de visualizações com tecnologia WebGL.

As principais áreas de foco através das quais o deck.gl v5 aborda esse desafio, são:

  • Uma API JavaScript pura: acessibilidade deck.gl para todos os usuários JavaScript (não-React)
    Agnosticismo do framework: uma filosofia declarada relacionada ao deck.gl para vários frameworks de interface do usuário
  • Suporte para scripts: suporte para programadores casuais para visualizar dados com deck.gl
  • Facilidade de uso: remoção dos cantos irregulares da API deck.gl

Uma API JavaScript pura

Para tornar o deck.gl acessível para um grupo maior de usuários, nossa primeira tarefa foi possibilitar o uso do deck.gl sem o React. Afinal, a necessidade de visualizar grandes volumes de dados na web, claramente não é exclusiva dos desenvolvedores do React, mas as versões anteriores do deck.gl eram compatíveis apenas com o React, criando uma barreira significativa para a entrada de usuários não familiarizados com o framework React.

Embora muitos códigos precisassem de modificação, a parte mais importante de tornar o deck.gl independente do React, foi decidir como a nova API não baseada no React deveria parecer. Queríamos que as APIs React, JavaScript e de scripts fossem as mais semelhantes, por isso optamos pela filosofia “One API”, o que significa que, com algumas diferenças na forma como a API é inicializada, quase todas as classes e propriedades têm o mesmo nome e semântica entre as versões.

Nossa abordagem “One API” funcionou para o deck.gl porque, mesmo na versão do React, quase toda a API deck.gl já estava exposta na forma de classes JavaScript simples e independentes do React. Apenas o componente principal DeckGL, que era necessário para usar o restante da API, era um componente React.

Adicionamos uma classe JavaScript Deck de alto nível, tomando exatamente as mesmas propriedades do componente React existente (para manter as APIs em sincronia, reconstruímos o componente React para ser um wrapper em torno do componente Deck).

Como qualquer desenvolvedor de deck.gl pode ver no código abaixo, um aplicativo deck.gl não baseado em React usa exatamente as mesmas propriedades da versão do DeckGL React. Eles são fornecidos apenas através da API um pouco diferente na nova classe Deck:

import {Deck, MapController} from '@deck.gl/core';
import {GeoJsonLayer} from '@deck.gl/core-layers';

// source: Natural Earth http://www.naturalearthdata.com/ via geojson.xyz
const GEOJSON =
  'https://d2ad6b4ur7yvpq.cloudfront.net/naturalearth-3.3.0/ne_110m_admin_1_states_provinces_shp.geojson'; //eslint-disable-line

const INITIAL_VIEW_STATE = {
  latitude: 40,
  longitude: -100,
  zoom: 3,
  bearing: 30,
  pitch: 30
};

export const deck = new Deck({
  width: '100%',
  height: '100%',
  initialViewState: INITIAL_VIEW_STATE,
  controller: MapController,
  layers: [
    new GeoJsonLayer({
      data: GEOJSON,
      stroked: true,
      filled: true,
      lineWidthMinPixels: 2,
      opacity: 0.4,
      getLineColor: () => [255, 100, 100],
      getFillColor: () => [200, 160, 0, 180]
    })
  ]
});

Agnosticismo do framework

Através do nosso trabalho na API JavaScript pura em deck.gl v5, projetamos todas as dependências do React a partir do deck.gl. Como resultado, já que o deck.gl agora suporta oficialmente o uso de qualquer framework de UI do JavaScript (como o React) e agora pode ser usado como base para construir integrações com outros frameworks de interface do usuário (como o Angular), podemos dizer que o deck.gl é um framework agnóstico. Abaixo, descrevemos o que o agnosticismo do framework realmente significa para usuários novos e existentes.

E o React?

Embora o framework seja agnóstico, o deck.gl ainda está 100% comprometido com sua integração com o React. Embora o componente DeckGL React seja agora um wrapper em cima da nova classe JavaScript Deck, todas as classes JavaScript no deck.gl são cuidadosamente projetadas para funcionar com bom desempenho nos aplicativos React (embora uma explicação completa do que isso significa esteja fora do escopo deste texto, para obter uma amostra dos problemas envolvidos, considere que os aplicativos React redesenham conceitualmente toda a interface do usuário sempre que alguma parte do estado do aplicativo for alterada).

Outros frameworks (Angular, Polymer, Vue, etc)

Adoraríamos ver o deck.gl sendo usado com outros frameworks. Com a disponibilidade de uma API JavaScript pura e oficial, tornamos muito mais fácil para os desenvolvedores de aplicativos fazerem as integrações que precisam, usando seus frameworks de escolha e para a comunidade criar versões pré-empacotadas de tais integrações. Enquanto não estamos trabalhando atualmente nessas integrações, ficaremos felizes em apoiar esses esforços de portabilidade.

Nova API de scripting

A nova API JavaScript foi um ótimo começo para ampliar nossa base de usuários. Mas nos perguntávamos se poderíamos tornar o deck.gl ainda mais fácil de usar para nossos desenvolvedores. Mesmo que o deck.gl não precisasse mais do uso do React, ainda estávamos pedindo aos desenvolvedores que criassem um aplicativo web completo antes de começar. E sabemos que a configuração dos requisitos necessários para os arquivos de configuração de compilação, instalações de pacotes, etc, pode ser assustadora e cansativa, especialmente para um novo usuário que deseja apenas fazer uma visualização rápida.

Para facilitar o desenvolvimento, empacotamos a nova API JavaScript do deck.gl independente do React, mais fácil de usar, com algumas conveniências adicionais, como a integração automática do mapa base do Mapbox, e publicamos o pacote resultante como uma versão de script do deck.gl.

Você pode brincar com este exemplo de script deck.gl em CodePen | Observable.

Essa versão de script do deck.gl funciona fora da caixa em ambientes CodePen e Observable, abrindo o deck.gl para mais casos de uso, como prototipagem colaborativa e depuração, em que uma configuração completa do projeto é desnecessária. Confira nosso texto ”Start Scripting with deck.gl” para mais detalhes, e alguns exemplos interessantes do que o script deck.gl permite fazer com apenas algumas linhas de código.

Facilidade de uso

A terceira prioridade em termos de tornar o deck.gl mais acessível (após o agnosticismo do framework e suporte para scripts), foi refinar ainda mais a API para reduzir a curva de aprendizado para novos usuários, particularmente aqueles que codam para suportar suas tarefas primárias em vez de trabalhar como engenheiros de software dedicados.

Uma API ainda mais declarativa

Um aspecto específico de facilidade de uso que atingimos no ciclo de lançamento do deck.gl v5 foi remover a necessidade de aplicativos deck.gl implementarem callbacks. Essa mudança foi particularmente convincente, já que a API deck.gl já possui um forte sabor declarativo, em grande parte devido às suas raízes React.

Observe que o termo “API declarativa” refere-se à capacidade dos usuários de especificar o comportamento de um framework por meio de um conjunto de propriedades estáticas, em vez de definir comportamento dinâmico por meio de funções e que geralmente são consideradas mais fáceis de aprender e usar.

Assim, embora as demos deck.gl e os aplicativos simples já pudessem ser gravados de forma quase declarativa, a necessidade de implementar callbacks para ações simples, como controlar o tamanho da janela, quebrou esse fluxo limpo e acrescentou desorganização aos exemplos, dando aos usuários mais coisas com que se preocupar.

Para resolver esse problema, os cinco novos recursos automáticos do deck.gl v5 garantem que uma série de pequenas – mas comuns – complicações de programação possam agora ser tratadas trivialmente pelos programadores deck.gl.

Destaque automático

Começamos a lista de facilidade de uso com um recurso pequeno, mas muito útil: destaque de objeto baseado em GPU. O deck.gl foi projetado para ser extremamente eficiente ao renderizar grandes conjuntos de dados estáticos. No entanto, destacar um único objeto (por exemplo, ao passar o mouse sobre ele) pode exigir a atualização desses conjuntos de dados, o que poderia resultar em um impacto significativo no desempenho e exigir uma quantidade frustrante de códigos no estilo de callback para serem implementados.

Digite o recurso de destaque automático, que permite que os programadores realcem visualmente um objeto em qualquer camada deck.gl simplesmente configurando a propriedade autoHighlight como true.

Adicionar uma única propriedade a uma camada deck.gl resulta em um destaque insatisfatório da GPU.

Consideramos esse recurso como um aperitivo inicial da nossa faixa de desenvolvimento General Purpose GPU.

Espere ver mais recursos alimentados por GPU em futuros lançamentos do deck.gl. Para obter mais detalhes sobre como usar esse pequeno, mas poderoso recurso, e como ele foi implementado, confira nosso artigo sobre o tópico.

Redimensionamento automático

Uma coisa tão simples quanto rastrear o tamanho da janela do navegador adicionou uma quantidade surpreendente de código extra aos nossos exemplos básicos. No entanto, quase todo aplicativo tem que fazer isso.

Para simplificar esse processo, adicionamos suporte para especificar tamanhos relativos diretamente no componente deck.gl. Essa adição nos permite remover a desordem do ouvinte de evento de redimensionamento de janela dos exemplos de deck.gl, conforme ilustrado abaixo:

const deck = new Deck({width: '100%', height: '100%, ...'})
// or, if using react
<DeckGL width="100%" height="100%" .../>

Nota: Para alguém familiarizado com especificadores de tamanho de HTML e CSS, o recurso de redimensionamento automático pode parecer insignificante, mas é necessário adicionar um novo sistema de classe View para oferecer suporte à especificação declarativa de tamanhos relativos em toda a API. Naturalmente, as novas classes View também servirão a muitas outras funções importantes, mas ainda é uma ilustração típica de como os recursos simples geralmente precisam ser desenvolvidos em conjunto com outras coisas.

Controles automáticos

Antes do deck.gl v5, até os menores exemplos de deck.gl precisavam lembrar e atualizar continuamente um estado de exibição em resposta a eventos do usuário (o que eles fizeram definindo uma callback onViewStateChange).

Entretanto, agora a maioria dos aplicativos – que não precisam de controle de interação refinado – pode apenas especificar a propriedade initialViewState e confiar no deck.gl para manipular automaticamente as interações do usuário a partir daí.

Carregamento automático de dados de camada

Anteriormente, as camadas deck.gl só podiam aceitar dados (por meio de suas propriedades de dados) que já estavam carregados no navegador (geralmente carregados a partir de uma URL que serve dados formatados em JSON). No deck.gl v5.3, uma propriedade de dados da camada deck.gl agora pode, alternativamente, ser definida como uma string de URL, e o deck.gl carregará os dados do endereço da internet indicado e os exibirá quando estiverem prontos.

Esse recurso permite que uma fonte de dados compatível seja especificada com uma única propriedade e evita as típicas de 5 a 10 linhas de código de callback normalmente necessárias para carregar de forma assíncrona os dados antes de instanciar a camada.

// Pass URL directly as data, no need to load it first

const deck = new Deck({
  ...
  layers: [
    new ScatterplotLayer({
      data: 'https://...' 
    })
  ]
});

// or, if using React

<DeckGL ... layers={[
  new ScatterplotLayer({
    data: 'https://...'
   })
]}/>

Posicionamento automático de componentes

O posicionamento automático de componentes permite que os aplicativos tenham componentes HTML adicionais, como mapas e rótulos de base, para serem posicionados automaticamente sob viewports deck.gl, o que é especialmente eficiente ao usar várias exibições.

import DeckGL, {MapView, FirstPersonView} from 'deck.gl';
// Multiple views and an auto-positioned base map
const views = [
  new FirstPersonView({...}),
  new MapView({id: 'basemap', ...})
];

render() {
  return (
    <DeckGL
      width={width}
      height={height}
      layers={this._renderLayers()}
      views={views} />

      <StaticMap
        viewId='basemap'
        {...viewState}/>

    </DeckGL>
  );
}

Transições de atributos

Por fim, outro recurso da nossa faixa de desenvolvimento do GPGPU em andamento é a capacidade do deck.gl de suavizar automaticamente a transição entre diferentes conjuntos de big data. O recurso é semelhante às transições CSS no desenvolvimento web clássico, com a diferença de que o deck.gl interpola milhões de valores, muitas vezes por segundom, diretamente na GPU.

Exemplos simplificados

Como outro esforço para tornar o deck.gl mais fácil de implementar para novos usuários, estamos analisando o código-fonte de nossos exemplos, reescrevendo cuidadosamente o código-fonte para aproveitar os novos recursos da v5 para garantir que não perdemos nenhuma oportunidade (incluindo o uso de nossas novas APIs sem callback) para torná-las mais simples para um novo programador digerir.

Recursos

Embora nosso foco tenha sido tornar o deck.gl mais fácil de implementar para um espectro mais amplo de usuários (técnicos e não técnicos), obviamente não paramos de adicionar recursos de visualização.

TextLayer

Antes tarde do que nunca, o novo TextLayer preenche uma lacuna importante no catálogo de camadas do deck.gl, finalmente fornecendo aos usuários do deck.gl, a capacidade de trabalhar de forma mais eficiente com o texto no WebGL.

Esse exemplo do novo TextLayer mostra hashtags referentes a locais de um conjunto de dados retirado de hashtags públicas do Twitter.

O novo TextLayer vem com um conjunto de recursos de personalização, como a capacidade de especificar fontes e conjuntos de caracteres. E se o desempenho do TextLayer for uma preocupação, este mostruário no site deck.gl deve tirar todas as suas dúvidas.

API Multi-view

Uma nova propriedade Deck.views permite que o aplicativo especifique várias classes View. Os novos Views aceitam parâmetros de tamanho relativo, permitindo que eles trabalhem perfeitamente com o novo recurso de redimensionamento automático.

Seleção profunda

Com o aumento do uso em aplicativos de visualização híbridos mais interativos, o deck.gl precisa corresponder aos recursos oferecidos pelas bibliotecas WebGL tradicionais, baseadas em gráfico de cena. Um dos recursos mais solicitados é a capacidade de identificar todos os objetos em um determinado pixel, não apenas o objeto mais alto renderizado na tela.

Para esse fim, o deck.gl v5 fornece uma nova função de seleção com um parâmetro de profundidade que permite que o aplicativo identifique várias correspondências sob o cursor ao escolher (efetivamente selecionando objetos ocluídos).

Deck.pickMultipleObjects({x, y, depth: 10});

Suporte para teste de regressão visual

Um novo sub-módulo deck.gl (@deck.gl/test-utils) oferece suporte para testes automatizados, fornecendo forte suporte de framework para o que geralmente é considerado um ponto em branco na comunidade de testes WebGL.

 

Para uma lista ainda mais detalhada de recursos, confira a documentação online do deck.gl.

Investimentos adicionais na comunidade deck.gl

Um ciclo de lançamento mais rápido

Para responder mais rapidamente aos novos requisitos, o deck.gl está adotando um calendário de lançamento mensal mais rápido com uma cadência de destino de aproximadamente três lançamentos mensais menores (incorporando novos recursos incrementais) seguidos por um lançamento principal.

Roadmap aberto

Também queremos que o roadmap do deck.gl seja o mais aberto possível, dando aos usuários uma noção de quais recursos estão chegando e de que os colaboradores podem se envolver conosco em pé de igualdade.

Para isso, publicamos um extenso catálogo de RFCs técnicos, permitindo que qualquer usuário participe das discussões de design sobre novos recursos, e adicionamos uma página de roadmap. Estamos considerando maneiras adicionais de permitir maior participação. Por favor, abra uma issue no GitHub se tiver sugestões.

Seguindo em frente

O amplo foco em tornar o framework deck.gl v5 mais fácil de usar o transformou em uma plataforma de visualização de dados significativamente mais acessível e fácil de usar.

E com o novo e mais flexível ciclo de lançamento em combinação com a abertura do roadmap do deck.gl, esperamos levar mais componentes, contribuições, colaborações e parcerias baseadas no deck.gl para a comunidade de visualização de dados. Nós já temos várias coisas importantes em andamento e estamos ansiosos para saber o que o futuro reserva para o projeto deck.gl e sua crescente comunidade de colaboradores!

A equipe de visualização da Uber abriu o código dos seguintes projetos: deck.gl, kepler.gl, luma.gl, react-vis e react-map-gl. Se você quiser conhecer todos os projetos open source do Uber, confira nossa página do GitHub e, se estiver interessado em se juntar à nossa equipe, visite a página Uber Careers.

Assine nossa newsletter para acompanhar as mais recentes inovações da Uber Engineering.

***

Este artigo é do Uber Engineering. Ele foi escrito por Ib Green. A tradução foi feita pela Redação iMasters com autorização. Você pode conferir o original em: https://eng.uber.com/deckgl-v5/