Grade de dados JavaScript para milhões de linhas [fechada]

225

Eu preciso apresentar um grande número de linhas de dados (ou seja, milhões de linhas) ao usuário em uma grade usando JavaScript.

O usuário não deve ver páginas ou exibir apenas quantidades finitas de dados por vez.

Em vez disso, deve parecer que todos os dados estão disponíveis.

Em vez de baixar os dados de uma só vez, pequenos blocos são baixados conforme o usuário os acessa (ou seja, rolando pela grade).

As linhas não serão editadas nesse front end, portanto, as grades somente leitura são aceitáveis.

Quais grades de dados, escritas em JavaScript, existem para esse tipo de paginação direta?

Rudiger
fonte
1
Eu aceitei a resposta jqgrid, pois parece falhar em grandes conjuntos de dados ... Alguma outra sugestão? E o ext-livegrid.com ?
Rudiger
6
Escreva o seu próprio. Tenho certeza de que os outros estão engasgando porque continuam anexando ao DOM. Eu acho que você precisará de uma solução que remova linhas enquanto elas rolam para fora da tela. Essa é a unica maneira. Você simplesmente não pode ter um milhão de linhas de tabela no DOM e espera que todos os navegadores sejam exibidos e rolem sem problemas em todos os ambientes. Seja razoável.
Josh Stodola
2
@ Rudiger: O SlickGrid agora suporta um número ilimitado de linhas de forma nativa. Consulte github.com/mleibman/SlickGrid/tree/unlimited-rows . Uma vez testado completamente, ele será incorporado ao ramo principal.
Tin
10
E sinto muito por qual empresa você está trabalhando. Para sua informação, uma tela 1920x1080 com apenas 1 milhão de linhas exibidas saltará 20 linhas para cada pixel de movimento na barra de rolagem. Faça alguns testes de usabilidade em vez de perder seu tempo.
Sleeper Smith
2
Esta pergunta e suas duas principais respostas (pelo menos) são extremamente úteis. Pode ter atraído algumas respostas de baixa qualidade, mas essa pergunta não deve ser encerrada. O uso do SlickGrid para resolver esse problema pode economizar muitas horas de problemas e codificação difícil, se as pessoas tentarem reimplementá-las.
Sam Watkins

Respostas:

190

( Isenção de responsabilidade: eu sou o autor do SlickGrid )

ATUALIZAÇÃO Agora isso foi implementado no SlickGrid .

Consulte http://github.com/mleibman/SlickGrid/issues#issue/22 para uma discussão contínua sobre como fazer o SlickGrid funcionar com um número maior de linhas.

O problema é que o SlickGrid não virtualiza a própria barra de rolagem - a altura da área rolável é definida como a altura total de todas as linhas. As linhas ainda estão sendo adicionadas e removidas à medida que o usuário está rolando, mas a rolagem em si é feita pelo navegador. Isso permite que seja muito rápido e suave (os eventos de rolagem são notoriamente lentos). A ressalva é que existem bugs / limites nos mecanismos CSS dos navegadores que limitam a altura potencial de um elemento. Para o IE, é 0x123456 ou 1193046 pixels. Para outros navegadores, é maior.

Há uma solução experimental no ramo "correção de largenum" que aumenta esse limite significativamente ao preencher a área de rolagem com "páginas" definidas para 1M pixels de altura e, em seguida, usar o posicionamento relativo nessas páginas. Como o limite de altura no mecanismo CSS parece ser diferente e significativamente menor do que no mecanismo de layout real, isso nos dá um limite superior muito mais alto.

Ainda estou procurando uma maneira de obter um número ilimitado de linhas sem abrir mão da margem de desempenho que o SlickGrid atualmente possui sobre outras implementações.

Rudiger, você pode elaborar como resolveu isso?

