Clusterize.js

Star Star

Tiny plugin to display large data sets easily


Follow these easy steps to see the benefits that clusterize.js provides

  • Step 1 Fill table with 5.000 rows
  • Step 2 Scroll table. Feels laggy, right? ➜
  • Step 3 Let's fix it. Init clusterize.js
  • Step 4 Scroll again. Much better, huh? ➜
  • Step 5 Let's append 100.000 rows more
  • Step 6 Noticed any difference? ➜
  • Step 7 How about 400.000 rows at once?
  • Step 8 Works smoothly as well, doesn't it? :) ➜
Process step 1
Row № Scroll progress %
No data, follow steps on the left
Rows: 0
How does it work?

The main idea is not to pollute DOM with all used tags. Instead of that - it splits the list to clusters, then shows elements for current scroll position and adds extra rows to top and bottom of the list to emulate full height of table so that browser shows scrollbar as for full list

Clusterize table example
May it be used for anything other than a table? Sure!
Ordered list Customized CSS counters!
  1. Loading…
Rows: 0
Unordered list
  • Loading…
Rows: 0
DIV's
Loading…
Rows: 0
 
And so on… Basically, it may be almost any tag you wish.
Quickstart
bower install clusterize
npm install clusterize.js
Include it on your page
<link href="./clusterize.css" rel="stylesheet">
<script src="./clusterize.min.js"></script>
Modules:
AMD
CommonJS
Usage

<!--HTML-->
<div class="clusterize">
  <table>
    <thead>
      <tr>
        <th>Headers</th>
      </tr>
    </thead>
  </table>
  <div id="scrollArea" class="clusterize-scroll">
    <table>
      <tbody id="contentArea" class="clusterize-content">
        <tr class="clusterize-no-data">
          <td>Loading data…</td>
        </tr>
      </tbody>
    </table>
  </div>
</div>

<!--HTML-->
<div class="clusterize">
  <table>
    <thead>
      <tr>
        <th>Headers</th>
      </tr>
    </thead>
  </table>
  <div id="scrollArea" class="clusterize-scroll">
    <table>
      <tbody id="contentArea" class="clusterize-content">
        <tr><td>First row</td></tr>
        <tr><td>Second row</td></tr>
        <tr><td>…</td></tr>
      </tbody>
    </table>
  </div>
</div>

<!--HTML-->
<div id="scrollArea" class="clusterize-scroll">
  <ol id="contentArea" class="clusterize-content">
    <li class="clusterize-no-data">Loading data…</li>
  </ol>
</div>

<!--HTML-->
<div id="scrollArea" class="clusterize-scroll">
  <ol id="contentArea" class="clusterize-content">
    <li>First row</li>
    <li>Second row</li>
    <li>…</li>
  </ol>
</div>

<!--HTML-->
<div id="scrollArea" class="clusterize-scroll">
  <ul id="contentArea" class="clusterize-content">
    <li class="clusterize-no-data">Loading data…</li>
  </ul>
</div>

<!--HTML-->
<div id="scrollArea" class="clusterize-scroll">
  <ul id="contentArea" class="clusterize-content">
    <li>First row</li>
    <li>Second row</li>
    <li>…</li>
  </ul>
</div>

<!--HTML-->
<div id="scrollArea" class="clusterize-scroll">
  <div id="contentArea" class="clusterize-content">
    <div class="clusterize-no-data">Loading data…</div>
  </div>
</div>

<!--HTML-->
<div id="scrollArea" class="clusterize-scroll">
  <div id="contentArea" class="clusterize-content">
    <div>First row</div>
    <div>Second row</div>
    <div>…</div>
  </div>
</div>

// JavaScript
var data = ['<tr>…</tr>', '<tr>…</tr>', …];
var clusterize = new Clusterize({
  rows: data,
  scrollId: 'scrollArea',
  contentId: 'contentArea'
});

// JavaScript
var clusterize = new Clusterize({
  scrollId: 'scrollArea',
  contentId: 'contentArea'
});

// JavaScript
var data = ['<li>…</li>', '<li>…</li>', …];
var clusterize = new Clusterize({
  rows: data,
  scrollId: 'scrollArea',
  contentId: 'contentArea'
});

// JavaScript
var clusterize = new Clusterize({
  scrollId: 'scrollArea',
  contentId: 'contentArea'
});

// JavaScript
var data = ['<li>…</li>', '<li>…</li>', …];
var clusterize = new Clusterize({
  rows: data,
  scrollId: 'scrollArea',
  contentId: 'contentArea'
});

