Code Monkey home page Code Monkey logo

vue-clusterize's Introduction

vue-clusterize

An implementation of Clusterize.js in vue.

Works similar to v-for but only takes enough data to fill the viewport 3 times.
This data is then splitted into three clusters which will move and get filled with the right data on scrolling.

Disclaimer

Only for webpack workflows.

No jQuery dependency

Install

npm install --save-dev vue-clusterize

use version 0.2.0 before vue 1.0.24

Usage

# link the components up
components:
  "clusterize": require("vue-clusterize")
# or ES6
import clusterize from "vue-clusterize"
components: {
  "clusterize": clusterize
}
<clusterize :data="rowsData">
  <!-- default slot will be used as a template for a single row -->
  <div>{{data}}</div>
  <!-- (optional) loading slot will be displayed in each cluster which is busy fetching data - only with dynamic data -->
  <p slot="loading">loading...</p>
</clusterize>

For examples see dev/.

Available variables in template

Name type description
data Object a single datapiece (see binding-name in props)
loading Number will be 0 when finished loading data (only with dynamic data)
index Number index of the datapiece
height Number the height of a single row

you can add your own variables with the row-watchers prop.

example:

<clusterize @get-data="getData">
  <div v-if="!loading" v-bind:style="{height:height+'px'}">{{data}} - index: {{index}}</div>
  <p slot="loading">loading...</p>
</clusterize>

Props

Name type default description
binding-name String "data" name to access the data in your template
height Number null Height of the clusterize element
auto-height Boolean false If autoheight should be used (see below)
manual-start Boolean false rendering doesn't start on ready (call start on the component instance instead)
data Array [] static data to render
scroll-top Number 0 sets scrollTop
scroll-left Number 0 sets scrollLeft
cluster-size-fac Number 1.5 determines the cluster size relative to visible size
row-height Number null enforced row-height, will be determined at runtime when not set
template String - row template (defaults to slot content)
style Object - to pass trough style (vue object)
row-watchers Object {height: {vm: this, prop:"rowHeight"}} variables, will be available in template
parent-vm Object this.$parent where to resolve components in template
flex Boolean false allow multiple items per row. See flex.
flex-initial Number 20 data pieces to take for calculation of row height (should fill several rows)
flex-fac Number 1 reduce to reduce items per row

Autoheight

There are two ways clusterize can be used, either use a fixed height:

<clusterize :data="rowsData" :height="400" v-ref:clusterize>

Or use autoheight:

<html style="height:100%">
  <body style="height:100%">
    <div style="position:relative">
      <clusterize :data="rowsData" auto-height>

In this case clusterize will always fill the nearest parent element with either position:relative; or position:absolute;.
Keep in mind, that padding of the parent will be ignored. If you need a padding, use a wrapper <div>.

Dynamic data

The clusterize instance emits two events to get dynamic data:

<clusterize @get-data="getData" @get-data-count="getDataCount">
methods:
  # For the first datapiece, first and last will be 0
  getData: function(first,last,cb) {
      # somehow get data
      cb(data)
    }
  getDataCount: function(cb) {
    cb(dataCount)
  }

To issue a manual redraw, call redraw() on the clusterize instance.

If you want to enforce a scroll-to-top use the scrollTop prop.

Flex

When using the flex prop, the usage changes. You will now recieve a array of row items per row which you can use in a v-for:

<clusterize :data="rowsData" flex>
  <div style="display:flex;align-items:center;justify-content:space-between">
    <div v-for="d in data">{{d}}</div>
  </div>
</clusterize>

The row height, items per row and rows per cluster will be recalculated on resize of clusterize.

Development

Clone repository.

npm install
npm run test

Browse to http://localhost:8080/.

To-Do

  • use html5 history mode or document.store to save scroll position

License

Copyright (c) 2016 Paul Pflugradt Licensed under the MIT license.

vue-clusterize's People

Contributors

paulpflug avatar rendom avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vue-clusterize's Issues

redraw() does not work....

   watch: {
        playList() {
            console.log('update');
            this.$refs.cluster.redraw();
            // or this one: setTimeout(() => this.$refs.cluster.redraw(), 500);
        }
    },

and i see 'update at console,but list had not updated until i scroll it.
PS: playList is an async function array so it couldn't be binding directly.

But below is worked

    watch: {
        playList() {
            console.log('update');
            let x = this.$refs.cluster.$el.scrollTop;
            this.$refs.cluster.$el.scrollTop = x + 1;
            setTimeout(() => this.$refs.cluster.$el.scrollTop = x, 500);
        }
    }

How can i use this fuction?

Can I get the index?

Like this

<clusterize :data="rowsData">
  <clusterize-row>{{index}} - {{data}}</clusterize-row>
  <p slot="loading">loading...</p>
</clusterize>

createAnchor

Not sure if I'm doing something wrong or if this library is broken with latest vue? Is this project active?
I get following error Uncaught TypeError: Cannot read property 'createAnchor' of undefined

this.end = this.Vue.util.createAnchor('clusterize-cluster-end');

Working with VueJS 2.1.0 ?

Hi,

will there be a version coming to match VueJS 2.1.0's changes, which are really different from VueJS 1.x.x ?

Or is it safe to use this version of your component with VueJS 2.x.x ?

help

hi
I am a Chinese Vue user,vue-clusterize can use by src link way, es5

Mixed height on rows

Is it not possible to have mixed heights on rows?

Example:
screenshot_04

<clusterize :data="magi" auto-height>
    <div style="background:red; border-bottom: 1px solid black; height: 80px; padding-top:20px; margin-top:50px;" v-if="data.type=='header'">
        @{{data.name}}
    </div>
    <div v-else style="border-bottom: 1px solid black">
        @{{data.name}}
    </div>

    <p slot="loading">Loading...</p>
</clusterize>

MutationObserver in IE10

Hey!

I know that IE10 doesn’t support MutationObserver. Vue fallbacks to setTimeout for such cases.
However vue-clusterize somehow throws an error when run on IE9-10.
mutationObserver is undefined
I’ve been looking into your code and it doesn’t use the MutationObserver directly, so it’s hard for me to guess where the problem originates.

Do you plan on supporting IE10?
If not, it might be a good idea to add info about supported browsers to readme.md.

Uncaught TypeError: Cannot read property 'nr' of undefined

clusterize.js:374

        absI = absIs[n];
        relI = absI % 3;
        if (this.clusters[relI].nr !== absI || repaint) {

and i found that rell is -1

clusterVisible == 1 and clustersCount == 2 and clustersBelow == 0
absIs = [-1, 0, 1]
absI = -1
relI = absI % 3; //=-1

I think this case you can just detect it and return because all item are rendered, nothing need to do..

Logic repeating because of shared _uid of child components

I noticed a problem in component logic of clusterized child components.

Assuming the child component looks like this:

example: 
{
    props: ['index'],

    template: '<div :style="(selected) ? 'background:red' : ''" v-on:click="selected=!selected">{{ index }}</div>',

    data: function()
    {
        return {
            selected: false
        }
    },
}

While the "index" property is properly set and displayed on clusterized components, it doesn't seem to be possible to keep logic within a unique child component because of the shared _uid's. So if you click on the component with the index of 1, you will see it will be repeated further down the list (in my case the component with an index of 60 has the same "selected" state... as well as 120, 180 and so on).

Applying a unique _uid to each component via track-by helps with the "selected" logic, but slows down the scrolling tremendously eliminating the advantages of vue-clusterize.

Is there any way to solve this?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.