Lata
fonte
1
Eu achei o SlickGrid o mais atraente - especialmente se alguém trabalha com o jQuery. Parabéns! (especialmente pela grande atitude e persistência.) :-)
Andras Vass
Estou tentando usar o slickgrid para mostrar os cabeçalhos do excel e estou vendo que, ao ter muitas colunas, o slickgrid otimiza apenas a rolagem das linhas e não das colunas. Eu também notei que, ao ter mais de 120 colunas, o slickgrid coloca as novas linhas em uma nova linha. O número máximo de linhas pode ser definido em algum lugar nos arquivos?
oneiros
1
O SlickGrid v2.1 usa rolagem virtual para colunas e linhas. Além disso, o problema de colunas transbordantes foi resolvido.
27512 da lata
@ Tin - Isso é semelhante à minha abordagem; Eu estava anos à frente do meu tempo! "Um primitivo de layout de bloco lento para criar rolagem infinita em aplicativos da web." docs.google.com/document/d/…
Rudiger 19/09/2013
@ Rudiger Sim, eu já vi isso no grupo Blink cerca de um mês atrás, mas não tenho muita certeza de como isso se encaixa na imagem. O layout lento opera com elementos realmente presentes no DOM, o que não podemos realmente fazer. Por favor explique :)
Tin
84

https://github.com/mleibman/SlickGrid/wiki

"O SlickGrid utiliza renderização virtual para permitir que você trabalhe facilmente com centenas de milhares de itens sem diminuir o desempenho. De fato, não há diferença no desempenho entre trabalhar com uma grade com 10 linhas versus 100.000 linhas " .

Alguns destaques:

  • Rolagem virtual adaptável (manipule centenas de milhares de linhas)
  • Velocidade de renderização extremamente rápida
  • Pós-renderização em segundo plano para células mais ricas
  • Configurável e personalizável
  • Navegação completa pelo teclado
  • Redimensionar / reordenar / mostrar / ocultar coluna
  • Dimensionamento automático da coluna e ajuste de força
  • Formadores e editores de células conectáveis
  • Suporte para editar e criar novas linhas. "por mleibman

É grátis (licença MIT). Ele usa jQuery.