// JavaScript
var clusterize = new Clusterize({
  scrollId: 'scrollArea',
  contentId: 'contentArea'
});

// JavaScript
var data = ['<div>…</div>', '<div>…</div>', …];
var clusterize = new Clusterize({
  rows: data,
  scrollId: 'scrollArea',
  contentId: 'contentArea'
});

// JavaScript
var clusterize = new Clusterize({
  scrollId: 'scrollArea',
  contentId: 'contentArea'
});
Options
Name Required Description
rows It depends
If you render rows by yourself - pass array of tags in String. This way is preferable.
Example: ['<tr><td>First</td></tr>', '<tr><td>Second</td></tr>'];
If you need to use existing markup - do not specify this option at all.
scrollId or scrollElem Required Id or DOM node of parent tag which used as scroll area. Example: scrollId: 'scrollArea' or scrollElem: document.getElementById('scrollArea')
contentId or contentElem Required Id or DOM node of tag where content will be placed. Example: contentId: 'contentArea' or contentElem: document.getElementById('contentArea')
tag Optional Tag name for supporting elements: spacing extra rows, empty-data row. It will be determined by itself once data provided, so it's optional. But if your data is not provided during initialization - it is better to specify this option because otherwise plugin will be unable to correctly render empty-data row. Example: 'tr'. Default: null
rows_in_block Optional Amount of rows in block. Increase means browser will be more loaded, decrease means browser will have to update clusters more often. This example would help to understand this property easier. Good practice will be to keep rows_in_block as amount of visible rows in your list. Must be even to keep parity. Default: 50
blocks_in_cluster Optional Amount of blocks in cluster. When scroll reaches last block - content replaces with next cluster. Default: 4
show_no_data_row Optional Specifies whether to display an "empty" placeholder row if there is no data provided. Default: true
no_data_text Optional Text for placeholder element if there is no data provided. Default: 'No data'
no_data_class Optional Class for placeholder element if there is no data provided. Default: 'clusterize-no-data'
keep_parity Optional Add extra tag to keep parity of rows. Useful when used :nth-child(even/odd). Default: true
Methods
Name Parameter Description
.update() Array Updates list with new data
.append() Array Appends new data to the list
.prepend() Array Prepends new data to the list
.refresh() Bool Refreshes row height. Clusterize must always know current row height. It watches for window resize by itself but the width of the container may be changed programmatically, for example by dynamic neighboring elements, which could lead to a change in the height of rows. In such cases, you must call .refresh () to force Clusterize get new row height.
Optional parameter (true) may be passed to force update Clusterize's processing, even if row height hasn't been changed. See #85 to get idea when it needed.
.getRowsAmount() Returns total amount of rows
.getScrollProgress() Returns current scroll progress
.clear() Clears the list
.destroy() Bool Destroys clusterize instance. Parameter: true - removes all data from the list, not specify or false - inserts all hidden data to the list
Callbacks
Name Description
clusterWillChange Will be called right before replacing previous cluster with new one.
clusterChanged Will be called right after replacing previous cluster with new one.
scrollingProgress Will be called on scrolling. Returns progress position.

// Callbacks usage example
var clusterize = new Clusterize({
  …
  callbacks: {
    clusterWillChange: function() {},
    clusterChanged: function() {},
    scrollingProgress: function(progress) {}
  }
});
Playground
</> </> </> </> </> </> </>
Row № Scroll progress %
Loading…
Rows: 0
FAQ
Rendered structure and classses (in case you decided to use tables)

<div class="clusterize">
  <table>
    <thead>
      <tr>
        <th>Headers</th>
      </tr>
    </thead>
  </table>
  <div id="scrollArea" class="clusterize-scroll">
    <table>
      <tbody id="contentArea" class="clusterize-content">
        <tr class="clusterize-extra-row clusterize-keep-parity"></tr>
        <tr class="clusterize-extra-row clusterize-top-space" style="height:12345px;"></tr>

        <!--tr>Your (rows_in_block * blocks_in_cluster) rows</tr-->
        
        <tr class="clusterize-extra-row clusterize-bottom-space" style="height:12345px;"></tr>
      </tbody>
    </table>
  </div>
</div>
Changelog
Browsers support
Browsers limitations !

Although Clusterize allows to use unlimited amount of rows all browsers have height limitations so be aware of that, use wisely and don't go crazy with it.

Author
Denis Lukov [ GitHub | LinkedIn | Twitter ], special thanks to igorrynkovoy for the concept
Contact me
If you enjoyed this you might also like: New!