├── .editorconfig
├── .eslintignore
├── .github
└── FUNDING.yml
├── .gitignore
├── .prettierrc
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── TODO.md
├── babel.config.js
├── cypress.json
├── docs
├── .vuepress
│ ├── components
│ │ └── githubbuttons.vue
│ ├── config.js
│ ├── enhanceApp.js
│ ├── public
│ │ ├── d2.png
│ │ ├── dashblocks.png
│ │ ├── dashboard_dark.png
│ │ └── logo.png
│ └── styles
│ │ └── index.styl
├── README.md
├── components
│ ├── README.md
│ ├── d3
│ │ ├── DbHorizon.vue.md
│ │ ├── DbSankey.vue.md
│ │ └── DbSunburst.vue.md
│ └── dygraphs
│ │ ├── DbDygraphs.vue.md
│ │ ├── DbDygraphsBar.vue.md
│ │ └── DbDygraphsLine.vue.md
└── guide
│ ├── README.md
│ ├── firstdashboard.md
│ └── gettingstarted.md
├── images
├── dblogo.png
├── dblogo.xcf
└── logo.xcf
├── package.json
├── public
├── data
│ └── superstore.arrow
├── favicon.ico
├── images
│ └── poster_grand_tour.png
└── index.html
├── screenshots
├── dashboard.png
├── dblogo.png
└── sample_dashboard.png
├── scripts
├── buildComponentDocs.js
├── pagesdeploy.sh
└── templates
│ └── component.md
├── src
├── App.vue
├── assets
│ ├── logo.png
│ └── scss
│ │ ├── dashblocks.scss
│ │ └── dashblocks
│ │ ├── _dbdashboard.scss
│ │ ├── _gridlayout.scss
│ │ ├── _gridlayout12.scss
│ │ ├── _material-colors.scss
│ │ ├── _variables.scss
│ │ ├── components
│ │ ├── _dbdygraps.scss
│ │ ├── _dbeasypie.scss
│ │ └── _dbnumber.scss
│ │ └── themes
│ │ ├── _theme-dark.scss
│ │ └── _theme-default.scss
├── components.js
├── components
│ ├── chartjs
│ │ ├── DbChartjs.js
│ │ └── index.js
│ ├── d3
│ │ ├── DbHorizon.vue
│ │ ├── DbRidgeline.vue
│ │ ├── DbSankey.vue
│ │ ├── DbSunburst.vue
│ │ ├── domuid.js
│ │ └── index.js
│ ├── dashboard
│ │ ├── DbDashboard.vue
│ │ └── index.js
│ ├── db
│ │ ├── DbEasyPie.vue
│ │ ├── DbHeatmapVariants.vue
│ │ ├── DbLinearProgress.vue
│ │ ├── DbMarkup.vue
│ │ ├── DbMultiProgress.vue
│ │ ├── DbNone.vue
│ │ ├── DbNumber.vue
│ │ ├── DbProgress.vue
│ │ ├── DbSparkHeatmap.vue
│ │ ├── DbSparkLinemap.vue
│ │ ├── DbSparkRidgeline.vue
│ │ ├── DbSparkRidgelineHeight.vue
│ │ ├── DbSparkline.vue
│ │ ├── DbTrendBar.vue
│ │ ├── DbTrendLine.vue
│ │ └── index.js
│ ├── dbcolors.js
│ ├── dbdata.js
│ ├── dblayouts.js
│ ├── dbutils.js
│ ├── dbwidgets.js
│ ├── dygraphs
│ │ ├── DbDygraphs.vue
│ │ ├── DbDygraphsBar.vue
│ │ ├── DbDygraphsDateTimeHistogram.vue
│ │ ├── DbDygraphsLine.vue
│ │ ├── DbDygraphsSparkLine.vue
│ │ └── index.js
│ ├── funnel
│ │ ├── DbFunnel.vue
│ │ └── index.js
│ ├── geo
│ │ ├── DbGeoMapbox.vue
│ │ ├── geomap.vue
│ │ ├── index.js
│ │ └── old_DbGeoMapbox.vue
│ ├── index.js
│ ├── layout
│ │ ├── DbGridLayout.vue
│ │ └── DbWidgetContainer.vue
│ ├── log.js
│ ├── mixins
│ │ └── dbstdprops.js
│ ├── perspective
│ │ ├── DbPerspective.vue
│ │ └── index.js
│ ├── plotly
│ │ ├── DbPlotly.vue
│ │ ├── DbPlotlyLine.vue
│ │ └── DbPlotlyPie.vue
│ └── utils
│ │ └── colors.js
├── css.js
├── demo
│ ├── assets
│ │ └── images
│ │ │ └── poster_grand_tour.png
│ ├── dashboards
│ │ ├── ChartJsShowcase.json
│ │ ├── dashfive.json
│ │ ├── dashsix.json
│ │ └── dashthree.json
│ ├── data
│ │ ├── energy.json
│ │ ├── flare.json
│ │ ├── geo_data_us.json
│ │ ├── metrics3.json
│ │ ├── ridgedata.json
│ │ ├── ridgemapdata.json
│ │ ├── series_api_latency.json
│ │ ├── series_rate_api_req_count.json
│ │ ├── series_test_jvm_memory_used_bytes.json
│ │ ├── sws_api_stats.json
│ │ └── testdata.js
│ ├── layouts
│ │ └── Default.vue
│ ├── mixins
│ │ └── demodashboard.js
│ ├── themes
│ │ ├── README.md
│ │ └── _theme_custom.scss
│ └── views
│ │ ├── About.vue
│ │ ├── ChartJsShowcase.vue
│ │ ├── CodeViewer.vue
│ │ ├── DashFive.vue
│ │ ├── DashFour.vue
│ │ ├── DashRidgeline.vue
│ │ ├── DashSix.vue
│ │ ├── DashThree.vue
│ │ ├── DashblocksShowcase.vue
│ │ ├── DygraphsDynamic.vue
│ │ ├── DynamicPerspective.vue
│ │ ├── DynamicSalesDashboard.vue
│ │ ├── DynamicSankey.vue
│ │ ├── DynamicTimelines.vue
│ │ ├── DynamicTimelinesDygraphs.vue
│ │ ├── GeoMapboxUS.vue
│ │ ├── Home.vue
│ │ ├── OverlayDashboard.vue
│ │ ├── OverlayDashboardImage.vue
│ │ ├── OverlayDashboardParallax.vue
│ │ ├── Perspective.vue
│ │ ├── Playground.vue
│ │ ├── ProgressDashboard.vue
│ │ ├── SalesFunnelDashboard.vue
│ │ ├── SalesSunburstDashboard.vue
│ │ ├── SampleDashboard.vue
│ │ ├── SankeyDashboard.vue
│ │ ├── SparkHeatMap.vue
│ │ ├── SparkLineMap.vue
│ │ ├── SparkLineMapDyn.vue
│ │ └── samples
│ │ ├── DbDygraphsBarSamples.vue
│ │ ├── DbHorizonSamples.vue
│ │ └── ProgressSamples.vue
├── index.esm.js
├── main.js
├── quasar.js
├── router.js
├── store.js
├── styles
│ ├── quasar.scss
│ └── quasar.variables.scss
├── views
│ ├── About.vue
│ └── Home.vue
└── webcomponents
│ ├── dashboard.vue
│ └── dygraphs.vue
├── tests
├── e2e
│ ├── .eslintrc.js
│ ├── plugins
│ │ └── index.js
│ ├── specs
│ │ └── test.js
│ └── support
│ │ ├── commands.js
│ │ └── index.js
├── unit
│ ├── .eslintrc.js
│ └── example.spec.js
└── wc
│ ├── db.html
│ └── index.html
├── vue.config.js
└── yarn.lock
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # editorconfig.org
4 |
5 | root = true
6 |
7 |
8 | [*]
9 |
10 | # Change these settings to your own preference
11 | indent_style = space
12 | indent_size = 2
13 |
14 | # We recommend you to keep these unchanged
15 | end_of_line = lf
16 | charset = utf-8
17 | trim_trailing_whitespace = true
18 | insert_final_newline = true
19 |
20 | [*.md]
21 | trim_trailing_whitespace = false
22 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | dist
2 | node_modules
3 | public
4 | tests
5 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: sv2
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | dist
4 | pages
5 | /dist
6 | /demo
7 | /docs/.vuepress/dist
8 | /pages
9 |
10 | /tests/e2e/videos/
11 | /tests/e2e/screenshots/
12 |
13 | # local env files
14 | .env.local
15 | .env.*.local
16 |
17 | # Log files
18 | npm-debug.log*
19 | yarn-debug.log*
20 | yarn-error.log*
21 |
22 | # Editor directories and files
23 | .idea
24 | .vscode
25 | *.suo
26 | *.ntvs*
27 | *.njsproj
28 | *.sln
29 | *.sw*
30 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "printWidth": 180
4 | }
5 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | Want to contribute to **dashblocks**? Awesome!
4 |
5 |
6 | There are many ways you can contribute:
7 |
8 | * by reviewing
9 | * by reporting bugs
10 | * by suggesting improvements and new features
11 | * by writing or editing documentation
12 | * by writing code ( no patch is too small )
13 | * by closing issues
14 |
15 | ## Proposing pull requests
16 |
17 | Pull requests are very welcome. Note that if you are going to propose drastic changes, be sure to open an issue for discussion first, to make sure that your PR will be accepted before you spend effort coding it.
18 |
19 |
20 | Inspired by https://github.com/middleman/middleman-heroku/blob/master/CONTRIBUTING.md
21 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2019 slana.tech
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/TODO.md:
--------------------------------------------------------------------------------
1 | # DashBlocks TODO
2 |
3 |
4 | ## Event propagation up to dashboard level
5 |
6 | - [X] db-event: generated by all widgets and propagated up to dashboard
7 | - [X] augment db-event with widget id on widget level
8 | - [X] Events for chartjs
9 | - [ ] Events for plotly
10 |
11 |
12 | ## Dashboards
13 |
14 | - [X] Overlay - dashboard on top of video, picture, etc - on a boarder & bottom [DEMO](https://dashblocks.io/demo/#/overlayimage)
15 | - [X] Dynamically generated dashboard based on data. I.e. multiple pie charts [DEMO](https://dashblocks.io/demo/#/dynamicsalesdashboard)
16 |
17 | ## Test Data
18 |
19 | - [X] Datasets, aggregation lib - use in sample dashboards
20 | - [X] Time-series sample dataset - i.e. sales over time
21 |
22 | [https://github.com/finos/perspective](https://github.com/finos/perspective) is used, together with [Apache Arrow](https://arrow.apache.org/) dataset
23 | Perspective enables dynamically aggregating Arrow data
24 |
25 | [DEMO](https://dashblocks.io/demo/#/dynamicsankey)
26 |
27 | ## Documentation
28 |
29 | - [X] Self-documenting components - jsdoc
30 |
31 | ## Pages
32 |
33 | - [x] github pages with doc - vuepress
34 | - [x] [Demo project](https://slanatech.github.io/dashblocks)
35 |
36 |
37 | ## Issues
38 |
39 |
40 | ## Style, Themes and Colors
41 |
42 | - [X] more color sets
43 | - [X] Dark mode support across all widgets
44 | - [ ] Examples of custom theme
45 |
46 |
47 | ## Dashboard widget
48 | - [ ] Title
49 |
50 |
51 | ## Chart Types / Components
52 |
53 | ### D3
54 | - [ ] Horizon: show values
55 | - [X] Sankey
56 | - [X] Sunburst
57 | - [X] Showcase dashboard
58 |
59 | https://dashblocks.io/demo/#/dynamicsankey
60 | https://dashblocks.io/demo/#/salessunburst
61 |
62 | ### Chart.js
63 | - [x] Showcase dashboard
64 |
65 | ### Plotly
66 | - [ ] Showcase dashboard
67 | - [ ] Consider: use more customized bundle ( specific modules ) instead of all-in-one.
68 | plotly.js-dist is too big to include in bundle ( ~6M )
69 |
70 |
71 | ### Dygraphs
72 | - [X] Showcase dashboard
73 | https://dashblocks.io/demo/#/dygraphsdynamic
74 |
75 | ### Dashblocks
76 | - [X] Number
77 | - [X] Percent
78 | - [ ] Multiple values - rows with sparklines
79 | - [X] [Showcase dashboard](https://dashblocks.io/demo/#/)
80 |
81 |
82 |
83 | ### Other
84 | - [X] Table - goodtable. Used in [dashblock-template separately](https://slanatech.github.io/dashblocks-template/#/vgt)
85 | - [X] Markup
86 | - [ ] Markdown
87 | - [ ] Showcase dashboard
88 |
89 |
90 | ## Options templates
91 |
92 | Create class to manage standard props/options templates for various chart types.
93 | So instead of specifying all props in dashboard definition always, just refer to
94 | template name (like DbDygraphs-AreaLine)
95 |
96 | Consider making template parameterized, i.e. pass axis name (see plotly props)
97 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: ['@vue/cli-plugin-babel/preset'],
3 | plugins: [
4 | [
5 | 'transform-imports',
6 | {
7 | quasar: {
8 | transform: 'quasar/dist/babel-transforms/imports.js',
9 | preventFullImport: true
10 | }
11 | }
12 | ]
13 | ]
14 | };
15 |
--------------------------------------------------------------------------------
/cypress.json:
--------------------------------------------------------------------------------
1 | {
2 | "pluginsFile": "tests/e2e/plugins/index.js"
3 | }
4 |
--------------------------------------------------------------------------------
/docs/.vuepress/components/githubbuttons.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/docs/.vuepress/config.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 | const webpack = require('webpack');
4 |
5 | const isDirectory = source => fs.lstatSync(source).isDirectory();
6 | const isNotDirectory = source => !fs.lstatSync(source).isDirectory();
7 | const getDirectories = source =>
8 | fs.readdirSync(source).map(name => path.join(source, name)).filter(isDirectory);
9 | const getFiles = source =>
10 | fs.readdirSync(source).map(name => path.join(source, name)).filter(isNotDirectory);
11 |
12 | module.exports = {
13 | base: '/',
14 | locales: {
15 | '/': {
16 | lang: 'en-US',
17 | title: 'dashblocks',
18 | description: 'Enable Analytics in your Apps'
19 | }
20 | },
21 | markdown: {
22 | lineNumbers: true
23 | },
24 | serviceWorker: true,
25 | themeConfig: {
26 | repo: 'slanatech/dashblocks',
27 | docsDir: 'docs',
28 | editLinks: true,
29 | sidebarDepth: 1,
30 | locales: {
31 | '/': {
32 | label: 'English',
33 | selectText: 'Languages',
34 | lastUpdated: 'Last Updated',
35 | editLinkText: 'Edit this page on GitHub',
36 | nav: [
37 | {
38 | text: 'Guide',
39 | link: '/guide/'
40 | },
41 | {
42 | text: 'Components',
43 | link: '/components/'
44 | },
45 | {
46 | text: 'Changelog',
47 | link: 'https://github.com/dashblocks/blob/dev/CHANGELOG.md'
48 | }
49 | ],
50 | sidebar: {
51 | '/guide/': ['/guide/', 'firstdashboard'],
52 | '/components/': getComponentsSidebar()
53 | /*[
54 | {
55 | title: 'Components',
56 | collapsable: false,
57 | children: ['']
58 | },
59 | {
60 | title: 'd3',
61 | collapsable: true,
62 | children: ['d3/DbHorizon.vue']
63 | }
64 | ]*/
65 | }
66 | }
67 | }
68 | },
69 | configureWebpack: {
70 | plugins: [
71 | // Ignore all locale files of moment.js
72 | new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
73 | ],
74 | resolve: {
75 | alias: {
76 | dashblocks: path.resolve(__dirname, '../../src/components/')
77 | }
78 | }
79 | }
80 | };
81 |
82 | function getComponentsSidebar() {
83 | let result = [
84 | {
85 | title: 'Components',
86 | collapsable: false,
87 | children: ['']
88 | }
89 | ];
90 |
91 | // Enumerate all folders
92 | let dirs = getDirectories(path.join(__dirname,'..','components'));
93 | console.log(`Directories: ${JSON.stringify(dirs)}`);
94 | for(let dir of dirs){
95 | let dirname = path.basename(dir);
96 | let files = getFiles(dir);
97 | let children = [];
98 | for(let file of files){
99 | let filename = path.basename(file);
100 | children.push(`${dirname}/${filename}`);
101 | }
102 |
103 | result.push(
104 | {
105 | title: dirname,
106 | collapsable: true,
107 | children: children
108 | }
109 | );
110 | }
111 |
112 | return result;
113 | }
114 |
--------------------------------------------------------------------------------
/docs/.vuepress/enhanceApp.js:
--------------------------------------------------------------------------------
1 | import DbHorizonSamples from '../../src/demo/views/samples/DbHorizonSamples';
2 | import DbDygraphsBarSamples from '../../src/demo/views/samples/DbDygraphsBarSamples';
3 | import SampleDashboard from '../../src/demo/views/SampleDashboard';
4 |
5 | export default ({
6 | Vue, // the version of Vue being used in the VuePress app
7 | options, // the options for the root Vue instance
8 | router, // the router instance for the app
9 | siteData // site metadata
10 | }) => {
11 | Vue.component('DbHorizonSamples', DbHorizonSamples);
12 | Vue.component('DbDygraphsBarSamples', DbDygraphsBarSamples);
13 | Vue.component('SampleDashboard', SampleDashboard);
14 | };
15 |
--------------------------------------------------------------------------------
/docs/.vuepress/public/d2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/slanatech/dashblocks/313aa29d14a23c5d50389ba3e1bb447c33ab1aa9/docs/.vuepress/public/d2.png
--------------------------------------------------------------------------------
/docs/.vuepress/public/dashblocks.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/slanatech/dashblocks/313aa29d14a23c5d50389ba3e1bb447c33ab1aa9/docs/.vuepress/public/dashblocks.png
--------------------------------------------------------------------------------
/docs/.vuepress/public/dashboard_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/slanatech/dashblocks/313aa29d14a23c5d50389ba3e1bb447c33ab1aa9/docs/.vuepress/public/dashboard_dark.png
--------------------------------------------------------------------------------
/docs/.vuepress/public/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/slanatech/dashblocks/313aa29d14a23c5d50389ba3e1bb447c33ab1aa9/docs/.vuepress/public/logo.png
--------------------------------------------------------------------------------
/docs/.vuepress/styles/index.styl:
--------------------------------------------------------------------------------
1 | body {
2 | background: rgba(0,0,0,0);
3 | }
4 |
5 |
6 | .theme-default-content:not(.custom) {
7 | max-width: 80%;
8 | width: 80%;
9 | }
10 |
11 | /*
12 | .theme-container.dashblocks-landing {
13 | background-image: url("/dashblocks/d2-3.png");
14 | height: 100%;
15 | background-repeat: no-repeat;
16 | background-size: cover;
17 | background-position: center;
18 | }
19 | */
20 |
21 |
22 | .theme-container.dashblocks-landing::before {
23 | background-image: url("/d2.png");
24 | filter: blur(6px);
25 | background-size: cover;
26 | content: "";
27 | display: block;
28 | position: absolute;
29 | top: 0;
30 | left: 0;
31 | width: 100%;
32 | height: 100%;
33 | z-index: -2;
34 | opacity: 0.4;
35 | -webkit-clip-path: polygon(0 0, 0 100%, 100% 40%, 100% 0);
36 | clip-path: polygon(0 0, 0 100%, 100% 40%, 100% 0);
37 | }
38 |
39 |
40 | /*
41 | .home {
42 | background-color: #00acc1;
43 | padding: 3.6rem 2rem 0;
44 | max-width: 100%;
45 | width: 100%;
46 | margin: 0px auto;
47 | display: block;
48 | }
49 |
50 | .home > features {
51 | background-color: #00acc1;
52 | padding: 3.6rem 2rem 0;
53 | max-width: 960px;
54 | margin: 0px auto;
55 | display: block;
56 | }
57 |
58 | .hero img {
59 | width: 100%;
60 | }
61 | */
62 |
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | home: true
3 | heroImage: /logo.png
4 | actionText: Get Started →
5 | actionLink: /guide/
6 | meta:
7 | - name: google-site-verification
8 | content: ypsB9NFIxGEr1b5D0BoZ0dyVzt8lLkilkI0dO755M54
9 | features:
10 | - title: Declarative
11 | details: Use declarative approach to define dashboard layout - Javascript object or JSON
12 | - title: Out of the box
13 | details: Provide reasonable out of the box defaults for all chart types, such as colors
14 | - title: Light and Dark
15 | details: Support Light and Dark themes out of the box
16 | - title: Interactive
17 | details: Enable interactivity by providing event handling on dashboard level
18 | - title: Dynamic
19 | details: Streamline dynamic updates of dashboard data, for example based on user interaction with dashboard
20 | - title: Data Driven
21 | details: Even dynamically generate Dashboard itself based on the data - thanks to declarative approach
22 | footer: MIT Licensed | Copyright © 2019 slana.tech
23 | pageClass: dashblocks-landing
24 | ---
25 |
26 |
27 |
32 |
33 |
34 |
37 |
38 | 
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/docs/components/README.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Components Reference
3 | lang: en-US
4 | ---
5 |
6 | # Components Reference
7 |
8 | This is the index page for all the documented components.
9 |
--------------------------------------------------------------------------------
/docs/components/d3/DbHorizon.vue.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "DbHorizon"
3 | ---
4 | # DbHorizon
5 |
6 | D3 Horizon Chart.
7 | Based on [https://observablehq.com/@d3/horizon-chart](https://observablehq.com/@d3/horizon-chart)
8 |
9 | DbHorizon accepts data in the following format:
10 |
11 | ```json
12 | [
13 | {key:'Series1', values:[{date:new Date(),value: 1},{date:new Date(),value: 2}]},
14 | {key:'Series2', values:[{date:new Date(),value: 2},{date:new Date(),value: 1}]}
15 | ]
16 | ```
17 |
18 |
19 | ### Properties
20 |
21 | |Name |Type |Required|Default |Description
22 | |:--------------|:--------|:-------|:-------|:----------
23 | |**_updated**|number|false|0|Change to trigger data update. Set this to current timestamp to inform component that data has been updated. Helpful in situations when, for example, only values in array are changed. See [https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats](https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats)
24 | |**dark**|boolean|false|false|Enable dark mode `true,false`
25 | |**data**|array|false|() => []|Chart Data
26 | |**seriesHeight**|number|false|23|Height of each series in pixels.
27 | |**colorSteps**|number|false|7|Number of overlapping color steps, in range 1-9
28 | |**scheme**|string|false|'schemePuBuGn'|Color scheme Use one of Discrete Diverging color schemes from d3-scale-chromatic: `schemeBrBG,schemePRGn, ...` See [https://github.com/d3/d3-scale-chromatic](https://github.com/d3/d3-scale-chromatic)
29 |
30 | ### Examples
31 |
32 |
33 |
34 |
35 |
36 |
37 | #### Code
38 |
39 | ```vue
40 |
41 |
42 |
43 |
Default configuration
44 |
45 |
46 |
47 |
48 |
Adjust seriesHeight: make each series higher (50px)
49 |
50 |
51 |
52 |
53 |
Adjust overlap: less color steps (2)
54 |
55 |
56 |
57 |
58 |
Adjust overlap: more color steps (9)
59 |
60 |
61 |
62 |
63 |
Different color scheme (schemeYlOrBr)
64 |
65 |
66 |
67 |
68 |
Dark mode. TODO Font color in DbHorizon
69 |
70 |
71 |
72 |
73 |
74 |
109 |
110 | ```
111 |
--------------------------------------------------------------------------------
/docs/components/d3/DbSankey.vue.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "DbSankey"
3 | ---
4 | # DbSankey
5 |
6 | DbSankey component
7 |
8 |
9 | ### Properties
10 |
11 | |Name |Type |Required|Default |Description
12 | |:--------------|:--------|:-------|:-------|:----------
13 | |**data**||false||
14 | |**colorScheme**|string|false|'interpolateRainbow'|
15 |
16 | ### Examples
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/docs/components/d3/DbSunburst.vue.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "DbSunburstZ"
3 | ---
4 | # DbSunburstZ
5 |
6 | DbSunburstZ component
7 |
8 |
9 | ### Properties
10 |
11 | |Name |Type |Required|Default |Description
12 | |:--------------|:--------|:-------|:-------|:----------
13 | |**wdata**||false||
14 | |**wspec**||false||
15 | |**dark**|boolean|false|false|
16 | |**colorScheme**|string|false|'interpolateRainbow'|
17 |
18 | ### Examples
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/docs/components/dygraphs/DbDygraphs.vue.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "DbDygraphs"
3 | ---
4 | # DbDygraphs
5 |
6 | DbDygraphs component
7 |
8 |
9 | ### Properties
10 |
11 | |Name |Type |Required|Default |Description
12 | |:--------------|:--------|:-------|:-------|:----------
13 | |**_updated**|number|false|0|
14 | |**data**|array|false|() => []|
15 | |**options**|object|false||
16 | |**dark**|boolean|false|false|
17 |
18 | ### Examples
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/docs/components/dygraphs/DbDygraphsBar.vue.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "DbDygraphsBar"
3 | ---
4 | # DbDygraphsBar
5 |
6 | Dygraphs Bar Chart.
7 | [http://dygraphs.com/](http://dygraphs.com/)
8 |
9 | Dygraphs accepts data in the following format:
10 |
11 | ```json
12 | [
13 | [date:new Date(),1,1,1],
14 | [date:new Date(),1,2,2],
15 | [date:new Date(),1,3,3]
16 | ]
17 | ```
18 |
19 |
20 | ### Properties
21 |
22 | |Name |Type |Required|Default |Description
23 | |:--------------|:--------|:-------|:-------|:----------
24 | |**_updated**|number|false|0|Change to trigger data update. Set this to current timestamp to inform component that data has been updated. Helpful in situations when, for example, only values in array are changed. See [https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats](https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats)
25 | |**dark**|boolean|false|false|Enable dark mode `true,false`
26 | |**data**|array|false|() => []|
27 | |**options**|object|false||
28 |
29 | ### Examples
30 |
31 |
32 |
33 |
34 |
35 |
36 | #### Code
37 |
38 | ```vue
39 |
40 |
41 |
42 |
Default configuration
43 |
44 |
45 |
46 |
47 |
Two Series
48 |
49 |
50 |
51 |
52 |
Dark mode. TODO Font color in DbDygraphs
53 |
54 |
55 |
56 |
57 |
58 |
96 |
103 |
104 | ```
105 |
--------------------------------------------------------------------------------
/docs/components/dygraphs/DbDygraphsLine.vue.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "DbDygraphsLine"
3 | ---
4 | # DbDygraphsLine
5 |
6 | DbDygraphsLine component
7 |
8 |
9 | ### Properties
10 |
11 | |Name |Type |Required|Default |Description
12 | |:--------------|:--------|:-------|:-------|:----------
13 | |**_updated**|number|false|0|
14 | |**data**|array|false|() => []|
15 | |**options**|object|false||
16 | |**dark**|boolean|false|false|
17 |
18 | ### Examples
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/docs/guide/README.md:
--------------------------------------------------------------------------------
1 | # Guide
2 |
3 |
4 | Dashblocks aims to simplify enabling robust In-App Analytics:
5 |
6 | * Use declarative approach to define dashboard layout
7 | * Provide reasonable out of the box defaults for all chart types, such as colors
8 | * Support dark / light modes out of the box
9 | * Enable interactivity by providing event handling on dashboard level
10 | * Streamline dynamic updates of dashboard data, for example based on user interaction with dashboard
11 | * Even dynamically generate Dashboard itself based on the data - thanks to declarative approach
12 |
13 |
14 | ## Installation
15 |
16 | ```bash
17 | # 1. Install
18 | npm install dashblocks --save
19 |
20 |
21 | ```
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/docs/guide/firstdashboard.md:
--------------------------------------------------------------------------------
1 | # Your first dashboard
2 |
3 | Create Dashboard in your Vue app as a Vue Component. In Dashboard component you define:
4 | * Dashboard Layout - add widgets to your dashboard, specifying how many columns and rows
5 | each widget takes. Dashblocks provides 16-columns CSS Grid layout. Pass additional options to widgets to adjust appearance as needed.
6 | * Set Data for each widget on a dashboard
7 |
8 |
9 |
10 |
11 |
12 | #### Code
13 |
14 | <<< @/src/demo/views/SampleDashboard.vue
15 |
--------------------------------------------------------------------------------
/docs/guide/gettingstarted.md:
--------------------------------------------------------------------------------
1 | # How to get started
2 |
3 | here are the instructions
4 |
--------------------------------------------------------------------------------
/images/dblogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/slanatech/dashblocks/313aa29d14a23c5d50389ba3e1bb447c33ab1aa9/images/dblogo.png
--------------------------------------------------------------------------------
/images/dblogo.xcf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/slanatech/dashblocks/313aa29d14a23c5d50389ba3e1bb447c33ab1aa9/images/dblogo.xcf
--------------------------------------------------------------------------------
/images/logo.xcf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/slanatech/dashblocks/313aa29d14a23c5d50389ba3e1bb447c33ab1aa9/images/logo.xcf
--------------------------------------------------------------------------------
/public/data/superstore.arrow:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/slanatech/dashblocks/313aa29d14a23c5d50389ba3e1bb447c33ab1aa9/public/data/superstore.arrow
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/slanatech/dashblocks/313aa29d14a23c5d50389ba3e1bb447c33ab1aa9/public/favicon.ico
--------------------------------------------------------------------------------
/public/images/poster_grand_tour.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/slanatech/dashblocks/313aa29d14a23c5d50389ba3e1bb447c33ab1aa9/public/images/poster_grand_tour.png
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | dashblocks
9 |
10 |
11 |
12 |
13 |
14 | We're sorry but dashblocks doesn't work properly without JavaScript enabled. Please enable it to continue.
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/screenshots/dashboard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/slanatech/dashblocks/313aa29d14a23c5d50389ba3e1bb447c33ab1aa9/screenshots/dashboard.png
--------------------------------------------------------------------------------
/screenshots/dblogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/slanatech/dashblocks/313aa29d14a23c5d50389ba3e1bb447c33ab1aa9/screenshots/dblogo.png
--------------------------------------------------------------------------------
/screenshots/sample_dashboard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/slanatech/dashblocks/313aa29d14a23c5d50389ba3e1bb447c33ab1aa9/screenshots/sample_dashboard.png
--------------------------------------------------------------------------------
/scripts/buildComponentDocs.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Build Components documentation based on JSDoc comments in component files
3 | *
4 | */
5 | const path = require('path');
6 | const fs = require('fs');
7 | const ejs = require('ejs');
8 | const { parse } = require('vue-docgen-api');
9 | const { pathOr } = require('ramda');
10 | const linkify = require('markdown-linkify');
11 |
12 | const basePath = path.join(__dirname, '..', 'src', 'components');
13 | const baseDocsPath = path.join(__dirname, '..', 'docs', 'components');
14 |
15 | const templateFN = path.join(__dirname, 'templates', 'component.md');
16 | const templateString = fs.readFileSync(templateFN, 'utf-8');
17 |
18 | function breakify(str) {
19 | return str.replace(/\r/g, '').replace(/\n/g, ' ');
20 | }
21 |
22 | const componentFiles = [
23 | { folder: 'd3', name: 'DbHorizon.vue' },
24 | { folder: 'd3', name: 'DbSankey.vue' },
25 | { folder: 'd3', name: 'DbSunburst.vue' },
26 | { folder: 'dygraphs', name: 'DbDygraphs.vue' },
27 | { folder: 'dygraphs', name: 'DbDygraphsBar.vue' },
28 | { folder: 'dygraphs', name: 'DbDygraphsLine.vue' }
29 | ];
30 |
31 | function camelCaseToDash(str) {
32 | return str.replace(/([a-zA-Z])(?=[A-Z])/g, '$1-').toLowerCase();
33 | }
34 |
35 | function parseComponentFile(componentFile) {
36 | // TODO Options ?
37 | let parseResult = parse(componentFile);
38 | return parseResult;
39 | }
40 |
41 | // Pre-process component properties
42 | function processProps(componentData) {
43 | let propsArray = [];
44 | for (let propName of Object.keys(componentData.props)) {
45 | let propData = componentData.props[propName];
46 | let propInfo = {
47 | name: propName,
48 | type: pathOr('', ['type', 'name'], propData),
49 | required: pathOr('', ['required'], propData) === 'true' ? 'true' : 'false',
50 | description: linkify(breakify(pathOr('', ['description'], propData))),
51 | default: pathOr('', ['defaultValue', 'value'], propData)
52 | };
53 | propsArray.push(propInfo);
54 | }
55 | return propsArray;
56 | }
57 |
58 | // Pre-process component examples
59 | // TODO Generate proper imports of sample components for vuepress ( enhanceApp.js )
60 | function processExamples(componentData, filePath, fileName) {
61 | let result = [];
62 |
63 | let examplesData = pathOr(null, ['tags', 'examples'], componentData);
64 | if (!examplesData || !Array.isArray(examplesData) || examplesData.length <= 0) {
65 | return result;
66 | }
67 |
68 | for (let example of examplesData) {
69 | let exampleContent = pathOr(null, ['content'], example);
70 | if (exampleContent) {
71 | let exampleFileName = path.join(filePath, exampleContent);
72 | let exampleBaseName = path.basename(exampleFileName, '.vue');
73 | let exampleComponent = camelCaseToDash(exampleBaseName);
74 | try {
75 | let exampleFileContent = fs.readFileSync(exampleFileName);
76 | let exampleCode = exampleFileContent.toString();
77 | result.push({
78 | code: exampleCode,
79 | component: exampleComponent,
80 | filePath: filePath,
81 | fileName: fileName
82 | });
83 | } catch (e) {
84 | // NOOP //
85 | }
86 | }
87 | }
88 |
89 | return result;
90 | }
91 |
92 | function renderComponentDoc(componentData, filePath, fileName) {
93 | let renderData = {
94 | name: pathOr('', ['displayName'], componentData),
95 | description: linkify(pathOr('', ['description'], componentData)),
96 | props: processProps(componentData),
97 | examples: processExamples(componentData, filePath, fileName)
98 | };
99 |
100 | let renderedDoc = ejs.render(templateString, renderData);
101 | return renderedDoc;
102 | }
103 |
104 | function processComponents() {
105 | for (let componentFile of componentFiles) {
106 | let filePath = path.join(basePath, componentFile.folder);
107 |
108 | let fullFN = path.join(filePath, componentFile.name);
109 |
110 | let parseResult = parseComponentFile(fullFN);
111 |
112 | let renderResult = renderComponentDoc(parseResult, filePath, componentFile.name);
113 |
114 | if (!fs.existsSync(path.join(baseDocsPath, componentFile.folder))) {
115 | fs.mkdirSync(path.join(baseDocsPath, componentFile.folder));
116 | }
117 |
118 | let docFN = path.join(baseDocsPath, componentFile.folder, componentFile.name + '.md');
119 |
120 | let defFS = fs.createWriteStream(docFN);
121 | defFS.write(renderResult);
122 | defFS.end();
123 | }
124 | }
125 |
126 | processComponents();
127 |
128 | //console.log('Test here!');
129 |
--------------------------------------------------------------------------------
/scripts/pagesdeploy.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # abort on errors
4 | set -e
5 |
6 | # navigate into the build output directory
7 | cd pages
8 |
9 | echo 'dashblocks.io' > CNAME
10 |
11 | git init
12 | git add -A
13 | git commit -m 'deploy for github pages'
14 |
15 | git push -f https://github.com/slanatech/dashblocks.git master:gh-pages
16 |
17 | cd -
18 |
--------------------------------------------------------------------------------
/scripts/templates/component.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "<%= name%>"
3 | ---
4 | # <%= name%>
5 |
6 | <%- description ? description : name + ' component'%>
7 |
8 |
9 | ### Properties
10 |
11 | |Name |Type |Required|Default |Description
12 | |:--------------|:--------|:-------|:-------|:----------
13 | <%
14 | for(let prop of props) {
15 | -%>
16 | |**<%- prop.name%>**|<%- prop.type%>|<%- prop.required%>|<%- prop.default%>|<%- prop.description%>
17 | <%
18 | }
19 | -%>
20 |
21 | ### Examples
22 |
23 |
24 |
25 | <%
26 | for(let example of examples) {
27 | -%>
28 |
29 | <<%- example.component%>><%- example.component%>>
30 |
31 | #### Code
32 |
33 | ```vue
34 | <%- example.code%>
35 | ```
36 | <%
37 | }
38 | -%>
39 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/slanatech/dashblocks/313aa29d14a23c5d50389ba3e1bb447c33ab1aa9/src/assets/logo.png
--------------------------------------------------------------------------------
/src/assets/scss/dashblocks.scss:
--------------------------------------------------------------------------------
1 | /*!
2 | DashBlocks
3 | */
4 |
5 | // Colors
6 | @import "dashblocks/material-colors";
7 |
8 |
9 | // Variables
10 | @import "dashblocks/variables";
11 |
12 |
13 | // Layouts
14 | @import "dashblocks/gridlayout";
15 | @import "dashblocks/gridlayout12";
16 |
17 | // Components
18 | @import "dashblocks/components/dbeasypie";
19 | @import "dashblocks/components/dbnumber";
20 | @import "dashblocks/components/dbdygraps";
21 |
22 | // Themes
23 | @import 'dashblocks/themes/theme-default';
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/assets/scss/dashblocks/_dbdashboard.scss:
--------------------------------------------------------------------------------
1 | // TODO Rename !!
2 | @mixin db-dashboard {
3 | font-family: $font-family;
4 | font-size: $font-size;
5 | color: $dark;
6 |
7 | .db-float-right {
8 | float: right;
9 | }
10 |
11 | .db-v-center {
12 | position: relative;
13 | top: 50%;
14 | transform: translateY(-50%);
15 | }
16 |
17 | .db-badge {
18 | background: $primary;
19 | color: $on-primary;
20 | font-size: 80%;
21 | padding: 2px 4px 2px 4px;
22 | border-radius: 4px;
23 | }
24 |
25 |
26 | & .db-grid-layout {
27 | column-gap: 0px;
28 | row-gap: 0px;
29 | }
30 |
31 | & .db-widget-container {
32 | margin: 4px;
33 | padding: 6px;
34 | border: 1px solid material-color('grey', '300');
35 | border-radius: 6px;
36 | }
37 |
38 | & .text-primary {
39 | color: $primary;
40 | }
41 | & .bg-primary {
42 | background: $primary;
43 | }
44 |
45 | & .text-on-primary {
46 | color: $on-primary;
47 | }
48 | & .text-on-secondary {
49 | color: $on-secondary;
50 | }
51 | & .text-on-background {
52 | color: $on-background;
53 | }
54 | & .text-on-surface {
55 | color: $on-surface;
56 | }
57 | & .text-on-error {
58 | color: $on-error;
59 | }
60 |
61 | & .text-faded {
62 | color: $faded;
63 | }
64 |
65 | & .text-neutral {
66 | color: $neutral;
67 | }
68 | & .text-positive {
69 | color: $positive;
70 | }
71 | & .text-negative {
72 | color: $negative;
73 | }
74 | & .text-info {
75 | color: $info;
76 | }
77 | & .text-warning {
78 | color: $warning;
79 | }
80 |
81 | & .text-xxs {
82 | font-size: 70%
83 | }
84 | & .text-xs {
85 | font-size: 80%
86 | }
87 | & .text-sm {
88 | font-size: 90%
89 | }
90 | & .text-base {
91 | font-size: 100%
92 | }
93 | & .text-md {
94 | font-size: 110%
95 | }
96 | & .text-lg {
97 | font-size: 120%
98 | }
99 | & .text-xl {
100 | font-size: 150%
101 | }
102 | & .text-xxl {
103 | font-size: 250%
104 | }
105 | & .text-x3l {
106 | font-size: 300%
107 | }
108 | & .text-x4l {
109 | font-size: 400%
110 | }
111 | & .text-x5l {
112 | font-size: 400%
113 | }
114 |
115 | & .bg-good {
116 | background: $positive;
117 | }
118 |
119 | & .bg-neutral {
120 | background: $neutral;
121 | }
122 | & .bg-success {
123 | background: $success;
124 | }
125 | & .bg-warning {
126 | background: $warning;
127 | }
128 | & .bg-alarm {
129 | background: $alarm;
130 | }
131 |
132 |
133 | }
134 |
135 |
136 |
137 |
138 |
--------------------------------------------------------------------------------
/src/assets/scss/dashblocks/_gridlayout.scss:
--------------------------------------------------------------------------------
1 | /*
2 | TODO Just 3 versions
3 | - large - all columns - 12 ?
4 | - medium - half of columns - 6 ?
5 | - small - just 1 column
6 | */
7 |
8 | .db-grid-layout {
9 | display: grid;
10 | grid-auto-rows: minmax(100px, auto);
11 |
12 | .rspan-1 { grid-row-end: span 1; }
13 | .rspan-2 { grid-row-end: span 2; }
14 | .rspan-3 { grid-row-end: span 3; }
15 | .rspan-4 { grid-row-end: span 4; }
16 | .rspan-5 { grid-row-end: span 5; }
17 | .rspan-6 { grid-row-end: span 6; }
18 | .rspan-7 { grid-row-end: span 7; }
19 | .rspan-8 { grid-row-end: span 8; }
20 | .rspan-9 { grid-row-end: span 9; }
21 | .rspan-10 { grid-row-end: span 10; }
22 | .rspan-11 { grid-row-end: span 11; }
23 | .rspan-12 { grid-row-end: span 12; }
24 | .rspan-13 { grid-row-end: span 13; }
25 | .rspan-14 { grid-row-end: span 14; }
26 | .rspan-15 { grid-row-end: span 15; }
27 | .rspan-16 { grid-row-end: span 16; }
28 | }
29 |
30 | /* Small devices (portrait tablets and large phones, 600px and up) */
31 | @media only screen and (min-width: 600px) {
32 | .db-grid-layout {
33 | /* minmax(0px, 1fr) - very important, resizing (making window smaller) on Firefox does not work without it
34 | * See https://github.com/w3c/csswg-drafts/issues/1777 */
35 | grid-template-columns: repeat(16, minmax(0px, 1fr));
36 | .cspan-1 { grid-column-end: span 8; }
37 | .cspan-2 { grid-column-end: span 16; }
38 | .cspan-3 { grid-column-end: span 16; }
39 | .cspan-4 { grid-column-end: span 16; }
40 | .cspan-5 { grid-column-end: span 16; }
41 | .cspan-6 { grid-column-end: span 16; }
42 | .cspan-7 { grid-column-end: span 16; }
43 | .cspan-8 { grid-column-end: span 16; }
44 | .cspan-9 { grid-column-end: span 16; }
45 | .cspan-10 { grid-column-end: span 16; }
46 | .cspan-11 { grid-column-end: span 16; }
47 | .cspan-12 { grid-column-end: span 16; }
48 | .cspan-13 { grid-column-end: span 16; }
49 | .cspan-14 { grid-column-end: span 16; }
50 | .cspan-15 { grid-column-end: span 16; }
51 | .cspan-16 { grid-column-end: span 16; }
52 | }
53 | }
54 |
55 | /* Medium devices (landscape tablets, 768px and up) */
56 | @media only screen and (min-width: 768px) {
57 | .db-grid-layout {
58 | grid-template-columns: repeat(16, minmax(0px, 1fr));
59 | .cspan-1 { grid-column-end: span 4; }
60 | .cspan-2 { grid-column-end: span 8; }
61 | .cspan-3 { grid-column-end: span 12; }
62 | .cspan-4 { grid-column-end: span 16; }
63 | .cspan-5 { grid-column-end: span 16; }
64 | .cspan-6 { grid-column-end: span 16; }
65 | .cspan-7 { grid-column-end: span 16; }
66 | .cspan-8 { grid-column-end: span 16; }
67 | .cspan-9 { grid-column-end: span 16; }
68 | .cspan-10 { grid-column-end: span 16; }
69 | .cspan-11 { grid-column-end: span 16; }
70 | .cspan-12 { grid-column-end: span 16; }
71 | .cspan-13 { grid-column-end: span 16; }
72 | .cspan-14 { grid-column-end: span 16; }
73 | .cspan-15 { grid-column-end: span 16; }
74 | .cspan-16 { grid-column-end: span 16; }
75 | }
76 | }
77 |
78 | /* Large devices (laptops/desktops, 992px and up) */
79 | @media only screen and (min-width: 992px) {
80 | .db-grid-layout {
81 | grid-template-columns: repeat(16, minmax(0px, 1fr));
82 | .cspan-1 { grid-column-end: span 2; }
83 | .cspan-2 { grid-column-end: span 4; }
84 | .cspan-3 { grid-column-end: span 6; }
85 | .cspan-4 { grid-column-end: span 8; }
86 | .cspan-5 { grid-column-end: span 10; }
87 | .cspan-6 { grid-column-end: span 12; }
88 | .cspan-7 { grid-column-end: span 14; }
89 | .cspan-8 { grid-column-end: span 16; }
90 | .cspan-9 { grid-column-end: span 16; }
91 | .cspan-10 { grid-column-end: span 16; }
92 | .cspan-11 { grid-column-end: span 16; }
93 | .cspan-12 { grid-column-end: span 16; }
94 | .cspan-13 { grid-column-end: span 16; }
95 | .cspan-14 { grid-column-end: span 16; }
96 | .cspan-15 { grid-column-end: span 16; }
97 | .cspan-16 { grid-column-end: span 16; }
98 | }
99 | }
100 |
101 | /* Extra large devices (large laptops and desktops, 1200px and up) */
102 | @media only screen and (min-width: 1200px) {
103 | .db-grid-layout {
104 | /* minmax(0px, 1fr) - very important, resizing (making window smaller) on Firefox does not work without it */
105 | grid-template-columns: repeat(16, minmax(0px, 1fr));
106 | .cspan-1 { grid-column-end: span 1; }
107 | .cspan-2 { grid-column-end: span 2; }
108 | .cspan-3 { grid-column-end: span 3; }
109 | .cspan-4 { grid-column-end: span 4; }
110 | .cspan-5 { grid-column-end: span 5; }
111 | .cspan-6 { grid-column-end: span 6; }
112 | .cspan-7 { grid-column-end: span 7; }
113 | .cspan-8 { grid-column-end: span 8; }
114 | .cspan-9 { grid-column-end: span 9; }
115 | .cspan-10 { grid-column-end: span 10; }
116 | .cspan-11 { grid-column-end: span 11; }
117 | .cspan-12 { grid-column-end: span 12; }
118 | .cspan-13 { grid-column-end: span 13; }
119 | .cspan-14 { grid-column-end: span 14; }
120 | .cspan-15 { grid-column-end: span 15; }
121 | .cspan-16 { grid-column-end: span 16; }
122 | }
123 | }
124 |
125 |
--------------------------------------------------------------------------------
/src/assets/scss/dashblocks/_gridlayout12.scss:
--------------------------------------------------------------------------------
1 | /* CSS Grid layout - 12 columns */
2 |
3 | .db-grid-layout-12 {
4 | display: grid;
5 | grid-auto-rows: minmax(100px, auto);
6 | .rspan-1 { grid-row-end: span 1; }
7 | .rspan-2 { grid-row-end: span 2; }
8 | .rspan-3 { grid-row-end: span 3; }
9 | .rspan-4 { grid-row-end: span 4; }
10 | .rspan-5 { grid-row-end: span 5; }
11 | .rspan-6 { grid-row-end: span 6; }
12 | .rspan-7 { grid-row-end: span 7; }
13 | .rspan-8 { grid-row-end: span 8; }
14 | .rspan-9 { grid-row-end: span 9; }
15 | .rspan-10 { grid-row-end: span 10; }
16 | .rspan-11 { grid-row-end: span 11; }
17 | .rspan-12 { grid-row-end: span 12; }
18 | .rspan-13 { grid-row-end: span 13; }
19 | .rspan-14 { grid-row-end: span 14; }
20 | .rspan-15 { grid-row-end: span 15; }
21 | .rspan-16 { grid-row-end: span 16; }
22 | }
23 |
24 | /* Small devices (portrait tablets and large phones, 600px and up) */
25 | @media only screen and (min-width: 600px) {
26 | .db-grid-layout-12 {
27 | /* minmax(0px, 1fr) - very important, resizing (making window smaller) on Firefox does not work without it
28 | * See https://github.com/w3c/csswg-drafts/issues/1777 */
29 | grid-template-columns: repeat(12, minmax(0px, 1fr));
30 | .cspan-1 { grid-column-end: span 6; }
31 | .cspan-2 { grid-column-end: span 12; }
32 | .cspan-3 { grid-column-end: span 12; }
33 | .cspan-4 { grid-column-end: span 12; }
34 | .cspan-5 { grid-column-end: span 12; }
35 | .cspan-6 { grid-column-end: span 12; }
36 | .cspan-7 { grid-column-end: span 12; }
37 | .cspan-8 { grid-column-end: span 12; }
38 | .cspan-9 { grid-column-end: span 12; }
39 | .cspan-10 { grid-column-end: span 12; }
40 | .cspan-11 { grid-column-end: span 12; }
41 | .cspan-12 { grid-column-end: span 12; }
42 | }
43 | }
44 |
45 | /* Medium devices (landscape tablets, 768px and up) */
46 | @media only screen and (min-width: 768px) {
47 | .db-grid-layout-12 {
48 | grid-template-columns: repeat(12, minmax(0px, 1fr));
49 | .cspan-1 { grid-column-end: span 4; }
50 | .cspan-2 { grid-column-end: span 6; }
51 | .cspan-3 { grid-column-end: span 8; }
52 | .cspan-4 { grid-column-end: span 10; }
53 | .cspan-5 { grid-column-end: span 12; }
54 | .cspan-6 { grid-column-end: span 12; }
55 | .cspan-7 { grid-column-end: span 12; }
56 | .cspan-8 { grid-column-end: span 12; }
57 | .cspan-9 { grid-column-end: span 12; }
58 | .cspan-10 { grid-column-end: span 12; }
59 | .cspan-11 { grid-column-end: span 12; }
60 | .cspan-12 { grid-column-end: span 12; }
61 | }
62 | }
63 |
64 | /* Large devices (laptops/desktops, 992px and up) */
65 | @media only screen and (min-width: 992px) {
66 | .db-grid-layout-12 {
67 | grid-template-columns: repeat(12, minmax(0px, 1fr));
68 | .cspan-1 { grid-column-end: span 2; }
69 | .cspan-2 { grid-column-end: span 4; }
70 | .cspan-3 { grid-column-end: span 6; }
71 | .cspan-4 { grid-column-end: span 8; }
72 | .cspan-5 { grid-column-end: span 10; }
73 | .cspan-6 { grid-column-end: span 12; }
74 | .cspan-7 { grid-column-end: span 12; }
75 | .cspan-8 { grid-column-end: span 12; }
76 | .cspan-9 { grid-column-end: span 12; }
77 | .cspan-10 { grid-column-end: span 12; }
78 | .cspan-11 { grid-column-end: span 12; }
79 | .cspan-12 { grid-column-end: span 12; }
80 | }
81 | }
82 |
83 | /* Extra large devices (large laptops and desktops, 1200px and up) */
84 | @media only screen and (min-width: 1200px) {
85 | .db-grid-layout-12 {
86 | /* minmax(0px, 1fr) - very important, resizing (making window smaller) on Firefox does not work without it */
87 | grid-template-columns: repeat(12, minmax(0px, 1fr));
88 | .cspan-1 { grid-column-end: span 1; }
89 | .cspan-2 { grid-column-end: span 2; }
90 | .cspan-3 { grid-column-end: span 3; }
91 | .cspan-4 { grid-column-end: span 4; }
92 | .cspan-5 { grid-column-end: span 5; }
93 | .cspan-6 { grid-column-end: span 6; }
94 | .cspan-7 { grid-column-end: span 7; }
95 | .cspan-8 { grid-column-end: span 8; }
96 | .cspan-9 { grid-column-end: span 9; }
97 | .cspan-10 { grid-column-end: span 10; }
98 | .cspan-11 { grid-column-end: span 11; }
99 | .cspan-12 { grid-column-end: span 12; }
100 | }
101 | }
102 |
103 |
--------------------------------------------------------------------------------
/src/assets/scss/dashblocks/_variables.scss:
--------------------------------------------------------------------------------
1 |
2 | // Dashblocks Variables
3 |
4 | $primary : #027BE3;
5 | $secondary : #26A69A;
6 | $accent : #9C27B0;
7 |
8 | $positive : #21BA45;
9 | $negative : #C10015;
10 | $info : #31CCEC;
11 | $warning : #F2C037;
12 |
13 | $light : #bdbdbd;
14 | $dark : #424242;
15 | $faded : #777;
16 |
17 | $white : #FFFFFF;
18 | $black : #000000;
19 |
20 |
21 | // Colors for ranges
22 | $neutral : material-color('light-blue', '900');
23 | $success : material-color('light-green', '900');
24 | $warning : material-color('orange', '900');
25 | $alarm : material-color('red', '900');
26 |
27 | // TODO - is this needed ?
28 | $dimmed-background : rgba(0, 0, 0, .4);
29 | $light-dimmed-background : rgba(255, 255, 255, .6);
30 | $separator-color : rgba(0, 0, 0, .12);
31 | $separator-dark-color : rgba(255, 255, 255, .48);
32 |
33 |
34 | // Fonts
35 | $font-family: 'Roboto', sans-serif;
36 | $font-size: 14px;
37 |
38 | // Text - TODO - is it needed ?
39 | $on-primary: white;
40 | $on-secondary: black;
41 | $on-background: material-color('grey', '800');
42 | $on-surface: $faded;
43 | $on-error: white;
44 |
45 |
46 |
47 |
48 | // Sidebar variables
49 |
50 | $primaryColor: #4285f4 !default;
51 | $baseBg: #2a2a2e !default;
52 | $baseIconBg: red !default;
53 | $darkenBg: darken( $baseBg, 5% ) !default;
54 | $lightenBg: lighten( $baseBg, 5% ) !default;
55 |
56 | $itemColor: #fff !default;
57 |
58 | $itemOpenColor: #fff !default;
59 | $itemOpenBg: $primaryColor !default;
60 |
61 | $itemHoverColor: #fff !default;
62 | $itemHoverBg: rgba($darkenBg, 0.5) !default;
63 |
64 | $iconColor: #fff !default;
65 | $iconBg: darken( $baseIconBg, 25% ) !default;
66 |
67 | $iconActiveColor: #fff !default;
68 | $iconActiveBg: lighten( $baseIconBg, 10% ) !default;
69 |
70 | $iconOpenColor: #fff !default;
71 | $iconOpenBg: transparent !default;
72 |
73 | $mobileItemColor: #fff !default;
74 | $mobileItemBg: $primaryColor !default;
75 | $mobileIconBg: transparent !default;
76 | $mobileIconColor: #fff !default;
77 |
78 | $dropDownColor: #fff !default;
79 | $dropDownBg: $lightenBg !default;
80 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/src/assets/scss/dashblocks/components/_dbdygraps.scss:
--------------------------------------------------------------------------------
1 | .db-dygraphs {
2 | width: 100%;
3 | height: 100%;
4 |
5 | & .dygraph-axis-label {
6 | font-size: 12px;
7 | }
8 |
9 | & .dygraph-ylabel {
10 | font-size: 16px;
11 | }
12 |
13 | & .dygraph-title {
14 | font-size: 16px;
15 | font-weight: normal;
16 | text-align: left;
17 | }
18 |
19 | & .dygraph-legend {
20 | background-color: rgba(255, 255, 255, 0.85);
21 | padding: 4px;
22 | border: 1px solid #e0e0e0;
23 | border-radius: 2px;
24 | pointer-events: none;
25 | min-width: 250px;
26 | max-width: 600px;
27 | width: fit-content;
28 | font-size: 12px;
29 | position: relative;
30 | }
31 | }
32 |
33 | .db-dark {
34 | & .db-dygraphs {
35 | & .dygraph-legend {
36 | color: #e0e0e0;
37 | background-color: rgba(69, 90, 100, 0.5);
38 | padding: 4px;
39 | border: 1px solid #263238;
40 | border-radius: 2px;
41 | pointer-events: none;
42 | min-width: 250px;
43 | max-width: 600px;
44 | width: fit-content;
45 | font-size: 12px;
46 | position: relative;
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/assets/scss/dashblocks/components/_dbeasypie.scss:
--------------------------------------------------------------------------------
1 | .db-easy-pie {
2 | position: relative;
3 | text-align: center;
4 | width: 100%;
5 | height: 100%;
6 |
7 | .inner-text {
8 | position: absolute;
9 | top: 0;
10 | left: 0;
11 | right: 0;
12 | bottom: 0;
13 | text-align: center;
14 | display: block;
15 | }
16 | }
17 |
18 |
--------------------------------------------------------------------------------
/src/assets/scss/dashblocks/components/_dbnumber.scss:
--------------------------------------------------------------------------------
1 | .db-number {
2 | width: 100%;
3 | height: 100%;
4 | display: flex;
5 | flex-flow: column;
6 |
7 | .db-n-content {
8 | width: 100%;
9 | flex: 2;
10 | position: relative;
11 | }
12 |
13 | .db-n-layer {
14 | position: absolute;
15 | width: 100%;
16 | height: 100%;
17 | }
18 |
19 | .db-n-main {
20 | position: relative;
21 | width: 100%;
22 | height: 100%;
23 | }
24 |
25 | .db-n-value {
26 | font-size: 210%;
27 | }
28 | .db-n-footer {
29 | height: 18px;
30 | }
31 |
32 | .db-n-subtitle {
33 | font-size: 100%;
34 | }
35 |
36 | .db-n-icon {
37 | font-size: 180%;
38 | padding: 2px;
39 | border-radius: 4px;
40 | color: white;
41 | opacity: 0.4;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/assets/scss/dashblocks/themes/_theme-dark.scss:
--------------------------------------------------------------------------------
1 | @import "../dbdashboard";
2 |
3 | $accent: red;
4 |
5 | .db-dashboard.db-theme-dark {
6 | @include db-dashboard;
7 | color: white;
8 |
9 | & .db-widget-container {
10 | border: 1px solid material-color('red', '600');
11 | }
12 |
13 | }
14 |
15 |
--------------------------------------------------------------------------------
/src/assets/scss/dashblocks/themes/_theme-default.scss:
--------------------------------------------------------------------------------
1 | @import '../dbdashboard';
2 |
3 |
4 | // TODO How to override variables for dark scheme ?
5 |
6 | .db-dashboard.db-theme-default {
7 | @include db-dashboard;
8 |
9 | & .db-txt-faded {
10 | color: material-color('grey', '700');
11 | }
12 |
13 | & .db-txt-highlight {
14 | color: material-color('grey', '800');
15 | }
16 |
17 | }
18 |
19 | .db-dashboard.db-theme-default.db-dark {
20 | color: $faded;
21 |
22 | & .db-txt-faded {
23 | color: material-color('grey', '700');
24 | }
25 |
26 | & .db-txt-highlight {
27 | color: material-color('grey', '500');
28 | }
29 |
30 | & .db-widget-container {
31 | border: 0px;
32 | background: material-color('grey', '900');
33 | }
34 |
35 | & .dygraph-axis-label {
36 | color: $light;
37 | }
38 | }
39 |
40 | .db-dashboard.db-transparent.db-theme-default {
41 | & .db-widget-container {
42 | background: none;
43 | }
44 | }
45 |
46 | .db-rsb {
47 | display: grid;
48 | grid-template-columns: 1fr minmax(100px, 25%);
49 | }
50 |
--------------------------------------------------------------------------------
/src/components.js:
--------------------------------------------------------------------------------
1 | export * from './components/dashboard/index.js';
2 | export * from './components/dygraphs/index.js';
3 | export * from './components/chartjs/index.js';
4 | export * from './components/db/index.js';
5 | export * from './components/funnel/index.js';
6 | export * from './components/d3/index.js';
7 | export * from './components/perspective/index.js';
8 | export * from './components/geo/index.js';
9 |
--------------------------------------------------------------------------------
/src/components/chartjs/index.js:
--------------------------------------------------------------------------------
1 | import {
2 | DbChartjsBar,
3 | DbChartjsHorizontalBar,
4 | DbChartjsDoughnut,
5 | DbChartjsLine,
6 | DbChartjsPie,
7 | DbChartjsPolarArea,
8 | DbChartjsRadar,
9 | DbChartjsBubble,
10 | DbChartjsScatter,
11 | DbChartjsFunnel
12 | } from './DbChartjs';
13 |
14 | export {
15 | DbChartjsBar,
16 | DbChartjsHorizontalBar,
17 | DbChartjsDoughnut,
18 | DbChartjsLine,
19 | DbChartjsPie,
20 | DbChartjsPolarArea,
21 | DbChartjsRadar,
22 | DbChartjsBubble,
23 | DbChartjsScatter,
24 | DbChartjsFunnel
25 | };
26 |
--------------------------------------------------------------------------------
/src/components/d3/domuid.js:
--------------------------------------------------------------------------------
1 | let count = 0;
2 |
3 | export default function(name) {
4 | return new Id('O-' + (name == null ? '' : name + '-') + ++count);
5 | }
6 |
7 | function Id(id) {
8 | this.id = id;
9 | //this.href = window.location.href + "#" + id;
10 | this.href = '#' + id;
11 | }
12 |
13 | Id.prototype.toString = function() {
14 | return 'url(' + this.href + ')';
15 | };
16 |
--------------------------------------------------------------------------------
/src/components/d3/index.js:
--------------------------------------------------------------------------------
1 | import DbHorizon from './DbHorizon';
2 | import DbSunburst from './DbSunburst';
3 | import DbSankey from './DbSankey';
4 | import DbRidgeline from './DbRidgeline';
5 |
6 | export { DbHorizon, DbSunburst, DbSankey, DbRidgeline };
7 |
--------------------------------------------------------------------------------
/src/components/dashboard/DbDashboard.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
80 |
81 | /* Notes ** That works: components: { 'WidgetOne': () => import('./WidgetOne.vue') }, */
82 |
--------------------------------------------------------------------------------
/src/components/dashboard/index.js:
--------------------------------------------------------------------------------
1 | import DbDashboard from './DbDashboard';
2 |
3 | export { DbDashboard };
4 |
--------------------------------------------------------------------------------
/src/components/db/DbEasyPie.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ percent }}%
5 |
6 |
7 |
8 |
162 |
--------------------------------------------------------------------------------
/src/components/db/DbMarkup.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
15 |
--------------------------------------------------------------------------------
/src/components/db/DbMultiProgress.vue:
--------------------------------------------------------------------------------
1 | /* DashBlocks: Multi-Progress
2 | * Shows multiple progress values simultaneously */
3 |
4 |
5 |
{{ title }}
6 |
7 |
8 |
{{ item.title }}
9 |
{{ formatValue(item.value) }}
10 |
11 |
12 |
13 |
14 |
15 |
16 |
157 |
--------------------------------------------------------------------------------
/src/components/db/DbNone.vue:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/src/components/db/DbNumber.vue:
--------------------------------------------------------------------------------
1 | /* DashBlocks: Number widget */
2 |
3 |
4 |
5 |
6 |
7 |
8 |
11 |
16 |
17 |
18 | {{ title }}
19 |
20 |
21 |
{{ formattedValue }}
22 |
{{ subtitle }}
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
151 |
--------------------------------------------------------------------------------
/src/components/db/DbProgress.vue:
--------------------------------------------------------------------------------
1 | /* DashBlocks: Number widget */
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
{{ title }}
11 |
{{ subtitle }}
12 |
13 |
{{ formattedValue }}
14 |
15 |
16 |
17 |
37 |
38 |
39 |
158 |
184 |
--------------------------------------------------------------------------------
/src/components/db/DbSparkline.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
134 |
--------------------------------------------------------------------------------
/src/components/db/DbTrendBar.vue:
--------------------------------------------------------------------------------
1 | /* DbTrendLine: Trend Line using https://github.com/QingWei-Li/vue-trend */
2 |
3 |
4 |
17 |
18 |
19 |
20 |
102 |
--------------------------------------------------------------------------------
/src/components/db/DbTrendLine.vue:
--------------------------------------------------------------------------------
1 | /* DbTrendLine: Trend Line using https://github.com/QingWei-Li/vue-trend */
2 |
3 |
4 |
20 |
21 |
22 |
23 |
116 |
--------------------------------------------------------------------------------
/src/components/db/index.js:
--------------------------------------------------------------------------------
1 | import DbNumber from './DbNumber';
2 | import DbEasyPie from './DbEasyPie';
3 | import DbTrendLine from './DbTrendLine';
4 | import DbTrendBar from './DbTrendBar';
5 | import DbSparkline from './DbSparkline';
6 | import DbSparkLineMap from './DbSparkLinemap';
7 | import DbSparkHeatMap from './DbSparkHeatmap';
8 | import DbNone from './DbNone';
9 | import DbMarkup from './DbMarkup';
10 | import DbLinearProgress from './DbLinearProgress';
11 | import DbProgress from './DbProgress';
12 | import DbMultiProgress from './DbMultiProgress';
13 | //import DbSparkRidgeline from './DbSparkRidgeline';
14 |
15 | export { DbNumber, DbEasyPie, DbTrendLine, DbTrendBar, DbSparkline, DbSparkLineMap, DbSparkHeatMap, DbNone, DbMarkup, DbLinearProgress, DbProgress, DbMultiProgress};
16 |
--------------------------------------------------------------------------------
/src/components/dbdata.js:
--------------------------------------------------------------------------------
1 | /* DashBlocks Data */
2 |
3 | import Vue from 'vue';
4 | import pathOr from 'ramda/es/pathOr';
5 |
6 | // TODO Support different kinds of data
7 | // - plain hash by widget name
8 | // - tabular data - i.e. query result from SQL
9 | // - support "query" in widgets to get data from table
10 | // - dataframes
11 |
12 | /* DashBlocks Data holder */
13 | class DbData {
14 | constructor() {
15 | // TODO accept widgets data set here
16 | // go through each key and add _updated
17 | this._updated = Date.now();
18 | }
19 |
20 | // TODO Get
21 |
22 | // TODO Set / Update
23 | setWData(key, data) {
24 | /*
25 | if (!(key in this)) {
26 | Vue.set(this, key, {d:data});
27 | Vue.set(this[key], '_updated', Date.now());
28 | } else {
29 | //Vue.set(this, key, data);
30 | this[key].d = data;
31 | this[key]['_updated'] = Date.now();
32 | }*/
33 | Vue.set(this, key, data);
34 | Vue.set(this[key], '_updated', Date.now());
35 | this['_updated'] = Date.now();
36 | }
37 |
38 | setUpdated(key) {
39 | Vue.set(this[key], '_updated', Date.now());
40 | Vue.set(this, '_updated', Date.now());
41 | }
42 |
43 | touch(key) {
44 | Vue.set(this[key], '_updated', Date.now());
45 | Vue.set(this, '_updated', Date.now());
46 | }
47 |
48 | getWData(key) {
49 | return pathOr(null, [key], this);
50 | }
51 |
52 | // TODO in setters, modify property like _updated = Date.now(), to trigger prop watch
53 | }
54 |
55 | export default DbData;
56 |
--------------------------------------------------------------------------------
/src/components/dblayouts.js:
--------------------------------------------------------------------------------
1 | // Import all Db Layouts
2 | import DbGridLayout from './layout/DbGridLayout.vue';
3 |
4 | // Mapping of layout name to layout component name
5 | const DB_LAYOUT = Object.freeze({
6 | grid: 'DbGridLayout'
7 | });
8 |
9 | // Resolve layout component by layout name
10 | function resolveLayout(layoutname) {
11 | // grid is default
12 | if (!(layoutname in DB_LAYOUT)) {
13 | return 'DbGridLayout';
14 | }
15 | return DB_LAYOUT[layoutname];
16 | }
17 |
18 | export default {
19 | DB_LAYOUT: DB_LAYOUT,
20 | components: {
21 | DbGridLayout
22 | },
23 | resolve: resolveLayout
24 | };
25 |
--------------------------------------------------------------------------------
/src/components/dbwidgets.js:
--------------------------------------------------------------------------------
1 | // Import all Db Widgets
2 | import DbHorizon from './d3/DbHorizon';
3 | import DbSunburst from './d3/DbSunburst';
4 | import DbSankey from './d3/DbSankey';
5 | import DbRidgeline from './d3/DbRidgeline';
6 | import {
7 | DbChartjsBar,
8 | DbChartjsHorizontalBar,
9 | DbChartjsDoughnut,
10 | DbChartjsLine,
11 | DbChartjsPie,
12 | DbChartjsPolarArea,
13 | DbChartjsRadar,
14 | DbChartjsBubble,
15 | DbChartjsScatter
16 | } from './chartjs/DbChartjs';
17 | import DbNumber from './db/DbNumber';
18 | import DbEasyPie from './db/DbEasyPie';
19 | import DbTrendLine from './db/DbTrendLine';
20 | import DbTrendBar from './db/DbTrendBar';
21 | import DbSparkline from './db/DbSparkline';
22 | /* TODO Revisit Plotly
23 | import DbPlotly from './plotly/DbPlotly';
24 | import DbPlotlyLine from './plotly/DbPlotlyLine';
25 | import DbPlotlyPie from './plotly/DbPlotlyPie';
26 | */
27 | import DbDygraphsBar from './dygraphs/DbDygraphsBar';
28 | import DbDygraphsLine from './dygraphs/DbDygraphsLine';
29 | import DbDygraphsSparkLine from './dygraphs/DbDygraphsSparkLine';
30 | import DbDygraphsDateTimeHistogram from './dygraphs/DbDygraphsDateTimeHistogram';
31 |
32 | export {
33 | DbHorizon,
34 | DbSunburst,
35 | DbSankey,
36 | DbRidgeline,
37 | DbChartjsBar,
38 | DbChartjsHorizontalBar,
39 | DbChartjsDoughnut,
40 | DbChartjsLine,
41 | DbChartjsPie,
42 | DbChartjsPolarArea,
43 | DbChartjsRadar,
44 | DbChartjsBubble,
45 | DbChartjsScatter,
46 | DbNumber,
47 | DbEasyPie,
48 | DbTrendLine,
49 | DbTrendBar,
50 | DbSparkline,
51 | /*
52 | DbPlotly,
53 | DbPlotlyLine,
54 | DbPlotlyPie,
55 | */
56 | DbDygraphsBar,
57 | DbDygraphsLine,
58 | DbDygraphsSparkLine,
59 | DbDygraphsDateTimeHistogram
60 | };
61 |
--------------------------------------------------------------------------------
/src/components/dygraphs/DbDygraphsBar.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
114 |
--------------------------------------------------------------------------------
/src/components/dygraphs/DbDygraphsDateTimeHistogram.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
136 |
153 |
--------------------------------------------------------------------------------
/src/components/dygraphs/DbDygraphsLine.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
70 |
98 |
--------------------------------------------------------------------------------
/src/components/dygraphs/index.js:
--------------------------------------------------------------------------------
1 | import DbDygraphs from './DbDygraphs';
2 | import DbDygraphsBar from './DbDygraphsBar';
3 | import DbDygraphsLine from './DbDygraphsLine';
4 | import DbDygraphsSparkLine from './DbDygraphsSparkLine';
5 | import DbDygraphsDateTimeHistogram from './DbDygraphsDateTimeHistogram';
6 |
7 | export { DbDygraphs, DbDygraphsBar, DbDygraphsLine, DbDygraphsSparkLine, DbDygraphsDateTimeHistogram };
8 |
--------------------------------------------------------------------------------
/src/components/funnel/index.js:
--------------------------------------------------------------------------------
1 | import DbFunnel from './DbFunnel';
2 |
3 | export { DbFunnel };
4 |
--------------------------------------------------------------------------------
/src/components/geo/index.js:
--------------------------------------------------------------------------------
1 | import DbGeoMapbox from './DbGeoMapbox';
2 |
3 | export { DbGeoMapbox };
4 |
--------------------------------------------------------------------------------
/src/components/index.js:
--------------------------------------------------------------------------------
1 | import DbData from './dbdata';
2 | import DbColors from './dbcolors';
3 | import DbUtils from './dbutils';
4 | import DbDashboard from './dashboard/DbDashboard';
5 | import { dbStdProps } from './mixins/dbstdprops';
6 | //import DbDygraphsBar from './dygraphs/DbDygraphsBar';
7 | // ???
8 | import * as dbComponents from './dbwidgets';
9 | import '../assets/scss/dashblocks.scss';
10 |
11 | const DashBlocks = {
12 | install(Vue) {
13 | Vue.component('DbDashboard', DbDashboard);
14 |
15 | Object.keys(dbComponents).forEach(key => {
16 | const c = dbComponents[key];
17 | Vue.component(key, c);
18 | });
19 |
20 | //Vue.component('DbDygraphsBar', DbDygraphsBar);
21 | /*
22 | Vue.component('db-dygraphs-bundle', function(resolve) {
23 | // This special require syntax will instruct Webpack to
24 | // automatically split your built code into bundles which
25 | // are loaded over Ajax requests.
26 | require(['./dygraphs/DbDygraphsBar'], resolve);
27 | });
28 | */
29 | }
30 | };
31 |
32 | export { DbData, DbColors, DbUtils, DbDashboard, DashBlocks, dbStdProps };
33 |
34 | //export default DashBlocks;
35 |
36 | /* TODO Consider this, make reasonable bundles of components based on underlying library
37 |
38 | Vue.component('async-webpack-example', function (resolve) {
39 | // This special require syntax will instruct Webpack to
40 | // automatically split your built code into bundles which
41 | // are loaded over Ajax requests.
42 | require(['./my-async-component'], resolve)
43 | })
44 |
45 | */
46 |
47 | /*
48 | const DashBlocks = {
49 | install(Vue) {
50 | Object.keys(dbComponents).forEach(name => {
51 | Vue.component(name, dbComponents[name]);
52 | });
53 | }
54 | };
55 | */
56 |
57 | /*
58 | Object.keys(DashBlocks).forEach(name => {
59 | console.log('Registergin component: ' + name);
60 | Vue.component(name, DashBlocks[name]);
61 | });
62 |
63 | export default DashBlocks;
64 | */
65 |
--------------------------------------------------------------------------------
/src/components/layout/DbGridLayout.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
14 |
15 |
16 |
17 |
18 |
76 |
81 |
--------------------------------------------------------------------------------
/src/components/layout/DbWidgetContainer.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
13 |
14 |
15 |
16 |
17 |
99 |
100 |
--------------------------------------------------------------------------------
/src/components/log.js:
--------------------------------------------------------------------------------
1 | import * as log from 'loglevel';
2 | import moment from 'moment';
3 |
4 | let LOG_LEVEL = 'info';
5 |
6 | let origFactory = log.methodFactory;
7 | log.methodFactory = function(methodName, logLevel, loggerName) {
8 | let origMethod = origFactory(methodName, logLevel, loggerName);
9 | return function(message) {
10 | const timestamp = moment([]).format('hh:mm:ss');
11 | const msg = `${timestamp} [${methodName.toUpperCase()}] [DB]: ${message}`;
12 | origMethod(msg);
13 | };
14 | };
15 |
16 | //log.setLevel(log.getLevel());
17 | log.setLevel(LOG_LEVEL);
18 |
19 | export default log;
20 |
--------------------------------------------------------------------------------
/src/components/mixins/dbstdprops.js:
--------------------------------------------------------------------------------
1 | // Standard properties for Dashblocks components
2 | export const dbStdProps = {
3 | props: {
4 | /**
5 | * Change to trigger data update.
6 | * Set this to current timestamp to inform component that data has been updated.
7 | * Helpful in situations when, for example, only values in array are changed.
8 | * See https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats
9 | */
10 | _updated: {
11 | type: Number,
12 | default: 0
13 | },
14 | /**
15 | * Enable dark mode
16 | *
17 | * `true,false`
18 | */
19 | dark: {
20 | type: Boolean,
21 | default: false
22 | },
23 | /**
24 | * Color Scheme Name
25 | * App may define multiple color schemes for different charts
26 | * and use this prop to specify which colorScheme to use
27 | * default: "default" - refers to default dashblocks colorScheme which is always defined
28 | */
29 | colorScheme: {
30 | type: String,
31 | default: 'default'
32 | }
33 | }
34 | };
35 |
--------------------------------------------------------------------------------
/src/components/perspective/DbPerspective.vue:
--------------------------------------------------------------------------------
1 | /* DbPerspective * Perspective viewer: https://perspective.finos.org/ */
2 |
3 |
4 |
5 |
61 |
--------------------------------------------------------------------------------
/src/components/perspective/index.js:
--------------------------------------------------------------------------------
1 | import DbPerspective from './DbPerspective';
2 |
3 | export { DbPerspective };
4 |
--------------------------------------------------------------------------------
/src/components/plotly/DbPlotly.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
78 |
79 |
--------------------------------------------------------------------------------
/src/components/plotly/DbPlotlyLine.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
47 |
48 |
--------------------------------------------------------------------------------
/src/components/plotly/DbPlotlyPie.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
45 |
--------------------------------------------------------------------------------
/src/components/utils/colors.js:
--------------------------------------------------------------------------------
1 | import map from 'lodash/map';
2 | import sortBy from 'lodash/sortBy';
3 | import flattenDeep from 'lodash/flattenDeep';
4 | import chunk from 'lodash/chunk';
5 | import zip from 'lodash/zip';
6 | import tinycolor from 'tinycolor2';
7 |
8 | export const PALETTE_ROWS = 4;
9 | export const PALETTE_COLUMNS = 14;
10 | export const DEFAULT_ANNOTATION_COLOR = 'rgba(0, 211, 255, 1)';
11 | export const OK_COLOR = 'rgba(11, 237, 50, 1)';
12 | export const ALERTING_COLOR = 'rgba(237, 46, 24, 1)';
13 | export const NO_DATA_COLOR = 'rgba(150, 150, 150, 1)';
14 | export const PENDING_COLOR = 'rgba(247, 149, 32, 1)';
15 | export const REGION_FILL_ALPHA = 0.09;
16 | export const colors = [
17 | '#7EB26D', // 0: pale green
18 | '#EAB839', // 1: mustard
19 | '#6ED0E0', // 2: light blue
20 | '#EF843C', // 3: orange
21 | '#E24D42', // 4: red
22 | '#1F78C1', // 5: ocean
23 | '#BA43A9', // 6: purple
24 | '#705DA0', // 7: violet
25 | '#508642', // 8: dark green
26 | '#CCA300', // 9: dark sand
27 | '#447EBC',
28 | '#C15C17',
29 | '#890F02',
30 | '#0A437C',
31 | '#6D1F62',
32 | '#584477',
33 | '#B7DBAB',
34 | '#F4D598',
35 | '#70DBED',
36 | '#F9BA8F',
37 | '#F29191',
38 | '#82B5D8',
39 | '#E5A8E2',
40 | '#AEA2E0',
41 | '#629E51',
42 | '#E5AC0E',
43 | '#64B0C8',
44 | '#E0752D',
45 | '#BF1B00',
46 | '#0A50A1',
47 | '#962D82',
48 | '#614D93',
49 | '#9AC48A',
50 | '#F2C96D',
51 | '#65C5DB',
52 | '#F9934E',
53 | '#EA6460',
54 | '#5195CE',
55 | '#D683CE',
56 | '#806EB7',
57 | '#3F6833',
58 | '#967302',
59 | '#2F575E',
60 | '#99440A',
61 | '#58140C',
62 | '#052B51',
63 | '#511749',
64 | '#3F2B5B',
65 | '#E0F9D7',
66 | '#FCEACA',
67 | '#CFFAFF',
68 | '#F9E2D2',
69 | '#FCE2DE',
70 | '#BADFF4',
71 | '#F9D9F9',
72 | '#DEDAF7'
73 | ];
74 |
75 | function sortColorsByHue(hexColors) {
76 | const hslColors = map(hexColors, hexToHsl);
77 |
78 | const sortedHSLColors = sortBy(hslColors, ['h']);
79 | const chunkedHSLColors = chunk(sortedHSLColors, PALETTE_ROWS);
80 | const sortedChunkedHSLColors = map(chunkedHSLColors, chunk => {
81 | return sortBy(chunk, 'l');
82 | });
83 | const flattenedZippedSortedChunkedHSLColors = flattenDeep(zip(...sortedChunkedHSLColors));
84 |
85 | return map(flattenedZippedSortedChunkedHSLColors, hslToHex);
86 | }
87 |
88 | function hexToHsl(color) {
89 | return tinycolor(color).toHsl();
90 | }
91 |
92 | function hslToHex(color) {
93 | return tinycolor(color).toHexString();
94 | }
95 |
96 | let sortedColors = sortColorsByHue(colors);
97 | export default sortedColors;
98 |
--------------------------------------------------------------------------------
/src/css.js:
--------------------------------------------------------------------------------
1 | // TODO Consider if needed
2 | //import '../assets/vendor/nucleo/css/nucleo.css';
3 | //import '../assets/vendor/font-awesome/css/font-awesome.css';
4 | import './assets/scss/dashblocks.scss';
5 | import './demo/themes/_theme_custom.scss';
6 |
--------------------------------------------------------------------------------
/src/demo/assets/images/poster_grand_tour.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/slanatech/dashblocks/313aa29d14a23c5d50389ba3e1bb447c33ab1aa9/src/demo/assets/images/poster_grand_tour.png
--------------------------------------------------------------------------------
/src/demo/dashboards/ChartJsShowcase.json:
--------------------------------------------------------------------------------
1 | {
2 | "layout": {
3 | "type": "grid"
4 | },
5 | "widgets": [
6 | {
7 | "id": "w1",
8 | "type": "DbChartjsLine",
9 | "cspan": 4,
10 | "height": 250,
11 | "properties": {
12 | "options": {
13 | "maintainAspectRatio": false,
14 | "legend": {
15 | "labels": {
16 | "fontColor": "red"
17 | }
18 | }
19 | }
20 | }
21 | },
22 | {
23 | "id": "w2",
24 | "type": "DbChartjsBar",
25 | "cspan": 4,
26 | "height": 250
27 | },
28 | {
29 | "id": "w3",
30 | "type": "DbChartjsHorizontalBar",
31 | "cspan": 4
32 | },
33 | {
34 | "id": "w4",
35 | "type": "DbChartjsPie",
36 | "cspan": 4
37 | },
38 | {
39 | "id": "w5",
40 | "type": "DbChartjsDoughnut",
41 | "cspan": 4,
42 | "height": 250
43 | },
44 | {
45 | "id": "w6",
46 | "type": "DbChartjsPolarArea",
47 | "cspan": 4,
48 | "height": 250
49 | },
50 | {
51 | "id": "w7",
52 | "type": "DbChartjsRadar",
53 | "cspan": 4,
54 | "height": 250
55 | },
56 | {
57 | "id": "w8",
58 | "type": "DbChartjsBar",
59 | "cspan": 4,
60 | "height": 250
61 | },
62 | {
63 | "id": "w9",
64 | "type": "DbChartjsBubble",
65 | "cspan": 8,
66 | "height": 300
67 | },
68 | {
69 | "id": "w10",
70 | "type": "DbChartjsScatter",
71 | "cspan": 8,
72 | "height": 300,
73 | "properties": {
74 | "options": {
75 | "scales": {
76 | "xAxes": [{
77 | "type": "linear",
78 | "position": "bottom"
79 | }]
80 | }
81 | }
82 | }
83 | },
84 | {
85 | "id": "w11",
86 | "type": "DbChartjsFunnel",
87 | "cspan": 8,
88 | "height": 300,
89 | "properties": {
90 | "options": {
91 | "sort": "desc",
92 | "keep": "auto",
93 | "legend": {
94 | "display": true
95 | }
96 | }
97 | }
98 | }
99 | ]
100 | }
101 |
--------------------------------------------------------------------------------
/src/demo/dashboards/dashfive.json:
--------------------------------------------------------------------------------
1 | {
2 | "layout": {
3 | "type": "grid"
4 | },
5 | "widgets": [
6 | {
7 | "id": "wa",
8 | "type": "DbDygraphsBar",
9 | "cspan": 16,
10 | "height": 250,
11 | "properties": {
12 | "options": {
13 | "stackedGraph": true
14 | }
15 | }
16 | },
17 | {
18 | "id": "w0",
19 | "type": "DbTrendLine",
20 | "cspan": 4,
21 | "properties": {
22 | "smooth": false,
23 | "strokeWidth": 1
24 | }
25 | },
26 | {
27 | "id": "w0",
28 | "type": "DbTrendLine",
29 | "cspan": 4
30 | },
31 | {
32 | "id": "w1",
33 | "type": "DbTrendBar",
34 | "cspan": 4
35 | },
36 | {
37 | "id": "w2",
38 | "type": "DbTrendBar",
39 | "cspan": 4
40 | },
41 | {
42 | "id": "w4",
43 | "type": "DbNumber",
44 | "cspan": 4,
45 | "properties": {
46 | "title": "Test OK",
47 | "badge": "req/s",
48 | "icon" : "fa fa-signal",
49 | "ranges": [1000,2000]
50 | }
51 | },
52 | {
53 | "id": "w5",
54 | "type": "DbNumber",
55 | "cspan": 4,
56 | "properties": {
57 | "title": "Test Warning",
58 | "badge": "req/s",
59 | "icon" : "fa fa-clock",
60 | "ranges": [1000,2000]
61 | }
62 | },
63 | {
64 | "id": "w6",
65 | "type": "DbNumber",
66 | "cspan": 4,
67 | "properties": {
68 | "title": "Test Alarm",
69 | "badge": "req/s",
70 | "icon" : "fa fa-chart-bar",
71 | "ranges": [1000,2000]
72 | }
73 | },
74 | {
75 | "id": "w7",
76 | "type": "DbPlotly",
77 | "cspan": 16,
78 | "rspan": 2,
79 | "properties": {
80 | "layout": {
81 | "paper_bgcolor":"rgba(0,0,0,0)",
82 | "plot_bgcolor":"rgba(0,0,0,0)",
83 | "modebar": {
84 | "bgcolor": "rgba(0,0,0,0)",
85 | "color": "rgba(0,0,0,0.5)"
86 | },
87 | "title": "reactive charts",
88 | "xaxis": {
89 | "title": "xaxis title"
90 | },
91 | "yaxis": {
92 | "title": "yaxis title"
93 | },
94 | "margin": {
95 | "l": 60,
96 | "r": 40,
97 | "b": 40,
98 | "t": 40,
99 | "pad": 5
100 | }
101 | }
102 | }
103 | },
104 | {
105 | "id": "w8",
106 | "type": "DbPlotlyLine",
107 | "cspan": 10,
108 | "height": 300,
109 | "properties": {
110 | "layout": {
111 | "template": "plotly_dark",
112 | "paper_bgcolor":"rgba(0,0,0,0)",
113 | "plot_bgcolor":"rgba(0,0,0,0)",
114 | "modebar": {
115 | "bgcolor": "rgba(0,0,0,0)",
116 | "color": "rgba(0,0,0,0.5)"
117 | },
118 | "margin": {
119 | "l": 60,
120 | "r": 40,
121 | "b": 40,
122 | "t": 40,
123 | "pad": 5
124 | }
125 | }
126 | }
127 | },
128 | {
129 | "id": "w9",
130 | "type": "DbPlotlyPie",
131 | "cspan": 6,
132 | "height": 300,
133 | "properties": {
134 | "layout": {
135 | "legend": {
136 | "orientation": "h"
137 | },
138 | "paper_bgcolor":"rgba(0,0,0,0)",
139 | "plot_bgcolor":"rgba(0,0,0,0)",
140 | "modebar": {
141 | "bgcolor": "rgba(0,0,0,0)",
142 | "color": "rgba(0,0,0,0.5)"
143 | },
144 | "margin": {
145 | "l": 60,
146 | "r": 40,
147 | "b": 40,
148 | "t": 40,
149 | "pad": 5
150 | }
151 | }
152 | }
153 | }
154 |
155 |
156 | ]
157 | }
158 |
--------------------------------------------------------------------------------
/src/demo/dashboards/dashsix.json:
--------------------------------------------------------------------------------
1 | {
2 | "layout": {
3 | "type": "grid"
4 | },
5 | "widgets": [
6 | {
7 | "id": "w1",
8 | "type": "DbDygraphsBar",
9 | "cspan": 16,
10 | "height": 250,
11 | "properties": {
12 | "options": {
13 | "stackedGraph": true
14 | }
15 | }
16 | },
17 | {
18 | "id": "w2",
19 | "type": "DbDygraphsLine",
20 | "cspan": 8,
21 | "height": 300,
22 | "properties": {
23 | "options": {
24 | "stackedGraph": false,
25 | "title": "Random value Chart",
26 | "ylabel": "Probability",
27 | "labels" : ["Date","AAA","BBB"],
28 | "legend": "always"
29 | }
30 | }
31 | },
32 | {
33 | "id": "w6",
34 | "type": "DbDygraphsLine",
35 | "cspan": 8,
36 | "height": 300,
37 | "properties": {
38 | "options": {
39 | "showRangeSelector": true,
40 | "stackedGraph": false,
41 | "title": "Random value Chart",
42 | "ylabel": "Probability",
43 | "labels" : ["Date","AAA","BBB"],
44 | "legend": "always"
45 | }
46 | }
47 | },
48 | {
49 | "id": "w3",
50 | "type": "DbDygraphsSparkLine",
51 | "cspan": 4,
52 | "properties": {
53 | "smoothing": 0.5
54 | }
55 | },
56 | {
57 | "id": "w4",
58 | "type": "DbDygraphsSparkLine",
59 | "cspan": 4,
60 | "properties": {
61 | "options": {
62 | "colors": ["gray"],
63 | "strokeWidth": 0,
64 | "fillGraph": true,
65 | "fillAlpha": 0.2
66 | }
67 | }
68 | },
69 | {
70 | "id": "w5",
71 | "type": "DbDygraphsSparkLine",
72 | "cspan": 4,
73 | "properties": {
74 | "smoothing": 0.5
75 | }
76 | }
77 | ]
78 | }
79 |
--------------------------------------------------------------------------------
/src/demo/dashboards/dashthree.json:
--------------------------------------------------------------------------------
1 | {
2 | "layout": {
3 | "type": "grid"
4 | },
5 | "widgets": [
6 | {
7 | "id": "w1",
8 | "type": "DbHorizon",
9 | "cspan": 16
10 | }
11 | ]
12 | }
13 |
--------------------------------------------------------------------------------
/src/demo/data/testdata.js:
--------------------------------------------------------------------------------
1 | /* DashBlocks - Test data for demo dashboards */
2 |
3 | import dl from 'datalib';
4 | //import pathOr from 'ramda/es/pathOr';
5 |
6 | /* DashBlocks - Test data for demo dashboards */
7 | class TestData {
8 | constructor() {
9 | this.stockdata = null;
10 | }
11 |
12 | init() {
13 | // Load test data
14 | this.stockdata = dl.csv('https://vega.github.io/datalib/data/stocks.csv');
15 | }
16 |
17 | // TODO Methods
18 | }
19 |
20 | export default TestData;
21 |
--------------------------------------------------------------------------------
/src/demo/mixins/demodashboard.js:
--------------------------------------------------------------------------------
1 | export const demodashboard = {
2 | computed: {
3 | isDark() {
4 | return this.$store.state.dark;
5 | },
6 | dbSpecText() {
7 | return this.$store.state.dashboardSpec;
8 | }
9 | },
10 | watch: {
11 | dbSpecText: function(val) {
12 | this.dbspec = JSON.parse(val);
13 | }
14 | }
15 | };
16 |
--------------------------------------------------------------------------------
/src/demo/themes/README.md:
--------------------------------------------------------------------------------
1 | # Custom themes
2 |
3 | Examples of custom themes
4 |
--------------------------------------------------------------------------------
/src/demo/themes/_theme_custom.scss:
--------------------------------------------------------------------------------
1 | // We need colors and variables
2 | @import "../../assets/scss/dashblocks/material-colors";
3 | @import "../../assets/scss/dashblocks/variables";
4 |
5 | // We need base dashboard style
6 | @import '../../assets/scss/dashblocks/dbdashboard';
7 |
8 | // We override what is needed in out theme
9 | .db-dashboard.db-theme-custom {
10 | @include db-dashboard;
11 |
12 | color: red;
13 |
14 | background: #0f2027; /* fallback for old browsers */
15 | background: -webkit-linear-gradient(to bottom, #0f2027, #203a43, #2c5364); /* Chrome 10-25, Safari 5.1-6 */
16 | background: linear-gradient(
17 | to bottom,
18 | #0f2027,
19 | #203a43,
20 | #2c5364
21 | ); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
22 |
23 | }
24 |
25 | // Dark mode
26 | .db-dashboard.db-theme-custom.db-dark {
27 | color: yellow;
28 | & .db-widget-container {
29 | border: 1px solid material-color('red', '800');
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/demo/views/About.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
11 |
--------------------------------------------------------------------------------
/src/demo/views/ChartJsShowcase.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
152 |
--------------------------------------------------------------------------------
/src/demo/views/CodeViewer.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Dashboard Definition
8 |
9 |
10 |
11 |
12 |
15 |
16 |
17 |
84 |
85 |
--------------------------------------------------------------------------------
/src/demo/views/DashFive.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
INC
5 |
INC-2
6 |
INC-STROKE
7 |
8 |
9 |
10 |
155 |
--------------------------------------------------------------------------------
/src/demo/views/DashFour.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
143 |
--------------------------------------------------------------------------------
/src/demo/views/DashRidgeline.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
65 |
--------------------------------------------------------------------------------
/src/demo/views/DashSix.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
81 |
--------------------------------------------------------------------------------
/src/demo/views/DashThree.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
58 |
--------------------------------------------------------------------------------
/src/demo/views/DygraphsDynamic.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
139 |
--------------------------------------------------------------------------------
/src/demo/views/GeoMapboxUS.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
49 |
--------------------------------------------------------------------------------
/src/demo/views/Home.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
11 |
--------------------------------------------------------------------------------
/src/demo/views/Perspective.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
56 |
--------------------------------------------------------------------------------
/src/demo/views/Playground.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
72 |
--------------------------------------------------------------------------------
/src/demo/views/ProgressDashboard.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
136 |
--------------------------------------------------------------------------------
/src/demo/views/SalesFunnelDashboard.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
154 |
--------------------------------------------------------------------------------
/src/demo/views/SampleDashboard.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
127 |
--------------------------------------------------------------------------------
/src/demo/views/SankeyDashboard.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
149 |
--------------------------------------------------------------------------------
/src/demo/views/SparkHeatMap.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Enable Outline
8 |
9 |
10 |
11 |
12 |
13 |
14 |
157 |
--------------------------------------------------------------------------------
/src/demo/views/samples/DbDygraphsBarSamples.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
Default configuration
5 |
6 |
7 |
8 |
12 |
13 |
14 |
Dark mode. TODO Font color in DbDygraphs
15 |
16 |
17 |
18 |
19 |
20 |
58 |
65 |
--------------------------------------------------------------------------------
/src/demo/views/samples/DbHorizonSamples.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
Default configuration
5 |
6 |
7 |
8 |
9 |
Adjust seriesHeight: make each series higher (50px)
10 |
11 |
12 |
13 |
14 |
Adjust overlap: less color steps (2)
15 |
16 |
17 |
18 |
19 |
Adjust overlap: more color steps (9)
20 |
21 |
22 |
23 |
24 |
Different color scheme (schemeYlOrBr)
25 |
26 |
27 |
28 |
29 |
Dark mode. TODO Font color in DbHorizon
30 |
31 |
32 |
33 |
34 |
35 |
70 |
--------------------------------------------------------------------------------
/src/demo/views/samples/ProgressSamples.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
Linear Progress - Default configuration
5 |
6 |
7 |
8 |
Linear Progress - Dynamic
9 |
10 |
11 |
12 |
Progress - Default configuration
13 |
14 |
15 |
16 |
17 |
18 |
Multi-Progress - Default configuration
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
94 |
--------------------------------------------------------------------------------
/src/index.esm.js:
--------------------------------------------------------------------------------
1 | import DbData from './components/dbdata';
2 | import dbColors from './components/dbcolors';
3 | import dbUtils from './components/dbutils';
4 |
5 | export * from './components.js';
6 |
7 | function installPlugin(Vue, opts) {}
8 |
9 | // DashBlocks Vue plugin
10 | const DashBlocks = {
11 | install(Vue, opts) {
12 | // Register specified components
13 | if (opts.components) {
14 | Object.keys(opts.components).forEach(key => {
15 | if (!(key in ['DashBlocks', 'DbData', 'dbColors', 'dbUtils'])) {
16 | const c = opts.components[key];
17 | Vue.component(key, c);
18 | }
19 | });
20 | }
21 | /*
22 | Vue.component('db-dygraphs-bundle', function(resolve) {
23 | // This special require syntax will instruct Webpack to
24 | // automatically split your built code into bundles which
25 | // are loaded over Ajax requests.
26 | require(['./dygraphs/DbDygraphsBar'], resolve);
27 | });
28 | */
29 | }
30 | };
31 |
32 | export { DashBlocks, DbData, dbColors, dbUtils };
33 |
34 | /*
35 | import DbColors from './components/dbcolors';
36 | import DbUtils from './components/dbutils';
37 | import DbData from './components/dbdata';
38 | import DbDashboard from './components/dashboard/DbDashboard';
39 | import DbHorizon from './components/d3/DbHorizon';
40 | import DbSunburst from './components/d3/DbSunburst';
41 | import DbSankey from './components/d3/DbSankey';
42 | import DbRidgeline from './components/d3/DbRidgeline';
43 | import {
44 | DbChartjsBar,
45 | DbChartjsHorizontalBar,
46 | DbChartjsDoughnut,
47 | DbChartjsLine,
48 | DbChartjsPie,
49 | DbChartjsPolarArea,
50 | DbChartjsRadar,
51 | DbChartjsBubble,
52 | DbChartjsScatter
53 | } from './components/chartjs/DbChartjs';
54 | import DbNumber from './components/db/DbNumber';
55 | import DbEasyPie from './components/db/DbEasyPie';
56 | import DbTrendLine from './components/db/DbTrendLine';
57 | import DbTrendBar from './components/db/DbTrendBar';
58 | import DbSparkline from './components/db/DbSparkline';
59 | import DbDygraphsBar from './components/dygraphs/DbDygraphsBar';
60 | import DbDygraphsLine from './components/dygraphs/DbDygraphsLine';
61 | import DbDygraphsSparkLine from './components/dygraphs/DbDygraphsSparkLine';
62 | import DbDygraphsDateTimeHistogram from './components/dygraphs/DbDygraphsDateTimeHistogram';
63 |
64 | export {
65 | DbColors,
66 | DbUtils,
67 | DbData,
68 | DbDashboard,
69 | DbHorizon,
70 | DbSunburst,
71 | DbSankey,
72 | DbRidgeline,
73 | DbChartjsBar,
74 | DbChartjsHorizontalBar,
75 | DbChartjsDoughnut,
76 | DbChartjsLine,
77 | DbChartjsPie,
78 | DbChartjsPolarArea,
79 | DbChartjsRadar,
80 | DbChartjsBubble,
81 | DbChartjsScatter,
82 | DbNumber,
83 | DbEasyPie,
84 | DbTrendLine,
85 | DbTrendBar,
86 | DbSparkline,
87 | DbDygraphsBar,
88 | DbDygraphsLine,
89 | DbDygraphsSparkLine,
90 | DbDygraphsDateTimeHistogram
91 | };
92 | */
93 |
94 | /*
95 | export default {
96 | DbColors,
97 | DbUtils,
98 | DbHorizon,
99 | DbSunburst,
100 | DbSankey,
101 | DbRidgeline,
102 | DbChartjsBar,
103 | DbChartjsHorizontalBar,
104 | DbChartjsDoughnut,
105 | DbChartjsLine,
106 | DbChartjsPie,
107 | DbChartjsPolarArea,
108 | DbChartjsRadar,
109 | DbChartjsBubble,
110 | DbChartjsScatter,
111 | DbNumber,
112 | DbEasyPie,
113 | DbTrendLine,
114 | DbTrendBar,
115 | DbSparkline,
116 | DbDygraphsBar,
117 | DbDygraphsLine,
118 | DbDygraphsSparkLine,
119 | DbDygraphsDateTimeHistogram
120 | };
121 | */
122 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import App from './App.vue';
3 | import router from './router';
4 | import store from './store';
5 |
6 | // Import all
7 | import { DashBlocks, dbColors } from 'dashblocks';
8 | import * as dashblocksComponents from 'dashblocks';
9 |
10 | Vue.use(DashBlocks, {
11 | components: dashblocksComponents
12 | });
13 |
14 | // DashBlocks Showcase app css
15 | import './css.js';
16 | import './quasar';
17 |
18 | Vue.config.productionTip = false;
19 |
20 | // Set up Color Schemes for Dashblocks
21 | function setupColorSchemes() {
22 | dbColors.setColorScheme('barChartDiverging', {
23 | light: dbColors.d3ScaleChromatic.schemeSpectral[4],
24 | dark: dbColors.d3ScaleChromatic.schemeRdYlBu[6]
25 | });
26 | }
27 |
28 | setupColorSchemes();
29 |
30 | new Vue({
31 | router,
32 | store,
33 | render: h => h(App)
34 | }).$mount('#app');
35 |
--------------------------------------------------------------------------------
/src/quasar.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 |
3 | import './styles/quasar.scss';
4 | import '@quasar/extras/roboto-font/roboto-font.css';
5 | import '@quasar/extras/material-icons/material-icons.css';
6 | //import '@quasar/extras/material-icons-outlined/material-icons-outlined.css';
7 | //import '@quasar/extras/material-icons-round/material-icons-round.css';
8 | //import '@quasar/extras/material-icons-sharp/material-icons-sharp.css';
9 | //import '@quasar/extras/fontawesome-v5/fontawesome-v5.css';
10 | //import '@quasar/extras/ionicons-v4/ionicons-v4.css';
11 |
12 | import {
13 | Quasar,
14 | Ripple,
15 | LoadingBar,
16 | QLayout,
17 | QHeader,
18 | QDrawer,
19 | QPageContainer,
20 | QPage,
21 | QPageSticky,
22 | QToolbar,
23 | QToolbarTitle,
24 | QBtn,
25 | QIcon,
26 | QList,
27 | QItem,
28 | QItemSection,
29 | QItemLabel,
30 | QSplitter,
31 | QScrollArea,
32 | QExpansionItem,
33 | QAvatar,
34 | QBtnToggle,
35 | QSeparator,
36 | QTooltip,
37 | QTable,
38 | QCard,
39 | QCardSection,
40 | QSelect,
41 | QToggle,
42 | QBadge,
43 | QSpace
44 | } from 'quasar';
45 |
46 | Vue.use(Quasar, {
47 | config: {},
48 | components: {
49 | QLayout,
50 | QHeader,
51 | QDrawer,
52 | QPageContainer,
53 | QPage,
54 | QPageSticky,
55 | QToolbar,
56 | QToolbarTitle,
57 | QBtn,
58 | QIcon,
59 | QList,
60 | QItem,
61 | QItemSection,
62 | QItemLabel,
63 | QSplitter,
64 | QScrollArea,
65 | QExpansionItem,
66 | QAvatar,
67 | QBtnToggle,
68 | QSeparator,
69 | QTooltip,
70 | QTable,
71 | QCard,
72 | QCardSection,
73 | QSelect,
74 | QToggle,
75 | QBadge,
76 | QSpace
77 | },
78 | directives: {
79 | Ripple
80 | },
81 | plugins: {
82 | LoadingBar
83 | }
84 | });
85 |
--------------------------------------------------------------------------------
/src/store.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import Vuex from 'vuex';
3 |
4 | Vue.use(Vuex);
5 |
6 | export default new Vuex.Store({
7 | state: {
8 | dark: (localStorage['db-dark-mode'] || 'false') === 'true',
9 | refreshTrigger: 0,
10 | refreshTimeout: 5000,
11 | refreshLast: 0,
12 | intervalId: null,
13 | rotateTrigger: 0,
14 | rotateLast: 0,
15 | rotateTimeout: 15000,
16 | dashboardSpec: ''
17 | },
18 | mutations: {
19 | SET_DARK(state, { dark }) {
20 | localStorage['db-dark-mode'] = dark;
21 | state.dark = dark;
22 | },
23 | SET_INTERVAL_ID(state, { id }) {
24 | state.intervalId = id;
25 | },
26 | SET_REFRESH_TIMEOUT(state, { timeout }) {
27 | state.refreshTimeout = timeout;
28 | },
29 | PERFORM_REFRESH(state) {
30 | state.refreshLast = Date.now();
31 | state.refreshTrigger = state.refreshLast;
32 | },
33 | PERFORM_ROTATE(state) {
34 | state.rotateLast = Date.now();
35 | state.rotateTrigger = state.rotateLast;
36 | },
37 | SET_DB_SPEC(state, { spec }) {
38 | state.dashboardSpec = spec;
39 | }
40 | },
41 | actions: {
42 | setDark({ commit }, { dark }) {
43 | commit('SET_DARK', { dark: dark });
44 | },
45 | initRefresh({ commit, state }) {
46 | if (state.intervalId) {
47 | return; // Already set up
48 | }
49 | let intervalId = setInterval(() => {
50 | if (state.refreshTimeout === 0) {
51 | return;
52 | }
53 | let tsNow = Date.now();
54 | let elapsed = tsNow - state.refreshLast;
55 | // If we're almost at refresh interval, refresh
56 | if (elapsed >= state.refreshTimeout - 100) {
57 | console.log(`Need to refresh: ${tsNow} - ${elapsed}`);
58 | commit('PERFORM_REFRESH');
59 | }
60 | // If we're almost at rotate interval, rotate
61 | let rotateElapsed = tsNow - state.rotateLast;
62 | if (rotateElapsed >= state.rotateTimeout - 100) {
63 | console.log(`Need to rotate: ${tsNow} - ${rotateElapsed}`);
64 | commit('PERFORM_ROTATE');
65 | }
66 | }, 1000);
67 | commit('SET_INTERVAL_ID', { id: intervalId });
68 | },
69 | setRefreshTimeout({ commit }, { timeout }) {
70 | commit('SET_REFRESH_TIMEOUT', { timeout: timeout });
71 | },
72 | performRefresh({ commit }) {
73 | commit('PERFORM_REFRESH');
74 | },
75 | setDashboardSpec({ commit }, { spec }) {
76 | commit('SET_DB_SPEC', { spec: spec });
77 | }
78 | }
79 | });
80 |
--------------------------------------------------------------------------------
/src/styles/quasar.variables.scss:
--------------------------------------------------------------------------------
1 | // It's highly recommended to change the default colors
2 | // to match your app's branding.
3 |
4 | $primary : #027BE3;
5 | $secondary : #26A69A;
6 | $accent : #9C27B0;
7 |
8 | $dark : #1D1D1D;
9 |
10 | $positive : #21BA45;
11 | $negative : #C10015;
12 | $info : #31CCEC;
13 | $warning : #F2C037;
14 |
15 | @import '~quasar-variables-styl';
16 |
--------------------------------------------------------------------------------
/src/views/About.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | This is an about page
4 |
5 |
6 |
7 |
12 |
--------------------------------------------------------------------------------
/src/views/Home.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
14 |
--------------------------------------------------------------------------------
/src/webcomponents/dashboard.vue:
--------------------------------------------------------------------------------
1 |
37 |
38 |
41 |
--------------------------------------------------------------------------------
/src/webcomponents/dygraphs.vue:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/tests/e2e/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: ["cypress"],
3 | env: {
4 | mocha: true,
5 | "cypress/globals": true
6 | },
7 | rules: {
8 | strict: "off"
9 | }
10 | };
11 |
--------------------------------------------------------------------------------
/tests/e2e/plugins/index.js:
--------------------------------------------------------------------------------
1 | // https://docs.cypress.io/guides/guides/plugins-guide.html
2 |
3 | module.exports = (on, config) => {
4 | return Object.assign({}, config, {
5 | fixturesFolder: "tests/e2e/fixtures",
6 | integrationFolder: "tests/e2e/specs",
7 | screenshotsFolder: "tests/e2e/screenshots",
8 | videosFolder: "tests/e2e/videos",
9 | supportFile: "tests/e2e/support/index.js"
10 | });
11 | };
12 |
--------------------------------------------------------------------------------
/tests/e2e/specs/test.js:
--------------------------------------------------------------------------------
1 | // https://docs.cypress.io/api/introduction/api.html
2 |
3 | describe("My First Test", () => {
4 | it("Visits the app root url", () => {
5 | cy.visit("/");
6 | cy.contains("h1", "Welcome to Your Vue.js App");
7 | });
8 | });
9 |
--------------------------------------------------------------------------------
/tests/e2e/support/commands.js:
--------------------------------------------------------------------------------
1 | // ***********************************************
2 | // This example commands.js shows you how to
3 | // create various custom commands and overwrite
4 | // existing commands.
5 | //
6 | // For more comprehensive examples of custom
7 | // commands please read more here:
8 | // https://on.cypress.io/custom-commands
9 | // ***********************************************
10 | //
11 | //
12 | // -- This is a parent command --
13 | // Cypress.Commands.add("login", (email, password) => { ... })
14 | //
15 | //
16 | // -- This is a child command --
17 | // Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
18 | //
19 | //
20 | // -- This is a dual command --
21 | // Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
22 | //
23 | //
24 | // -- This is will overwrite an existing command --
25 | // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
26 |
--------------------------------------------------------------------------------
/tests/e2e/support/index.js:
--------------------------------------------------------------------------------
1 | // ***********************************************************
2 | // This example support/index.js is processed and
3 | // loaded automatically before your test files.
4 | //
5 | // This is a great place to put global configuration and
6 | // behavior that modifies Cypress.
7 | //
8 | // You can change the location of this file or turn off
9 | // automatically serving support files with the
10 | // 'supportFile' configuration option.
11 | //
12 | // You can read more here:
13 | // https://on.cypress.io/configuration
14 | // ***********************************************************
15 |
16 | // Import commands.js using ES2015 syntax:
17 | import "./commands";
18 |
19 | // Alternatively you can use CommonJS syntax:
20 | // require('./commands')
21 |
--------------------------------------------------------------------------------
/tests/unit/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | jest: true
4 | }
5 | };
6 |
--------------------------------------------------------------------------------
/tests/unit/example.spec.js:
--------------------------------------------------------------------------------
1 | import { shallowMount } from "@vue/test-utils";
2 | //import HelloWorld from "@/components/HelloDash.vue";
3 |
4 | describe("HelloWorld.vue", () => {
5 | it("renders props.msg when passed", () => {
6 | const msg = "new message";
7 | //const wrapper = shallowMount(HelloWorld, {
8 | // propsData: { msg }
9 | //});
10 | //expect(wrapper.text()).toMatch(msg);
11 | expect(true).toBeTruthy();
12 | });
13 | });
14 |
--------------------------------------------------------------------------------
/tests/wc/db.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | db demo
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
95 |
96 |
97 |
98 |
99 |
100 |
--------------------------------------------------------------------------------
/tests/wc/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | db demo
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | Dygraphs
14 |
15 |
16 |
17 |
72 |
73 |
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/vue.config.js:
--------------------------------------------------------------------------------
1 | // vue.config.js
2 | const path = require('path');
3 | const webpack = require('webpack');
4 | const PerspectivePlugin = require('@finos/perspective-webpack-plugin');
5 |
6 | // We will not include plotly.js-dist into lib bundle, to keep lib size reasonable.
7 | // plotly.js-dist is ~6M
8 | // App that uses dashblocks should have plotly.js-dist in it's dependencies
9 | // Also not including dygraphs as it must be loaded on demand
10 | // TODO Enable for Demo app build
11 | function getProdExternals() {
12 | return {
13 | 'plotly.js-dist': {
14 | commonjs: 'plotly.js-dist',
15 | commonjs2: 'plotly.js-dist'
16 | }
17 | /*
18 | dygraphs: {
19 | commonjs: 'dygraphs',
20 | commonjs2: 'dygraphs'
21 | }
22 | */
23 | };
24 | }
25 |
26 | module.exports = {
27 | publicPath: '/demo/',
28 |
29 | devServer: {
30 | proxy: 'http://localhost:3400'
31 | },
32 |
33 | configureWebpack: {
34 | //externals: process.env.NODE_ENV === 'production' ? getProdExternals() : {},
35 | plugins: [
36 | // Ignore all locale files of moment.js
37 | new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
38 | new PerspectivePlugin()
39 | ],
40 | resolve: {
41 | alias: {
42 | dashblocks: path.resolve(__dirname, 'src/index.esm.js')
43 | }
44 | },
45 | module: {
46 | rules: [
47 | {
48 | sideEffects: true
49 | }
50 | ]
51 | }
52 | },
53 |
54 | pluginOptions: {
55 | quasar: {
56 | importStrategy: 'manual',
57 | treeShake: true
58 | }
59 | }
60 |
61 | //transpileDependencies: ['quasar']
62 | };
63 |
--------------------------------------------------------------------------------