Andras Vass
fonte
Funciona bem até precisamente 131.001 linhas ... Ou seja, há uma linha de código como esta: data.length = Math.min(131000, parseInt(resp.total));... E, é claro, isso codificado por um motivo :(
Rudiger
6
Demorou um pouco de trabalho, mas fiz algumas alterações para tornar a grade independente do comprimento da datamatriz. É um erro, mas eu tenho as respostas preenchendo uma bigdatamatriz, e os menores datapuxa da bigdatamatriz. O restante do programa usa a matriz de dados menor, exceto a medição da barra de rolagem e alguns outros locais que agora são ilimitados para um grande número de linhas. Em suma, era muito mais fácil do que escrever minha própria.
Rudiger
8
@ Rudiger: O SlickGrid agora suporta um número ilimitado de linhas de forma nativa. Consulte github.com/mleibman/SlickGrid/tree/unlimited-rows . Uma vez testado completamente, ele será incorporado ao ramo principal.
Tin
Estou tentando usar o slickgrid para mostrar os cabeçalhos do excel e estou vendo que, ao ter muitas colunas, o slickgrid otimiza apenas a rolagem das linhas e não das colunas. Eu também notei que, ao ter mais de 120 colunas, o slickgrid coloca as novas linhas em uma nova linha. O número máximo de linhas pode ser definido em algum lugar nos arquivos?
oneiros
se você quiser algo realmente rápido, não confie em nada que use o jquery para fazer as coisas principais e, em vez disso, use innerHTML do que o DOM anexado. As barras de rolagem Javascript podem ser notadas mais lentamente que as barras de rolagem do navegador em computadores lentos, evitam regras complexas de CSS e você deve gastar tempo simplificando o layout de uma única linha. As micro-otimizações podem ser significativas neste caso. Essas são apenas práticas gerais para melhorar o desempenho. jsPerf.com é seu amigo.
Vitim.us
37

As melhores grades na minha opinião estão abaixo:

Minhas 3 melhores opções são jqGrid, jqxGrid e DataTables. Eles podem trabalhar com milhares de linhas e oferecer suporte à virtualização.

scripto
fonte
1
+1 na lista, embora não haja muito em termos de comparação. Um bom começo seria adicionar o número de confirmações para cada um - 33 para o Flexigrid a partir de agora, contra 491 para o SlickGrid.
Dan Dascalescu
12
Parafuso limite de edição de comentários de 5 minutos do SO. # 1 - jqGrid - mais de 1000 confirmações ; # 2 - 752 para DataTables ; # 3-491 para SlickGrid ; # 4-33 confirma para Flexigrid . Ingrid - nenhuma atualização desde junho de 2011 . jqGridView - nenhuma atualização desde 2009
Dan Dascalescu
3
Com base no comentário anterior, incluí o número de garfos por projeto aqui: # 1 - SlickGrid - 670 garfos; # 2 - jqGrid - 358 garfos; # 3 - Flexigrid - 238; # 4 - Tabelas de dados - 216; # 5 - Ingrid - 41; # 6 - jqGridView - 0;
Ljs.dev
1
Dê uma olhada em nexts.github.io/Clusterize.js
Denis
Posso comentar que o Slickgrid ainda está vivo e bem, mas o mleibman repo mencionado acima está morto. Novo link: github.com/6pac/SlickGrid (referências mleibman-lo em uma nota final sobre a sua repo), ou www.slickgrid.net
Ben McIntyre
25

Não pretendo iniciar uma guerra de chamas, mas, assumindo que seus pesquisadores são humanos, você não os conhece tão bem quanto pensa. Só porque eles têm petabytes de dados não os torna capazes de visualizar milhões de registros de maneira significativa. Eles podem dizer que querem ver milhões de registros, mas isso é bobagem. Faça com que seus pesquisadores mais inteligentes façam algumas contas básicas: suponha que eles gastem 1 segundo visualizando cada registro. Nesse ritmo, levará 1000000 segundos, o que ocorre por mais de seis semanas (de 40 horas semanais de trabalho sem interrupções para alimentação ou lavatório).

Eles (ou você) pensam seriamente que uma pessoa (a que está olhando para a grade) pode reunir esse tipo de concentração? Eles estão realmente realizando muito nesse primeiro segundo, ou estão (mais provavelmente) filtrando as coisas que não querem? Suspeito que, depois de exibir um subconjunto "de tamanho razoável", eles possam descrever um filtro para você que filtrará automaticamente esses registros.

Como paxdiablo e Sleeper Smith e Lasse V Karlsen também sugeriram, você (e eles) não considerou os requisitos. No lado positivo, agora que você encontrou o SlickGrid, tenho certeza de que a necessidade desses filtros se tornou imediatamente óbvia.

Daniel 'Dang' Griffith
fonte
2
Ter a necessidade de milhões de linhas nem sempre é visualizá-las. Às vezes, os clientes desejam um despejo parcial de registros para execução em seus próprios sistemas de análise de dados.
Cbmeeks 30/10/12
10
Se for um despejo de dados para sua própria análise, não seria exibido em uma grade em uma página da Web, seria?
Steven Benitez
5
não preciso vê-los todos de uma vez. É para isso que serve a classificação de colunas Ctrl+F. A alternativa (paginação, pesquisa no site) é muito pior. Basta olhar para o StackOverflow ao tentar rolar por perguntas ou respostas, o Reddit para rolar pelo histórico de comentários de um usuário. A classificação e a pesquisa instantânea fornecem o poder que o Windows Explorer possui, mas os sites não têm.
11558 Ian
15

Posso dizer com certeza que você não precisa mostrar milhões de linhas de dados para o usuário.

Não há usuário no mundo capaz de compreender ou gerenciar esse conjunto de dados; mesmo que você consiga executá-lo tecnicamente, não resolverá nenhum problema conhecido para esse usuário.

Em vez disso, eu focaria no motivo pelo qual o usuário deseja ver os dados. O usuário não deseja ver os dados apenas para vê-los; geralmente há uma pergunta sendo feita. Se você se concentrar em responder a essas perguntas, estará muito mais perto de algo que resolva um problema real.

Lasse V. Karlsen
fonte
16
Meus usuários são pesquisadores acostumados a petabytes de dados. Acho que conheço meus usuários um pouco melhor do que você, embora você esteja certo no caso geral. Quanto ao porquê , esse datagrid é simplesmente parte de um conjunto de ferramentas para gerenciar big data.
Rudiger
7

Eu recomendo a grade Ext JS com o recurso Buffered View.

http://www.extjs.com/deploy/dev/examples/grid/buffer.html

richardtallent
fonte
ExtJs, de fato. É basicamente construída especialmente para a apresentação dos dados
KdgDev
1
ExtJs é tão bom que eu quero chorar que não é construído em cima do jQuery
James Westgate
Agora você pode carregar apenas as partes relacionadas à grade do ExtJS, para que a adição de uma grade ExtJS ao seu aplicativo não seja muito pesada. No entanto, você ainda precisa considerar as diferenças de aparência e usar o modo ExtJS de temas apenas para esse componente.
JD Smith
7

(Isenção de responsabilidade: eu sou o autor do w2ui)

Recentemente, escrevi um artigo sobre como implementar a grade JavaScript com 1 milhão de registros ( http://w2ui.com/web/blog/7/JavaScript-Grid-with-One-Million-Records ). Descobri que, no final das contas, existem três restrições que impedem o aumento:

  1. A altura da div tem um limite (pode ser superada pela rolagem virtual)
  2. Operações como classificação e pesquisa começam a ficar lentas depois de 1 milhão de registros
  3. A RAM é limitada porque os dados são armazenados na matriz JavaScript

Eu testei a grade com 1 milhão de registros (exceto o IE) e funciona bem. Veja o artigo para demonstrações e exemplos.

vitmalina
fonte
Com esse milhão de registros, sua página html tem tamanho de 3 MB, mas quando carrego meus dados, a página tem 15 MB, o w2ui consegue lidar com isso? Preciso de todos os dados para alguns cálculos.
Chetan S. Choudhary
6

O dojox.grid.DataGrid oferece uma abstração JS para dados, para que você possa conectá-lo a vários back-ends com os armazenamentos dojo.data fornecidos ou gravar seus próprios. Obviamente, você precisará de um que suporte acesso aleatório para tantos registros. O DataGrid também fornece acessibilidade total.

Edite, então aqui está um link para o artigo de Matthew Russell, que deve fornecer o exemplo de que você precisa, visualizando milhões de registros com dojox.grid. Observe que ele usa a versão antiga da grade, mas os conceitos são os mesmos, houve apenas algumas melhorias incompatíveis na API.

Ah, e é um código aberto totalmente gratuito.

peller
fonte
4

Aqui estão algumas otimizações que você pode aplicar para acelerar as coisas. Apenas pensando em voz alta.

Como o número de linhas pode estar na casa dos milhões, você desejará um sistema de armazenamento em cache apenas para os dados JSON do servidor. Não consigo imaginar alguém querendo baixar todos os X milhões de itens, mas se o fizessem, seria um problema. Este pequeno teste no Chrome para uma matriz com mais de 20 milhões de números inteiros trava na minha máquina constantemente.

var data = [];
for(var i = 0; i < 20000000; i++) {
    data.push(i);
}
console.log(data.length);​

Você pode usar LRU ou algum outro algoritmo de cache e ter um limite superior para a quantidade de dados que deseja armazenar em cache.

Para as próprias células da tabela, acho que construir / destruir nós DOM pode ser caro. Em vez disso, você pode predefinir o número X de células e sempre que o usuário rolar para uma nova posição, injetar os dados JSON nessas células. A barra de rolagem praticamente não teria relação direta com a quantidade de espaço (altura) necessária para representar o conjunto de dados inteiro. Você pode definir arbitrariamente a altura do contêiner da tabela, por exemplo, 5000 px e mapear isso para o número total de linhas. Por exemplo, se a altura do contêiner for 5000px e houver um total de 10 milhões de linhas, o starting row ≈ (scroll.top/5000) * 10Mwhere scroll.toprepresenta a distância de rolagem da parte superior do contêiner. Pequena demonstração aqui .

Para detectar quando solicitar mais dados, o ideal é que um objeto atue como um mediador que escute os eventos de rolagem. Esse objeto controla a rapidez com que o usuário está rolando e, quando parece que o usuário está mais lento ou parou completamente, faz uma solicitação de dados para as linhas correspondentes. A recuperação de dados dessa maneira significa que seus dados serão fragmentados; portanto, o cache deve ser projetado com isso em mente.

Além disso, os limites do navegador para o máximo de conexões de saída podem desempenhar um papel importante. Um usuário pode rolar para uma determinada posição que acionará uma solicitação AJAX, mas antes que isso termine, o usuário pode rolar para outra parte. Se o servidor não for responsivo o suficiente, as solicitações serão colocadas na fila e o aplicativo parecerá não responder. Você pode usar um gerenciador de solicitações através do qual todas as solicitações são roteadas e pode cancelar solicitações pendentes para liberar espaço.

Anurag
fonte
4

Eu sei que é uma pergunta antiga, mas ainda assim. Há também o dhtmlxGrid que pode lidar com milhões de linhas. Há uma demonstração com 50.000 linhas, mas o número de linhas que podem ser carregadas / processadas na grade é ilimitado.

Disclaimer: Eu sou da equipe DHTMLX.

Paulo
fonte
Quero mostrar 10 MB de dados Json e quero usá-los no cálculo. O DHTMLX pode fazer isso? Com ​​esses dados e tags html, a página do meu navegador tem cerca de 15 MB. Vale a pena usar DHTMLX?
Chetan S. Choudhary
3

Disclaimer: eu uso muito o YUI DataTable sem dor de cabeça por um longo tempo . É poderoso e estável. Para suas necessidades, você pode usar uma ScrollingDataTable que suporta

  • rolagem x
  • rolagem y
  • rolagem xy
  • Um poderoso mecanismo de eventos

Para o que você precisa, acho que você quer é um tableScrollEvent . Sua API diz

Disparado quando uma DataTable de rolagem fixa tem uma rolagem.

Como cada DataTable usa um DataSource, você pode monitorar seus dados por meio de tableScrollEvent junto com o tamanho do loop de renderização para preencher seu ScrollingDataTable de acordo com suas necessidades.

O tamanho do loop de renderização diz

Nos casos em que seu DataTable precise exibir a totalidade de um conjunto muito grande de dados, a configuração renderLoopSize pode ajudar a gerenciar a renderização DOM do navegador para que o encadeamento da UI não fique bloqueado em tabelas muito grandes . Qualquer valor maior que 0 fará com que a renderização do DOM seja executada nas cadeias setTimeout () que renderizam o número especificado de linhas em cada loop. O valor ideal deve ser determinado por implementação, uma vez que não existem regras rígidas e rápidas, apenas diretrizes gerais:

  • Por padrão, renderLoopSize é 0, portanto, todas as linhas são renderizadas em um único loop. Um renderLoopSize> 0 adiciona sobrecarga, portanto, use com cuidado.
  • Se seu conjunto de dados for grande o suficiente (número de linhas X número de complexidade de formatação das Colunas X) para que os usuários experimentem latência na renderização visual e / ou cause a interrupção do script, considere configurar um renderLoopSize .
  • Um renderLoopSize abaixo de 50 provavelmente não vale a pena. Um renderLoopSize> 100 provavelmente é melhor.
  • Um conjunto de dados provavelmente não é considerado grande o suficiente, a menos que tenha centenas e centenas de linhas.
  • Ter um renderLoopSize> 0 e <total de linhas faz com que a tabela seja renderizada em um loop (o mesmo que renderLoopSize = 0), mas também aciona funcionalidades como a faixa de linhas pós-renderização para serem manipuladas a partir de um encadeamento setTimeout separado.

Por exemplo

// Render 100 rows per loop
 var dt = new YAHOO.widget.DataTable(<WHICH_DIV_WILL_STORE_YOUR_DATATABLE>, <HOW YOUR_TABLE_IS STRUCTURED>, <WHERE_DOES_THE_DATA_COME_FROM>, {
     renderLoopSize:100
 });

<WHERE_DOES_THE_DATA_COME_FROM> é apenas um único DataSource . Pode ser um JSON, JSFunction, XML e até um único elemento HTML

Aqui você pode ver um tutorial simples, fornecido por mim. Esteja ciente de que nenhum outro plug-in DATA_TABLE suporta clique único e duplo ao mesmo tempo. YUI DataTable permite que você. E mais, você pode usá-lo mesmo com o JQuery sem dor de cabeça

Alguns exemplos, você pode ver

Sinta-se à vontade para fazer perguntas sobre qualquer outra coisa que desejar sobre o YUI DataTable.

Saudações,

Arthur Ronald
fonte
3

Eu meio que falho em entender o ponto, para jqGrid você pode usar a funcionalidade de rolagem virtual:

http://www.trirand.net/aspnetmvc/grid/performancevirtualscrolling

mas, novamente, milhões de linhas com filtragem podem ser feitas:

http://www.trirand.net/aspnetmvc/grid/performancelinq

Eu realmente não vejo o ponto de "como se não houvesse páginas", quero dizer ... não há como exibir 1.000.000 de linhas ao mesmo tempo no navegador - são 10 MB de HTML bruto, meio que não consigo ver por que os usuários não gostariam de ver as páginas.

De qualquer forma...

user125775
fonte
2

A melhor abordagem que eu poderia pensar é carregando o bloco de dados no formato json para cada rolagem ou algum limite antes que a rolagem termine. O json pode ser facilmente convertido em objetos e, portanto, as linhas da tabela podem ser construídas facilmente e sem obstruções

codificador
fonte
É assim que eu tenho. É feita uma solicitação para um conjunto de linhas enviadas de volta em JSON ... Estou procurando um renderizador do lado do cliente javascript que suporte isso!
precisa
O que??? O que diabos é "renderizador de site do cliente"? Qualquer javascript ainda precisará fazer uma chamada ajax - portanto, você ainda precisará optar por algum formato de transporte. Você não pode escapar de fazer algum trabalho. Ninguém fará isso por você, meu amigo.
Andriy Drozdyuk 16/03/10
1
Eu sei que uma ligação AJAX precisa ser feita; esta parte é simples. O cliente solicita algo como "start = 20 & limit = 20" e recupera as linhas 20-39 do servidor (formato XML ou JSON). O "renderizador do lado do cliente" (minha terminologia!) Faz essas solicitações de forma inteligente (por exemplo, quando o usuário rola para baixo) e renderiza os resultados perfeitamente em uma grade bonita. Ao contrário do que você diz, alguém fez esse trabalho por mim. É isso que todas as outras respostas a esta pergunta são.
Rudiger
Bem, parece que ninguém mais fez isso por você :)
Andriy Drozdyuk 18/03/10
1

Eu recomendo o Open rico . É difícil de implementar no começo, mas depois de agarrá-lo, você nunca mais olhará para trás.

Mosid
fonte
0

Dê uma olhada no dGrid:

https://dgrid.io/

Concordo que os usuários NUNCA, NUNCA precisam visualizar milhões de linhas de dados de uma só vez, mas o dGrid pode exibi-los rapidamente (uma tela de cada vez).

Não ferva o oceano para fazer uma xícara de chá.

ColemanTO
fonte
sua xícara de chá (link) não foi encontrada. :)
Akshay
Ela tem seu próprio site agora :)
ColemanTO