Vue-Crosstab(0.8.0)

The most complete crosstab solution for Vue.js

License

Getting started


Try it on JSFiddle

Installation

via npm

npm install vue-crosstab --save

via CDN

<script src="https://unpkg.com/vue-crosstab"></script>

Basic usage

<!-- Vue component -->
<template>
  <div>
    <crosstab
       :data="data"
       :cols="cols"
       :rows="rows"></crosstab>
  </div>
</template>

<script>
  import Crosstab from 'vue-crosstab'

  // register globally
  Vue.component(Crosstab)

  export default {
    // OR register locally
    components: { Crosstab },
    data () {
      return {
        data: [
          {
            "date": "2012/01/01",
            "precipitation": 0,
            "temp_max": 12.8,
            "temp_min": 5,
            "wind": 4.7,
            "weather": "drizzle"
          },
          {
            "date": "2012/01/02",
            "precipitation": 10.9,
            "temp_max": 10.6,
            "temp_min": 2.8,
            "wind": 4.5,
            "weather": "rain"
          },
          {
            "date": "2012/02/06",
            "precipitation": 0,
            "temp_max": 16.1,
            "temp_min": 1.7,
            "wind": 5,
            "weather": "sun"
          }
        ],
        rows: [
          {field: 'date', type: 'temporal', timeUnit: 'month', label: 'Month'}
        ],
        cols: [
          {field: 'date', type: 'temporal', timeUnit: 'year', label: 'Year'},
          {field: 'weather', label: 'Weather', aggregate: 'count'}
        ]
      }
    }
  }
</script>

Examples


Basic crosstab

The basic crosstab doesn’t require much configuration.

Optional configuration flags:

  • field: "sex" – name of data field.
  • aggregate: "sum" – sum of all aggregated measure values. Possible values: count, avg, sum, max, min. Must be last field in rows/cols.
import Crosstab from 'vue-crosstab'
import data from 'data/people.json'

export default {
  components: {
    Crosstab
  },
  data () {
    return {
      data,
      cols: [
        {field: 'sex'},
        {field: 'smoker'},
        {field: 'total_bill', aggregate: 'sum', formatter: 'currency'}
      ],
      rows: [
        {field: 'day'},
        {field: 'time'}
      ]
    }
  }
}

div
  label.typo__label Basic Crosstab
  div.overflow-auto
    crosstab(
      :data="data",
      :cols="cols",
      :rows="rows"
    )

<div>
  <label class="typo__label">Basic Crosstab</label>
  <div class="overflow-auto">
    <crosstab :data="data" :cols="cols" :rows="rows"></crosstab>
  </div>
</div>

Data types

The basic crosstab doesn’t require much configuration.

Optional configuration flags:

  • type: "temporal" – can be appied to date field type.
  • timeUnit: "temporal" – can be appied temporal fields. Possible values: year, quarter, month, day.
  • label: "Day" – field label.
import Crosstab from 'vue-crosstab'
import data from 'data/seattle-weather-lite.json'

export default {
  components: {
    Crosstab
  },
  data () {
    return {
      data,
      rows: [
        {field: 'date', type: 'temporal', timeUnit: 'year', label: 'Year'},
        {field: 'date', type: 'temporal', timeUnit: 'month', label: 'Month'}
      ],
      cols: [
        {field: 'date', type: 'temporal', timeUnit: 'day', label: 'Day'},
        {field: 'weather', label: 'Weather'},
        {field: 'wind', aggregate: 'avg', label: 'Wind'}
      ]
    }
  }
}

div
  label.typo__label Data types
  div.overflow-auto
    crosstab(
      :data="data",
      :cols="cols",
      :rows="rows"
    )

<div>
  <label class="typo__label">Data types</label>
  <div class="overflow-auto">
    <crosstab :data="data" :cols="cols" :rows="rows"></crosstab>
  </div>
</div>

Filters

The basic crosstab doesn’t require much configuration.

Optional configuration flags:

  • transform - an array with filters and calsulated fields
  • filter: weatherweather field name in record.
  • equals – name of the filter. Posible values equals, isNotEqualTo, isOneOf, isNotOneOf, contains, isGreaterThan, isSmallerThan.
