Skip to content

Commit

Permalink
feat: Vue package improvements and docs
Browse files Browse the repository at this point in the history
Fix slot composing issue and add examples using vue library (#68)
  • Loading branch information
richipargo authored and paveltiunov committed Apr 2, 2019
1 parent a00aef0 commit fc38e69
Show file tree
Hide file tree
Showing 28 changed files with 10,208 additions and 19 deletions.
95 changes: 95 additions & 0 deletions docs/Cube.js-Frontend/@cubejs-client-vue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
---
title: '@cubejs-client/vue'
permalink: /@cubejs-client-vue
category: Cube.js Frontend
---

`@cubejs-client/vue` provides Vue Components for easy integration Cube.js
into Vue.js app.

## QueryRenderer

`<QueryRenderer />` Vue component takes a query, fetches the given query, and uses the slot scoped props to render the resulting data.

### Props

- `query`: analytic query. [Learn more about it's format](query-format).
- `cubejsApi`: `CubejsApi` instance to use.

### Scoped Slot Props

- `resultSet`: A `resultSet` is an object containing data obtained from the query. If this object is not defined, it means that the data is still being fetched. [ResultSet](@cubejs-client-core#result-set) object provides a convient interface for data munipulation.
- `error`: Error will be defined if an error has occurred while fetching the query.
- `loadingState`: Provides information about the state of the query loading.

## QueryBuilder
`<QueryBuilder />` is used to build interactive analytics query builders. It abstracts state management and API calls to Cube.js Backend. It uses scoped slot props technique.

### Props

- `query`: default query.
- `cubejsApi`: `CubejsApi` instance to use. Required.
- `defaultChartType`: default value of chart type. Default: 'line'.

### Scoped Slot Props

- `measurers`, `dimensions`, `segments`, `timeDimensions`, `filters` - arrays of
selected query builder members.
- `availableMeasures`, `availableDimensions`, `availableTimeDimensions`,
`availableSegments` - arrays of available to select members. They are loaded via
API from Cube.js Backend.
- `updateMeasures`, `updateDimensions`, `updateSegments`, `updateTimeDimensions` - objects with three functions: `add`, `remove`, and `update`. They are used to control the state of the query builder. Ex: `updateMeasures.add(newMeasure)`
- `chartType` - string, containing currently selected chart type.
- `updateChartType` - function-setter for chart type.
- `isQueryPresent` - Bool indicating whether is query ready to be displayed or
not.
- `query` - current query, based on selected members.
- `resultSet`, `error`, `loadingState` - same as `<QueryRenderer />` [Scoped slot params.](#query-scoped-slot-props)

### Example
[Open in CodeSandbox](https://codesandbox.io/s/3rlxjkv2p)
```vue
<template>
<div class="hello">
<query-builder :cubejs-api="cubejsApi" :query="query">
<template v-slot="{ resultSet }">
</template>
</query-builder>
</div>
</template>
<script>
import cubejs from '@cubejs-client/core';
import { QueryBuilder } from '@cubejs-client/vue';
import ChartRenderer from "./ChartRenderer.vue";
const cubejsApi = cubejs(
'YOUR-CUBEJS-API-TOKEN',
{ apiUrl: 'http://localhost:4000/cubejs-api/v1' },
);
export default {
name: "HelloWorld",
components: {
QueryBuilder,
ChartRenderer
},
data() {
const query = {
measures: ["LineItems.count", "LineItems.quantity", "Orders.count"],
timeDimensions: [
{
dimension: "LineItems.createdAt",
granularity: "month"
}
]
};
return {
cubejsApi,
query
};
}
};
</script>
```
76 changes: 76 additions & 0 deletions docs/Getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,13 @@ $ npm i --save @cubejs-client/core
$ npm i --save @cubejs-client/react
```

Vue:

```bash
$ npm i --save @cubejs-client/core
$ npm i --save @cubejs-client/vue
```

### Example Usage

#### Vanilla Javascript
Expand Down Expand Up @@ -175,3 +182,72 @@ export default () => {
)
}
```

#### Vue
Import `cubejs` and `QueryRenderer` components, and use them to fetch the data.
In the example below we use Vue-Chartkick to visualize data.

```jsx
<template>
<div class="hello">
<query-renderer :cubejs-api="cubejsApi" :query="query">
<template v-slot="{ measures, resultSet, loading }">
<line-chart :data="transformData(resultSet)"></line-chart>
</template>
</query-renderer>
</div>
</template>

<script>
import cubejs from '@cubejs-client/core';
import { QueryBuilder } from '@cubejs-client/vue';
import Vue from 'vue';
import VueChartkick from 'vue-chartkick';
import Chart from 'chart.js';

Vue.use(VueChartkick, { adapter: Chart });

const cubejsApi = cubejs(
'YOUR-CUBEJS-API-TOKEN',
{ apiUrl: 'http://localhost:4000/cubejs-api/v1' },
);

export default {
name: 'HelloWorld',
components: {
QueryBuilder,
},
props: {
msg: String,
},
data() {
const query = {
measures: ['LineItems.count', 'LineItems.quantity', 'Orders.count'],
timeDimensions: [
{
dimension: 'LineItems.createdAt',
granularity: 'month',
},
],
};

return {
cubejsApi,
query,
};
},
methods: {
transformData(resultSet) {
const seriesNames = resultSet.seriesNames();
const pivot = resultSet.chartPivot();
const series = [];
seriesNames.forEach((e) => {
const data = pivot.map(p => [p.x, p[e.key]]);
series.push({ name: e.key, data });
});
return series;
},
},
};
</script>
```
3 changes: 3 additions & 0 deletions examples/vue-dashboard/backend/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
CUBEJS_API_SECRET=SECRET
CUBEJS_DB_TYPE=postgres
CUBEJS_DB_NAME=ecom
7 changes: 7 additions & 0 deletions examples/vue-dashboard/backend/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const CubejsServer = require('@cubejs-backend/server');

const server = new CubejsServer();

server.listen().then(({ port }) => {
console.log(`🚀 Cube.js server is listening on ${port}`);
});
12 changes: 12 additions & 0 deletions examples/vue-dashboard/backend/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "backend",
"version": "0.0.1",
"private": true,
"scripts": {
"dev": "./node_modules/.bin/cubejs-dev-server"
},
"dependencies": {
"@cubejs-backend/postgres-driver": "^0.4.4",
"@cubejs-backend/server": "^0.4.6"
}
}
40 changes: 40 additions & 0 deletions examples/vue-dashboard/backend/schema/LineItems.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
cube(`LineItems`, {
sql: `SELECT * FROM public.line_items`,

joins: {
Orders: {
sql: `${CUBE}.order_id = ${Orders}.id`,
relationship: `belongsTo`
}
},

measures: {
count: {
type: `count`,
drillMembers: [id, createdAt]
},

quantity: {
sql: `quantity`,
type: `sum`
},

price: {
sql: `price`,
type: `sum`
}
},

dimensions: {
id: {
sql: `id`,
type: `number`,
primaryKey: true
},

createdAt: {
sql: `created_at`,
type: `time`
}
}
});
45 changes: 45 additions & 0 deletions examples/vue-dashboard/backend/schema/Orders.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
cube(`Orders`, {
sql: `SELECT * FROM public.orders`,

joins: {
Users: {
sql: `${CUBE}.user_id = ${Users}.id`,
relationship: `belongsTo`
}
},

measures: {
count: {
type: `count`,
drillMembers: [id, createdAt]
},

number: {
sql: `number`,
type: `sum`
}
},

dimensions: {
id: {
sql: `id`,
type: `number`,
primaryKey: true
},

status: {
sql: `status`,
type: `string`
},

createdAt: {
sql: `created_at`,
type: `time`
},

completedAt: {
sql: `completed_at`,
type: `time`
}
}
});
42 changes: 42 additions & 0 deletions examples/vue-dashboard/backend/schema/Users.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
cube(`Users`, {
sql: `SELECT * FROM public.users`,

joins: {

},

measures: {
count: {
type: `count`,
drillMembers: [city, id, createdAt]
}
},

dimensions: {
city: {
sql: `city`,
type: `string`
},

gender: {
sql: `gender`,
type: `string`
},

id: {
sql: `id`,
type: `number`,
primaryKey: true
},

company: {
sql: `company`,
type: `string`
},

createdAt: {
sql: `created_at`,
type: `time`
}
}
});
2 changes: 2 additions & 0 deletions examples/vue-dashboard/frontend/.env.development
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
REACT_APP_CUBEJS_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE1NTM3NjIwNzIsImV4cCI6MTU1Mzg0ODQ3Mn0.zwBj40GgBSwGc72RYo2_6PeOnHMNo7AYummdYGJkiDo
REACT_APP_API_URL=http://localhost:4000/cubejs-api/v1
2 changes: 2 additions & 0 deletions examples/vue-dashboard/frontend/.env.production
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
REACT_APP_CUBEJS_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.K9PiJkjegbhnw4Ca5pPlkTmZihoOm42w8bja9Qs2qJg
REACT_APP_API_URL=https://react-query-builder.herokuapp.com/cubejs-api/v1
23 changes: 23 additions & 0 deletions examples/vue-dashboard/frontend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*

0 comments on commit fc38e69

Please sign in to comment.