import Crosstab from 'vue-crosstab'
import data from 'data/seattle-weather-lite.json'

export default {
  components: {
    Crosstab
  },
  data () {
    return {
      data,
      transform: [
        {filter: 'weather', equals: 'sun'},
        {filter: 'date_year', isGreaterThan: 2012}
      ],
      cols: [
        {field: 'date', type: 'temporal', timeUnit: 'year', label: 'Year'},
        {field: 'weather', label: 'Weather', aggregate: 'count'}
      ],
      rows: [
        {field: 'date', type: 'temporal', timeUnit: 'month', label: 'Month'}
      ]
    }
  }
}

div
  label.typo__label Filters
  div.overflow-auto
    crosstab(
      :data="data",
      :cols="cols",
      :rows="rows",
      :transform="transform"
    )

<div>
  <label class="typo__label">Filters</label>
  <div class="overflow-auto">
    <crosstab :data="data" :cols="cols" :rows="rows" :transform="transform"></crosstab>
  </div>
</div>

Formatters

Use internal formmatter.

  • formatter - can be one of predefined formatters or function
  • formatter: "currency" – format value as currency. Available formatters currency
import Crosstab from 'vue-crosstab'
import data from 'data/salary.json'

export default {
  components: {
    Crosstab
  },
  data () {
    return {
      data,
      transform: [],
      rows: [
        {field: 'programming_language', label: 'Speciality'}
      ],
      cols: [
        {field: 'salary_per_month', label: 'Salary', aggregate: 'max', formatter: 'currency'}
      ]
    }
  }
}

div
  label.typo__label Filters
  div.overflow-auto
    crosstab(
      :data="data",
      :cols="cols",
      :rows="rows",
      :cellWidth="150",
      :transform="transform"
    )

<div>
  <label class="typo__label">Filters</label>
  <div class="overflow-auto">
    <crosstab :data="data" :cols="cols" :rows="rows" :cellWidth="150" :transform="transform"></crosstab>
  </div>
</div>

Calculated fields

The basic crosstab doesn’t require much configuration.

Optional configuration flags:

  • calculate: 'season' – create season calculated field.
  • value: record => {}value value for season calculated field. Takes function which will be called with each record in data
import Crosstab from 'vue-crosstab'
import _ from 'underscore'
import data from 'data/seattle-weather-lite.json'

export default {
  components: {
    Crosstab
  },
  data () {
    return {
      data,
      transform: [
        {
          calculate: 'season',
          value: record => {
            return _.contains(['December', 'January', 'February'], record.date_month) ? 'Winter' :
                   _.contains(['March', 'April', 'May'], record.date_month) ? 'Spring' :
                   _.contains(['June', 'July', 'August'], record.date_month) ? 'Summer' : 'Autumn'
          }
        }
      ],
      cols: [
        {field: 'date', type: 'temporal', timeUnit: 'year', label: 'Year'},
        {field: 'weather', label: 'Weather', aggregate: 'count'}
      ],
      rows: [
        {field: 'season', label: 'Season'},
        {field: 'date', type: 'temporal', timeUnit: 'month', label: 'Month'}
      ]
    }
  }
}

div
  label.typo__label Calculated fields
  div.overflow-auto
    crosstab(
      :data="data",
      :cols="cols",
      :rows="rows",
      :transform="transform"
    )

<div>
  <label class="typo__label">Calculated fields</label>
  <div class="overflow-auto">
    <crosstab :data="data" :cols="cols" :rows="rows" :transform="transform"></crosstab>
  </div>
</div>

Rows only

Rows only.

Optional configuration flags:

  • aggregate: "count" – count aggregation function.
import Crosstab from 'vue-crosstab'
import data from 'data/people.json'

export default {
  components: {
    Crosstab
  },
  data () {
    return {
      data,
      rows: [
        {field: 'sex'},
        {field: 'smoker'},
        {field: 'total_bill', aggregate: 'sum'}
      ]
    }
  }
}

div
  label.typo__label Rows Only
  div.overflow-auto
    crosstab(
      :data="data",
      :rows="rows",
      :cellWidth="80"
    )

<div>
  <label class="typo__label">Rows Only</label>
  <div class="overflow-auto">
    <crosstab :data="data" :rows="rows" :cellWidth="80"></crosstab>
  </div>
</div>

Columns only

Columns only.

Optional configuration flags:

  • aggregate: "count" – count aggregation function.
  • :width" – width of crosstab. Cells width will be ajusted.
import Crosstab from 'vue-crosstab'
import data from 'data/people.json'

export default {
  components: {
    Crosstab
  },
  data () {
    return {
      data,
      cols: [
        {field: 'sex'},
        {field: 'smoker', aggregate: 'count'}
      ]
    }
  }
}

div
  label.typo__label Cols Only
  div.overflow-auto
    crosstab(
      :data="data",
      :cols="cols"
    )

<div>
  <label class="typo__label">Cols Only</label>
  <div class="overflow-auto">
    <crosstab :data="data" :cols="cols"></crosstab>
  </div>
</div>

No Rows No Columns

Whtout rows and columns.

import Crosstab from 'vue-crosstab'
import data from 'data/people.json'

export default {
  components: {
    Crosstab
  },
  data () {
    return {
      data
    }
  }
}

div
  label.typo__label No rows and now cols
  div.overflow-auto
    crosstab(
      :data="data"
    )

<div>
  <label class="typo__label">No rows and now cols</label>
  <div class="overflow-auto">
    <crosstab :data="data"></crosstab>
  </div>
</div>

Custom configuration

Custom cells configuration.

Optional configuration flags:

  • :cellWidth="75" – cell width in pixels.
  • :cellHeight="75" – cell height in pixels.
  • :fontSize="20" – font size in pixels.
import Crosstab from 'vue-crosstab'
import data from 'data/people.json'

export default {
  components: {
    Crosstab
  },
  data () {
    return {
      data,
      rows: [
        {field: 'sex'},
        {field: 'smoker'}
      ],
      cols: [
        {field: 'time'},
        {field: 'total_bill', aggregate: 'sum'}
      ]
    }
  }
}

div
  label.typo__label Basic Crosstab
  div.overflow-auto
    crosstab(
      :data="data",
      :rows="rows",
      :cols="cols",
      :cellWidth="75",
      :cellHeight="75",
      :fontSize="20"
    )

<div>
  <label class="typo__label">Basic Crosstab</label>
  <div class="overflow-auto">
    <crosstab :data="data" :rows="rows" :cols="cols" :cellWidth="75" :cellHeight="75" :fontSize="20"></crosstab>
  </div>
</div>

Custom Theme

Custom cells configuration.

Optional configuration flags:

  • :theme="theme" – custom theme configuration.
  • theme.name - theme name. Available themes Teal, Blue, Light Blue, Pink, Indigo, Deep Purple
import Crosstab from 'vue-crosstab'
import Multiselect from 'vue-multiselect'
import data from 'data/people.json'

export default {
  components: {
    Crosstab,
    Multiselect
  },
  data () {
    return {
      data,
      rows: [
        {field: 'day'},
        {field: 'time'}
      ],
      cols: [
        {field: 'sex'},
        {field: 'smoker'},
        {field: 'total_bill', aggregate: 'sum'}
      ],
      theme: {name: 'Teal'},
      themes: [
        {name: 'Blue'},
        {name: 'Light Blue'},
        {name: 'Indigo'},
        {name: 'Pink'},
        {name: 'Deep Purple'},
        {name: 'Teal'}
      ]
    }
  }
}

div
  label.typo__label Custom Theme
  div.overflow-auto
    multiselect(v-model="theme", :options="themes",  label="name", track-by="name")
    br
    br
    crosstab(
      :data="data",
      :rows="rows",
      :cols="cols",
      :width="380",
      :theme="theme"
    )

<div>
  <label class="typo__label">Custom Theme</label>
  <div class="overflow-auto">
    <multiselect v-model="theme" :options="themes" label="name" track-by="name"></multiselect><br><br>
    <crosstab :data="data" :rows="rows" :cols="cols" :width="380" :theme="theme"></crosstab>
  </div>
</div>

Scroll Reverse

Scroll direction.

Optional configuration flags:

  • :scrollReverse="false" – use natural scroll direction.
import Crosstab from 'vue-crosstab'
import data from 'data/people.json'

export default {
  components: {
    Crosstab
  },
  data () {
    return {
      data,
      cols: [
        {field: 'day'},
        {field: 'time'},
        {field: 'total_bill', aggregate: 'sum'}
      ],
      rows: [
        {field: 'sex'},
        {field: 'smoker'}
      ]
    }
  }
}

div
    div
        label.typo__label Natural scroll direction
        div.overflow-auto
            crosstab(
            :data="data",
            :rows="rows",
            :cols="cols",
            :scrollReverse="false"
            height="300")
    div
        label.typo__label Reversed scroll direction (default)
        div.overflow-auto
            crosstab(
            :data="data",
            :rows="rows",
            :cols="cols",
            height="300")

<div>
  <div>
    <label class="typo__label">Natural scroll direction</label>
    <div class="overflow-auto">
      <crosstab :data="data" :rows="rows" :cols="cols" :scrollReverse="false" height="300"></crosstab>
    </div>
  </div>
  <div>
    <label class="typo__label">Reversed scroll direction (default)</label>
    <div class="overflow-auto">
      <crosstab :data="data" :rows="rows" :cols="cols" height="300"></crosstab>
    </div>
  </div>
</div>

Load Data by URL

Loading data by url.

Optional configuration flags:

  • dataUrl – url to load data. Possible data type json, csv.
import Crosstab from 'vue-crosstab'

export default {
  components: {
    Crosstab
  },
  data () {
    return {
      dataUrl: 'static/data/seattle-weather-lite.json',
      rows: [
        {field: 'date', type: 'temporal', timeUnit: 'year', label: 'Year'},
        {field: 'date', type: 'temporal', timeUnit: 'month', label: 'Month'}
      ],
      cols: [
        {field: 'date', type: 'temporal', timeUnit: 'day', label: 'Day'},
        {field: 'weather', label: 'Weather'},
        {field: 'wind', aggregate: 'avg', label: 'Wind'}
      ]
    }
  }
}

div
  label.typo__label Load data
  div.overflow-auto
    crosstab(
      :dataUrl="dataUrl",
      :cols="cols",
      :rows="rows",
      height="200"
    )

<div>
  <label class="typo__label">Load data</label>
  <div class="overflow-auto">
    <crosstab :dataUrl="dataUrl" :cols="cols" :rows="rows" height="200"></crosstab>
  </div>
</div>

Bar Chart

Show bar cahr indicator.

Optional configuration flags:

  • :bars="true" – show bar cahrt indecator. Default false.
import Crosstab from 'vue-crosstab'
import data from 'data/salary.json'

export default {
  components: {
    Crosstab
  },
  data () {
    return {
      data,
      transform: [],
      rows: [
        {field: 'programming_language', label: 'Speciality'}
      ],
      cols: [
        {field: 'salary_per_month', label: 'Salary', aggregate: 'max', formatter: 'currency'}
      ]
    }
  }
}

div
  label.typo__label Filters
  div.overflow-auto
    crosstab(
      :data="data",
      :cols="cols",
      :rows="rows",
      :bars="true",
      :cellWidth="150",
      :transform="transform"
    )

<div>
  <label class="typo__label">Filters</label>
  <div class="overflow-auto">
    <crosstab :data="data" :cols="cols" :rows="rows" :bars="true" :cellWidth="150" :transform="transform"></crosstab>
  </div>
</div>

Props

NameTypeDefaultDescription
dataArrayData to be displayed in crosstab.
rowsArray[]Sequence of row levels.
colsArray[]Sequence of column levels.
aggregateStringName of aggregation function. Can besum,max,min,avg,count
typeStringField type. Can betemporal
timeUnitStringCan be applied for temporal field type. Can beyear,quarter,month,day
widthNumberCrosstab width in pixels.
heightNumberCrosstab height in pixels.
cellWidthNumberCell width in pixels.
cellHeightNumberCell height in pixels.
fontSizeNumberFont size in pixels.
scrollReverseBooleantrueUse reversed scroll direction

Events

NameAttributesListen toDescription
Update(value)@updateEmitted after this.data changes

Created by Artem Malieiev