├── .editorconfig ├── .gitignore ├── .yarnrc ├── LICENSE ├── README.md ├── demo ├── chart │ ├── bar-1 │ │ ├── angular.ts │ │ ├── data.ts │ │ ├── json.ts │ │ ├── react.tsx │ │ └── vue.vue │ ├── cell-bar-1 │ │ ├── json.ts │ │ └── vueCell.vue │ ├── facet-1 │ │ ├── angular.ts │ │ ├── data.ts │ │ ├── json.ts │ │ ├── react.tsx │ │ └── vue.vue │ ├── index.ts │ ├── slider │ │ ├── data.ts │ │ ├── react.tsx │ │ └── vue.vue │ └── viser-graph-1 │ │ ├── angular.ts │ │ ├── json.ts │ │ ├── react.tsx │ │ └── vueGraph.vue ├── config │ ├── dev.env.js │ ├── index.js │ └── prod.env.js ├── index.css ├── index.html ├── index.tsx ├── package.json ├── run.js ├── tsconfig.json ├── types.d.ts ├── typings.d.ts ├── utils.js ├── vue-loader.config.js ├── webpack.config.js └── yarn.lock ├── lerna.json ├── package.json ├── packages ├── viser-cell-vue │ ├── .babelrc.js │ ├── .prettierrc │ ├── README.md │ ├── package.json │ ├── src │ │ ├── index.ts │ │ └── typed.ts │ ├── tsconfig.json │ └── webpack.config.js ├── viser-cell │ ├── .babelrc.js │ ├── .prettierrc │ ├── README.md │ ├── package.json │ ├── src │ │ ├── components │ │ │ ├── setAxisConfig.ts │ │ │ ├── setCoordConfig.ts │ │ │ ├── setCustomFormatter.ts │ │ │ ├── setGuideConfig.ts │ │ │ ├── setLegendConfig.ts │ │ │ ├── setQuickType.ts │ │ │ ├── setScaleConfig.ts │ │ │ ├── setSeriesConfig.ts │ │ │ └── setTooltipConfig.ts │ │ ├── core │ │ │ └── CommonChart.ts │ │ ├── index.ts │ │ ├── typed │ │ │ ├── IAxis.ts │ │ │ ├── IChart.ts │ │ │ ├── ICoord.ts │ │ │ ├── IGuide.ts │ │ │ ├── ILegend.ts │ │ │ ├── IMain.ts │ │ │ ├── IScale.ts │ │ │ ├── ISeries.ts │ │ │ ├── IStyle.ts │ │ │ └── ITooltip.ts │ │ └── utils │ │ │ ├── CustomizeUtils.ts │ │ │ ├── MathUtils.ts │ │ │ └── PolarUtils.ts │ ├── tsconfig.json │ ├── tslint.json │ └── webpack.config.js ├── viser-graph-ng │ ├── .babelrc.js │ ├── .prettierrc │ ├── package.json │ ├── src │ │ ├── components │ │ │ ├── Edge.ts │ │ │ ├── Graph.ts │ │ │ ├── GraphService.ts │ │ │ ├── Node.ts │ │ │ ├── Zoom.ts │ │ │ ├── index.ts │ │ │ └── utils.ts │ │ └── index.ts │ ├── tsconfig.json │ ├── tslint.json │ └── webpack.config.js ├── viser-graph-react │ ├── .babelrc.js │ ├── .prettierrc │ ├── package.json │ ├── src │ │ ├── components │ │ │ ├── Graph.tsx │ │ │ └── SubComponent.tsx │ │ ├── index.ts │ │ └── typed │ │ │ ├── IGraph.ts │ │ │ └── IZoom.ts │ ├── tsconfig.json │ ├── tslint.json │ └── webpack.config.js ├── viser-graph-vue │ ├── .babelrc.js │ ├── .prettierrc │ ├── package.json │ ├── src │ │ ├── index.ts │ │ ├── typed.ts │ │ └── utils.ts │ ├── tsconfig.json │ ├── tslint.json │ └── webpack.config.js ├── viser-graph │ ├── .babelrc.js │ ├── .prettierrc │ ├── package.json │ ├── src │ │ ├── graph.ts │ │ ├── index.ts │ │ ├── typed │ │ │ ├── IEdge.ts │ │ │ ├── IEvent.ts │ │ │ ├── IGraph.ts │ │ │ ├── ILayout.ts │ │ │ ├── INode.ts │ │ │ ├── ITooltip.ts │ │ │ ├── IZoom.ts │ │ │ ├── common.ts │ │ │ └── index.ts │ │ └── utils.ts │ ├── tsconfig.json │ ├── tslint.json │ └── webpack.config.js ├── viser-ng │ ├── .babelrc.js │ ├── README.md │ ├── package.json │ ├── src │ │ ├── Chart.ts │ │ ├── LiteChart.ts │ │ ├── chartService.ts │ │ ├── components │ │ │ ├── Axis.ts │ │ │ ├── Brush.ts │ │ │ ├── Coord.ts │ │ │ ├── Facet.ts │ │ │ ├── Guide.ts │ │ │ ├── Legend.ts │ │ │ ├── Series.ts │ │ │ ├── Style.ts │ │ │ ├── Tooltip.ts │ │ │ ├── View.ts │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── module.ts │ │ ├── plugins │ │ │ ├── Plugin.ts │ │ │ ├── PluginService.ts │ │ │ └── Slider.ts │ │ └── typed │ │ │ └── IRChart.ts │ ├── tsconfig.json │ ├── tslint.json │ └── webpack.config.js ├── viser-react │ ├── .babelrc.js │ ├── .prettierrc │ ├── README.md │ ├── package.json │ ├── src │ │ ├── components │ │ │ ├── Chart.tsx │ │ │ ├── Facet.tsx │ │ │ ├── FacetView.tsx │ │ │ ├── LiteChart.tsx │ │ │ ├── SubComponent.tsx │ │ │ └── View.tsx │ │ ├── index.tsx │ │ ├── plugins │ │ │ ├── SubPlugin.tsx │ │ │ └── plugin.tsx │ │ └── typed │ │ │ ├── IRChart.ts │ │ │ └── IRLiteChart.ts │ ├── tools │ │ └── babel-preset.js │ ├── tsconfig.json │ ├── tslint.json │ └── webpack.config.js ├── viser-vue │ ├── .babelrc.js │ ├── .prettierrc │ ├── README.md │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── index.ts │ │ └── typed.ts │ ├── tsconfig.json │ └── webpack.config.js └── viser │ ├── .babelrc.js │ ├── .prettierrc │ ├── README.md │ ├── package.json │ ├── src │ ├── components │ │ ├── setAxisConfig.ts │ │ ├── setCoordConfig.ts │ │ ├── setCustomFormatter.ts │ │ ├── setFilterConfig.ts │ │ ├── setGuideConfig.ts │ │ ├── setLegendConfig.ts │ │ ├── setQuickType.ts │ │ ├── setScaleConfig.ts │ │ ├── setSeriesConfig.ts │ │ └── setTooltipConfig.ts │ ├── core │ │ └── CommonChart.ts │ ├── index.ts │ ├── plugins │ │ ├── Slider.ts │ │ └── index.ts │ ├── shapes │ │ ├── ErrorBar.ts │ │ ├── Sankey.ts │ │ └── loadShapes.ts │ ├── typed │ │ ├── IAxis.ts │ │ ├── IBrush.ts │ │ ├── IChart.ts │ │ ├── ICoord.ts │ │ ├── IFacet.ts │ │ ├── IFilter.ts │ │ ├── IGuide.ts │ │ ├── ILegend.ts │ │ ├── IMain.ts │ │ ├── IScale.ts │ │ ├── ISeries.ts │ │ ├── IShapePoints.ts │ │ ├── ISlider.ts │ │ ├── IStyle.ts │ │ ├── ITooltip.ts │ │ └── IView.ts │ └── utils │ │ ├── CustomizeUtils.ts │ │ ├── EventUtils.ts │ │ ├── MathUtils.ts │ │ └── PolarUtils.ts │ ├── tsconfig.json │ ├── tslint.json │ └── webpack.config.js ├── scripts └── publish.sh └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain 2 | # consistent coding styles between different editors and IDEs. 3 | 4 | root = true 5 | 6 | [*] 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | indent_style = space 12 | indent_size = 2 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.log 3 | node_modules 4 | packages/**/build 5 | packages/**/umd 6 | packages/**/lib 7 | packages/**/es 8 | demo/**/*/umd 9 | coverage 10 | npm-debug.log 11 | *.orig 12 | -------------------------------------------------------------------------------- /.yarnrc: -------------------------------------------------------------------------------- 1 | workspaces-experimental true 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 viserjs 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 all 13 | 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 THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /demo/chart/bar-1/angular.ts: -------------------------------------------------------------------------------- 1 | 2 | import { Component, NgModule } from '@angular/core'; 3 | import { BrowserModule } from '@angular/platform-browser'; 4 | import { ViserModule } from '../../../packages/viser-ng/src/index'; 5 | import { data, scale } from './data'; 6 | const DataSet = require('@antv/data-set'); 7 | 8 | const ds: any = new DataSet(); 9 | const dv = ds.createView().source(data); 10 | dv.transform({ 11 | type: 'percent', 12 | field: 'value', 13 | dimension: 'country', 14 | groupBy: ['year'], 15 | as: 'percent' 16 | }); 17 | 18 | const filter = [{ 19 | dataKey: 'country', 20 | callback: (ev) => { 21 | return ev === 'Europe'; 22 | } 23 | }]; 24 | 25 | @Component({ 26 | selector: '#mount', 27 | template: ` 28 |
29 | 31 | 32 | 33 | 34 | 35 |
36 | ` 37 | }) 38 | class AppComponent { 39 | forceFit: boolean = true; 40 | height: number = 400; 41 | data = dv.rows; 42 | scale = scale; 43 | fields = ['cut', 'clarity']; 44 | filter = filter; 45 | onTooltipShow = () => { console.log('show'); }; 46 | onTooltipHide = () => { console.log('hide'); }; 47 | onTooltipChange = () => { console.log('change'); }; 48 | } 49 | 50 | @NgModule({ 51 | declarations: [ 52 | AppComponent 53 | ], 54 | imports: [ 55 | BrowserModule, 56 | ViserModule 57 | ], 58 | providers: [], 59 | bootstrap: [ 60 | AppComponent 61 | ] 62 | }) 63 | export default class AppModule { } 64 | -------------------------------------------------------------------------------- /demo/chart/bar-1/data.ts: -------------------------------------------------------------------------------- 1 | export const data = [ 2 | { country: 'Europe', year: '1750', value: 163 }, 3 | { country: 'Europe', year: '1800', value: 203 }, 4 | { country: 'Europe', year: '1850', value: 276 }, 5 | { country: 'Europe', year: '1900', value: 408 }, 6 | { country: 'Europe', year: '1950', value: 547 }, 7 | { country: 'Europe', year: '1999', value: 729 }, 8 | { country: 'Europe', year: '2050', value: 628 }, 9 | { country: 'Europe', year: '2100', value: 828 }, 10 | { country: 'Asia', year: '1750', value: 502 }, 11 | { country: 'Asia', year: '1800', value: 635 }, 12 | { country: 'Asia', year: '1850', value: 809 }, 13 | { country: 'Asia', year: '1900', value: 947 }, 14 | { country: 'Asia', year: '1950', value: 1402 }, 15 | { country: 'Asia', year: '1999', value: 3634 }, 16 | { country: 'Asia', year: '2050', value: 5268 }, 17 | { country: 'Asia', year: '2100', value: 7268 } 18 | ]; 19 | 20 | export const data1 = { 21 | 'country': ['Europe', 'Europe', 'Europe', 'Asia', 'Asia', 'Asia'], 22 | 'year': ['1750', '1800', '1850', '1750', '1800', '1850'], 23 | 'value': [163, 203, 276, 502, 635, 809], 24 | }; 25 | 26 | export const data2 = [ 27 | ['country', 'Europe', 'Europe', 'Europe', 'Asia', 'Asia', 'Asia'], 28 | ['year', '1750', '1800', '1850', '1750', '1800', '1850'], 29 | ['value', 163, 203, 276, 502, 635, 809], 30 | ]; 31 | 32 | export const data3 = [ 33 | ['Europe', 'Europe', 'Europe', 'Europe', 'Europe', 'Europe', 'Europe', 'Europe', 'Asia', 'Asia', 'Asia', 'Asia', 'Asia', 'Asia', 'Asia', 'Asia'], 34 | ['1750', '1800', '1850', '1900', '1950', '1999', '2050', '2100', '1750', '1800', '1850', '1900', '1950', '1999', '2050', '2100'], 35 | [163, 203, 276, 408, 547, 729, 628, 828, 502, 635, 809, 947, 1402, 3634, 5268, 7268], 36 | ]; 37 | 38 | export const scale = [{ 39 | dataKey: 'percent', 40 | min: 0, 41 | formatter: '.2%', 42 | }]; 43 | -------------------------------------------------------------------------------- /demo/chart/bar-1/json.ts: -------------------------------------------------------------------------------- 1 | import viser from '../../../packages/viser/src/index'; 2 | import { data, scale } from './data' 3 | const DataSet = require('@antv/data-set'); 4 | 5 | const ds = new DataSet(); 6 | const dv = ds.createView() 7 | .source(data) 8 | .transform({ 9 | type: 'percent', 10 | field: 'value', 11 | dimension: 'country', 12 | groupBy: ['year'], 13 | as: 'percent' 14 | }); 15 | 16 | viser({ 17 | data: dv.rows, 18 | scale: scale, 19 | axis: true, 20 | tooltip: true, 21 | legend: { 22 | dataKey: 'country', 23 | position: 'top-left', 24 | onItemMouseEnter: (ev) => { 25 | console.log(5, ev); 26 | } 27 | }, 28 | series: [{ 29 | quickType: 'stackBar', 30 | style: { 31 | stroke: '#fff', 32 | lineWidth: 1 33 | }, 34 | position: 'year*percent', 35 | color: 'country', 36 | onMouseEnter: (ev) => { 37 | console.log(3, ev); 38 | }, 39 | }], 40 | brush: { 41 | type: 'X', 42 | onBrushStart(ev, chart) { 43 | chart.hideTooltip(); 44 | }, 45 | onBrushMove(ev, chart) { 46 | chart.hideTooltip(); 47 | } 48 | }, 49 | chart: { 50 | container: 'mount', 51 | forceFit: true, 52 | height: 400, 53 | padding: [100, 80, 80, 80], 54 | renderer: 'svg', 55 | onPlotdblclick: (ev: any, chart: any) => { 56 | chart.get('options').filters = {}; 57 | chart.repaint(); 58 | } 59 | }, 60 | }); 61 | -------------------------------------------------------------------------------- /demo/chart/bar-1/vue.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 68 | -------------------------------------------------------------------------------- /demo/chart/cell-bar-1/json.ts: -------------------------------------------------------------------------------- 1 | import viser from '../../../packages/viser-cell/src/index'; 2 | 3 | const data = [ 4 | { name: 'London', 月份: 'Jan.', 月均降雨量: 18.9 }, 5 | { name: 'London', 月份: 'Feb.', 月均降雨量: 28.8 }, 6 | { name: 'London', 月份: 'Mar.', 月均降雨量: 39.3 }, 7 | { name: 'London', 月份: 'Apr.', 月均降雨量: 81.4 }, 8 | { name: 'London', 月份: 'May.', 月均降雨量: 47 }, 9 | { name: 'London', 月份: 'Jun.', 月均降雨量: 20.3 }, 10 | { name: 'London', 月份: 'Jul.', 月均降雨量: 24 }, 11 | { name: 'London', 月份: 'Aug.', 月均降雨量: 35.6 }, 12 | { name: 'Berlin', 月份: 'Jan.', 月均降雨量: 12.4 }, 13 | { name: 'Berlin', 月份: 'Feb.', 月均降雨量: 23.2 }, 14 | { name: 'Berlin', 月份: 'Mar.', 月均降雨量: 34.5 }, 15 | { name: 'Berlin', 月份: 'Apr.', 月均降雨量: 99.7 }, 16 | { name: 'Berlin', 月份: 'May.', 月均降雨量: 52.6 }, 17 | { name: 'Berlin', 月份: 'Jun.', 月均降雨量: 35.5 }, 18 | { name: 'Berlin', 月份: 'Jul.', 月均降雨量: 37.4 }, 19 | { name: 'Berlin', 月份: 'Aug.', 月均降雨量: 42.4 } 20 | ]; 21 | 22 | viser({ 23 | data: data, 24 | axis: true, 25 | tooltip: { 26 | custom: true, 27 | onChange(obj, chart) { 28 | const legend = chart.get('legendController').legends.top[0]; 29 | const tooltipItems = obj.items; 30 | const legendItems = legend.items; 31 | const map = {}; 32 | legendItems.map(item => { 33 | map[item.name] = item; 34 | }); 35 | tooltipItems.map(item => { 36 | const { name, value } = item; 37 | if (map[name]) { 38 | map[name].value = value; 39 | } 40 | }); 41 | legend.setItems(Object.values(map)); 42 | }, 43 | onHide(ev, chart) { 44 | const legend = chart.get('legendController').legends.top[0]; 45 | legend.setItems(chart.getLegendItems().country); 46 | } 47 | }, 48 | legend: true, 49 | series: [{ 50 | quickType: 'bar', 51 | position: '月份*月均降雨量', 52 | color: 'name', 53 | adjust: { 54 | type: 'dodge', 55 | marginRatio: 0.05, 56 | }, 57 | }], 58 | chart: { 59 | id: 'mountNode', 60 | height: 400, 61 | width: 200, 62 | pixelRatio: window.devicePixelRatio, 63 | }, 64 | }); 65 | -------------------------------------------------------------------------------- /demo/chart/cell-bar-1/vueCell.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 45 | -------------------------------------------------------------------------------- /demo/chart/facet-1/angular.ts: -------------------------------------------------------------------------------- 1 | import { Component, NgModule } from '@angular/core'; 2 | import { BrowserModule } from '@angular/platform-browser'; 3 | import { ViserModule } from '../../../packages/viser-ng/src/index'; 4 | import { sourcedata } from './data'; 5 | const DataSet = require('@antv/data-set'); 6 | const { DataView } = DataSet; 7 | 8 | const scale = [{ 9 | dataKey: 'mean', 10 | sync: true 11 | }, { 12 | dataKey: 'cut', 13 | sync: true, 14 | }]; 15 | 16 | const views = (view, facet) => { 17 | const data = facet.data; 18 | const dv = new DataView(); 19 | dv.source(data).transform({ 20 | type: 'aggregate', 21 | fields: ['price'], 22 | operations: ['mean'], 23 | as: ['mean'], 24 | groupBy: ['cut'] 25 | }); 26 | 27 | return { 28 | data: dv, 29 | series: { 30 | quickType: 'bar', 31 | position: 'cut*mean', 32 | color: 'cut', 33 | } 34 | } 35 | } 36 | 37 | @Component({ 38 | selector: '#mount', 39 | template: ` 40 |
41 | 42 | 43 | 44 | 45 | 46 | 47 |
48 | ` 49 | }) 50 | class AppComponent { 51 | forceFit: boolean = true; 52 | height: number = 600; 53 | chartData = sourcedata; 54 | scale = scale; 55 | opacity = 0.3; 56 | size = 3; 57 | fields = ['clarity']; 58 | views = views; 59 | } 60 | 61 | @NgModule({ 62 | declarations: [ 63 | AppComponent 64 | ], 65 | imports: [ 66 | BrowserModule, 67 | ViserModule 68 | ], 69 | providers: [], 70 | bootstrap: [AppComponent] 71 | }) 72 | 73 | export default class AppModule { } 74 | -------------------------------------------------------------------------------- /demo/chart/facet-1/json.ts: -------------------------------------------------------------------------------- 1 | import viser from '../../../packages/viser/src/index'; 2 | import { sourcedata } from './data'; 3 | const DataSet = require('@antv/data-set'); 4 | const { DataView } = DataSet; 5 | 6 | const scale = [{ 7 | dataKey: 'mean', 8 | sync: true 9 | }, { 10 | dataKey: 'cut', 11 | sync: true, 12 | }]; 13 | 14 | viser({ 15 | data: sourcedata, 16 | tooltip: true, 17 | legend: true, 18 | coord: { 19 | type: "polar" 20 | }, 21 | scale: scale, 22 | facet: { 23 | type: "circle", 24 | fields: ['clarity'], 25 | views: (view, facet) => { 26 | const data = facet.data; 27 | const dv = new DataView(); 28 | dv.source(data).transform({ 29 | type: 'aggregate', 30 | fields: [ 'price' ], 31 | operations: [ 'mean' ], 32 | as: [ 'mean' ], 33 | groupBy: [ 'cut' ] 34 | }); 35 | 36 | return { 37 | data: dv, 38 | series: { 39 | quickType: 'interval', 40 | position: 'cut*mean', 41 | color: 'cut', 42 | } 43 | } 44 | } 45 | }, 46 | chart: { 47 | container: 'mount', 48 | forceFit: true, 49 | height: 600, 50 | }, 51 | }); 52 | -------------------------------------------------------------------------------- /demo/chart/facet-1/react.tsx: -------------------------------------------------------------------------------- 1 | import { Chart, Facet, Coord, View, Tooltip, Legend, Axis, Point, FacetView } from '../../../packages/viser-react/src/index'; 2 | import * as React from 'react'; 3 | import { sourcedata } from './data' 4 | const DataSet = require('@antv/data-set'); 5 | const { DataView } = DataSet; 6 | 7 | const scale = [{ 8 | dataKey: 'mean', 9 | sync: true 10 | }, { 11 | dataKey: 'cut', 12 | sync: true, 13 | }]; 14 | 15 | const views = (view, facet) => { 16 | const data = facet.data; 17 | const dv = new DataView(); 18 | dv.source(data).transform({ 19 | type: 'aggregate', 20 | fields: [ 'price' ], 21 | operations: [ 'mean' ], 22 | as: [ 'mean' ], 23 | groupBy: [ 'cut' ] 24 | }); 25 | 26 | return { 27 | data: dv, 28 | series: { 29 | quickType: 'bar', 30 | position: 'cut*mean', 31 | color: 'cut', 32 | } 33 | } 34 | } 35 | 36 | export default class App extends React.Component { 37 | state = { 38 | data: [], 39 | }; 40 | 41 | componentDidMount() { 42 | setTimeout(() => { 43 | this.setState({ 44 | data: sourcedata 45 | }); 46 | }, 500); 47 | } 48 | render() { 49 | return ( 50 |
51 | 52 | 53 | 54 | 55 | 56 | 57 |
58 | ); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /demo/chart/facet-1/vue.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 60 | -------------------------------------------------------------------------------- /demo/chart/index.ts: -------------------------------------------------------------------------------- 1 | export default [ 2 | { 3 | type: 'bar-1', 4 | case: ['json', 'react', 'vue', 'angular'], 5 | }, 6 | { 7 | type: 'cell-bar-1', 8 | case: ['json', 'vueCell'], 9 | }, 10 | { 11 | type: 'facet-1', 12 | case: ['json', 'react', 'vue', 'angular'], 13 | }, 14 | { 15 | type: 'viser-graph-1', 16 | case: ['json', 'react', 'vueGraph', 'angular'], 17 | }, 18 | { 19 | type: 'slider', 20 | case: ['json', 'react', 'vue', 'angular'], 21 | } 22 | ]; 23 | -------------------------------------------------------------------------------- /demo/chart/viser-graph-1/angular.ts: -------------------------------------------------------------------------------- 1 | import 'zone.js'; 2 | import 'reflect-metadata'; 3 | import { Component, enableProdMode, NgModule } from '@angular/core'; 4 | import { BrowserModule } from '@angular/platform-browser'; 5 | import { ViserGraphModule, GlobalG6 as G6 } from '../../../packages/viser-graph-ng/src/index'; 6 | 7 | const data = { 8 | nodes: [{ 9 | id: '0', 10 | x: 150, 11 | y: 100 12 | }, { 13 | id: '1', 14 | x: 350, 15 | y: 300 16 | }], 17 | edges: [ 18 | // 内置折线 19 | { 20 | source: '0', 21 | target: '1' 22 | }] 23 | }; 24 | 25 | const graph = { 26 | data, 27 | type: 'graph', 28 | container: 'mount', 29 | width: 500, 30 | height: 500, 31 | pixelRatio: 2, 32 | renderer: 'svg', 33 | fitView: true, 34 | modes: { 35 | default: [ 'drag-node' ] 36 | }, 37 | defaultNode: { 38 | style: { 39 | fill: '#DEE9FF', 40 | stroke: '#5B8FF9' 41 | } 42 | }, 43 | defaultEdge: { 44 | shape: 'polyline', 45 | style: { 46 | stroke: '#F6BD16' 47 | } 48 | }, 49 | }; 50 | 51 | 52 | @Component({ 53 | selector: '#mount', 54 | template: ` 55 |
56 | 60 | 61 |
62 | ` 63 | }) 64 | 65 | class AppComponent { 66 | data = data; 67 | graph = graph; 68 | } 69 | 70 | @NgModule({ 71 | declarations: [ 72 | AppComponent 73 | ], 74 | imports: [ 75 | BrowserModule, 76 | ViserGraphModule 77 | ], 78 | providers: [], 79 | bootstrap: [ 80 | AppComponent 81 | ] 82 | }) 83 | export default class AppModule {} 84 | -------------------------------------------------------------------------------- /demo/chart/viser-graph-1/json.ts: -------------------------------------------------------------------------------- 1 | import { ViserGraph } from '../../../packages/viser-graph/src/index'; 2 | 3 | const data = { 4 | nodes: [{ 5 | id: '0', 6 | x: 150, 7 | y: 100 8 | }, { 9 | id: '1', 10 | x: 350, 11 | y: 300 12 | }], 13 | edges: [ 14 | // 内置折线 15 | { 16 | source: '0', 17 | target: '1' 18 | }] 19 | }; 20 | new ViserGraph({ 21 | data, 22 | graph: { 23 | container: 'mount', 24 | type: 'graph', 25 | width: 500, 26 | height: 500, 27 | pixelRatio: 2, 28 | renderer: 'svg', 29 | modes: { 30 | default: [ 'drag-node' ] 31 | } as any, 32 | fitView: true, 33 | defaultNode: { 34 | style: { 35 | fill: '#DEE9FF', 36 | stroke: '#5B8FF9' 37 | } 38 | } as any, 39 | } as any, 40 | edge: { 41 | formatter: () => { 42 | return { 43 | shape: 'polyline', 44 | style: { 45 | stroke: '#F6BD16' 46 | } 47 | } 48 | }, 49 | }, 50 | }).render(); -------------------------------------------------------------------------------- /demo/chart/viser-graph-1/react.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Graph } from '../../../packages/viser-graph-react/src/index'; 3 | 4 | const data = { 5 | nodes: [{ 6 | id: '0', 7 | x: 150, 8 | y: 100 9 | }, { 10 | id: '1', 11 | x: 350, 12 | y: 300 13 | }], 14 | edges: [ 15 | // 内置折线 16 | { 17 | source: '0', 18 | target: '1' 19 | }] 20 | }; 21 | 22 | const graph = { 23 | data, 24 | type: 'graph', 25 | container: 'mount', 26 | width: 500, 27 | height: 500, 28 | pixelRatio: 2, 29 | renderer: 'svg', 30 | fitView: true, 31 | modes: { 32 | default: [ 'drag-node' ] 33 | }, 34 | defaultNode: { 35 | style: { 36 | fill: '#DEE9FF', 37 | stroke: '#5B8FF9' 38 | } 39 | }, 40 | defaultEdge: { 41 | shape: 'polyline', 42 | style: { 43 | stroke: '#F6BD16' 44 | } 45 | }, 46 | }; 47 | 48 | export default class App extends React.Component { 49 | constructor(props) { 50 | super(props); 51 | 52 | } 53 | 54 | render() { 55 | return ( 56 |
57 | 58 |
59 | ); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /demo/chart/viser-graph-1/vueGraph.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 71 | -------------------------------------------------------------------------------- /demo/config/dev.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const merge = require('webpack-merge') 3 | const prodEnv = require('./prod.env') 4 | 5 | module.exports = merge(prodEnv, { 6 | NODE_ENV: '"development"' 7 | }) 8 | -------------------------------------------------------------------------------- /demo/config/index.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict' 3 | // Template version: 1.1.3 4 | // see http://vuejs-templates.github.io/webpack for documentation. 5 | 6 | const path = require('path') 7 | 8 | module.exports = { 9 | build: { 10 | env: require('./prod.env'), 11 | index: path.resolve(__dirname, '../dist/index.html'), 12 | assetsRoot: path.resolve(__dirname, '../dist'), 13 | assetsSubDirectory: 'static', 14 | assetsPublicPath: '/', 15 | productionSourceMap: true, 16 | // Gzip off by default as many popular static hosts such as 17 | // Surge or Netlify already gzip all static assets for you. 18 | // Before setting to `true`, make sure to: 19 | // npm install --save-dev compression-webpack-plugin 20 | productionGzip: false, 21 | productionGzipExtensions: ['js', 'css'], 22 | // Run the build command with an extra argument to 23 | // View the bundle analyzer report after build finishes: 24 | // `npm run build --report` 25 | // Set to `true` or `false` to always turn it on or off 26 | bundleAnalyzerReport: process.env.npm_config_report 27 | }, 28 | dev: { 29 | env: require('./dev.env'), 30 | port: process.env.PORT || 8080, 31 | autoOpenBrowser: true, 32 | assetsSubDirectory: 'static', 33 | assetsPublicPath: '/', 34 | proxyTable: {}, 35 | // CSS Sourcemaps off by default because relative paths are "buggy" 36 | // with this option, according to the CSS-Loader README 37 | // (https://github.com/webpack/css-loader#sourcemaps) 38 | // In our experience, they generally work as expected, 39 | // just be aware of this issue when enabling this option. 40 | cssSourceMap: false 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /demo/config/prod.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | module.exports = { 3 | NODE_ENV: '"production"' 4 | } 5 | -------------------------------------------------------------------------------- /demo/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | } 4 | 5 | #mountNode { 6 | margin-top: 30px; 7 | } 8 | -------------------------------------------------------------------------------- /demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | viser 4 | 5 | 6 | 7 |
8 |
9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "viser-demo", 3 | "version": "0.1.0", 4 | "description": "viser demo", 5 | "scripts": { 6 | "start": "cross-env UV_THREADPOOL_SIZE=100 && node --max_old_space_size=8192 run.js" 7 | }, 8 | "dependencies": { 9 | "@angular/compiler": "^8.0.0", 10 | "@angular/core": "^8.2.14", 11 | "@angular/platform-browser": "^8.0.0", 12 | "@angular/platform-browser-dynamic": "^8.0.0", 13 | "@antv/data-set": "^0.10.2", 14 | "@antv/g6": "^3.2.3", 15 | "d3": "^4.0.0", 16 | "dagre": "^0.8.4", 17 | "react": "^16.0.0", 18 | "react-dom": "^16.0.0", 19 | "reflect-metadata": "^0.1.13", 20 | "rxjs": "^6.0.0", 21 | "vue": "^2.5.0", 22 | "zone.js": "^0.10.2" 23 | }, 24 | "devDependencies": { 25 | "@types/react": "*", 26 | "@types/react-dom": "*", 27 | "@types/node": "*", 28 | "colors": "^1.4.0", 29 | "cross-env": "^6.0.3", 30 | "css-loader": "^3.2.0", 31 | "extract-text-webpack-plugin": "^3.0.2", 32 | "moment": "^2.24.0", 33 | "rimraf": "^3.0.0", 34 | "style-loader": "^1.0.0", 35 | "ts-loader": "^6.2.0", 36 | "tslint": "^5.20.0", 37 | "tsutils": "^3.17.1", 38 | "typescript": "<3.6.0", 39 | "vue-loader": "^15.7.1", 40 | "vue-template-compiler": "^2.6.10", 41 | "webpack": "^4.41.2", 42 | "webpack-cli": "^3.3.9", 43 | "webpack-dev-server": "^3.8.2", 44 | "webpack-merge": "^4.2.2" 45 | }, 46 | "engines": { 47 | "node": ">=8" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /demo/run.js: -------------------------------------------------------------------------------- 1 | var colors = require('colors'); 2 | var webpack = require("webpack"); 3 | var webpackDevServer = require("webpack-dev-server"); 4 | var config = require("./webpack.config.js"); 5 | var compiler = webpack(config); 6 | 7 | var server = new webpackDevServer(compiler, { 8 | publicPath: config.output.publicPath, 9 | noInfo: false, 10 | stats: { colors: true }, 11 | }); 12 | 13 | server.listen(3000); 14 | -------------------------------------------------------------------------------- /demo/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es5", 5 | "jsx": "react", 6 | "moduleResolution": "node", 7 | "noImplicitAny": false, 8 | "removeComments": true, 9 | "preserveConstEnums": true, 10 | "allowJs": true, 11 | "sourceMap": true, 12 | "experimentalDecorators": true, 13 | "emitDecoratorMetadata": true, 14 | "allowSyntheticDefaultImports": true, 15 | "alwaysStrict": true, 16 | "lib": [ 17 | "es2015", 18 | "es2017", 19 | "dom" 20 | ] 21 | }, 22 | "include": [ 23 | "./index.tsx" 24 | ], 25 | "exclude": ["node_modules", "build"] 26 | } 27 | -------------------------------------------------------------------------------- /demo/types.d.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viserjs/viser/625d52c2b2799cce9b1289857e61577e1f71b167/demo/types.d.ts -------------------------------------------------------------------------------- /demo/typings.d.ts: -------------------------------------------------------------------------------- 1 | /* SystemJS module definition */ 2 | declare var module: NodeModule; 3 | interface NodeModule { 4 | id: string; 5 | } 6 | -------------------------------------------------------------------------------- /demo/utils.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const config = require('./config') 4 | const ExtractTextPlugin = require('extract-text-webpack-plugin') 5 | 6 | exports.assetsPath = function (_path) { 7 | const assetsSubDirectory = process.env.NODE_ENV === 'production' 8 | ? config.build.assetsSubDirectory 9 | : config.dev.assetsSubDirectory 10 | return path.posix.join(assetsSubDirectory, _path) 11 | } 12 | 13 | exports.cssLoaders = function (options) { 14 | options = options || {} 15 | 16 | const cssLoader = { 17 | loader: 'css-loader', 18 | options: { 19 | minimize: process.env.NODE_ENV === 'production', 20 | sourceMap: options.sourceMap 21 | } 22 | } 23 | 24 | // generate loader string to be used with extract text plugin 25 | function generateLoaders(loader, loaderOptions) { 26 | const loaders = [cssLoader] 27 | if (loader) { 28 | loaders.push({ 29 | loader: loader + '-loader', 30 | options: Object.assign({}, loaderOptions, { 31 | sourceMap: options.sourceMap 32 | }) 33 | }) 34 | } 35 | 36 | // Extract CSS when that option is specified 37 | // (which is the case during production build) 38 | if (options.extract) { 39 | return ExtractTextPlugin.extract({ 40 | use: loaders, 41 | fallback: 'vue-style-loader' 42 | }) 43 | } else { 44 | return ['vue-style-loader'].concat(loaders) 45 | } 46 | } 47 | 48 | // https://vue-loader.vuejs.org/en/configurations/extract-css.html 49 | return { 50 | css: generateLoaders(), 51 | postcss: generateLoaders(), 52 | less: generateLoaders('less'), 53 | sass: generateLoaders('sass', { indentedSyntax: true }), 54 | scss: generateLoaders('sass'), 55 | stylus: generateLoaders('stylus'), 56 | styl: generateLoaders('stylus') 57 | } 58 | } 59 | 60 | // Generate loaders for standalone style files (outside of .vue) 61 | exports.styleLoaders = function (options) { 62 | const output = [] 63 | const loaders = exports.cssLoaders(options) 64 | for (const extension in loaders) { 65 | const loader = loaders[extension] 66 | output.push({ 67 | test: new RegExp('\\.' + extension + '$'), 68 | use: loader 69 | }) 70 | } 71 | return output 72 | } 73 | -------------------------------------------------------------------------------- /demo/vue-loader.config.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const utils = require('./utils') 3 | const config = require('./config') 4 | const isProduction = process.env.NODE_ENV === 'production' 5 | 6 | module.exports = { 7 | loaders: utils.cssLoaders({ 8 | sourceMap: isProduction 9 | ? config.build.productionSourceMap 10 | : config.dev.cssSourceMap, 11 | extract: isProduction 12 | }), 13 | transformToRequire: { 14 | video: 'src', 15 | source: 'src', 16 | img: 'src', 17 | image: 'xlink:href' 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /demo/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpack = require('webpack'); 3 | const vueLoaderConfig = require('./vue-loader.config') 4 | const VueLoaderPlugin = require('vue-loader/lib/plugin') 5 | 6 | module.exports = { 7 | mode: 'development', 8 | context: __dirname, 9 | devtool: '#inline-source-map', 10 | entry: ['./index.tsx'], 11 | output: { 12 | path: path.resolve(__dirname, 'build'), 13 | filename: 'bundle.js', 14 | publicPath: 'http://localhost:3000/build/' 15 | }, 16 | resolve: { 17 | extensions: ['.ts', '.tsx', '.js', '.json', '.vue'], 18 | alias: { 19 | viser: path.resolve(__dirname, '../packages/viser/src/index'), 20 | 'viser-react': path.resolve(__dirname, '../packages/viser-react/src/index'), 21 | 'viser-vue': path.resolve(__dirname, '../packages/viser-vue/src/index'), 22 | 'viser-ng': path.resolve(__dirname, '../packages/viser-ng/src/index'), 23 | 'viser-cell-vue': path.resolve(__dirname, '../packages/viser-cell-vue/src/index'), 24 | 'viser-cell': path.resolve(__dirname, '../packages/viser-cell/src/index'), 25 | 'viser-graph': path.resolve(__dirname, '../packages/viser-graph/src/index'), 26 | 'viser-graph-ng': path.resolve(__dirname, '../packages/viser-graph-ng/src/index'), 27 | 'vue$': 'vue/dist/vue.esm.js' 28 | }, 29 | modules: [ 30 | path.resolve(__dirname, '../packages/viser-ng/node_modules'), 'node_modules' 31 | ] 32 | }, 33 | module: { 34 | rules: [ 35 | { 36 | test: /\.vue$/, 37 | loader: 'vue-loader', 38 | options: vueLoaderConfig 39 | }, 40 | { test: /\.css$/, loader: 'style-loader!css-loader' }, 41 | { test: /\.tsx?$/, loader: 'ts-loader' } 42 | ] 43 | }, 44 | plugins: [ 45 | new webpack.NamedModulesPlugin(), 46 | new VueLoaderPlugin() 47 | ] 48 | }; 49 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "lerna": "2.11.0", 3 | "npmClient": "npm", 4 | "useWorkspaces": true, 5 | "version": "independent", 6 | "changelog": { 7 | "labels": { 8 | "tag: new feature": ":rocket: New Feature", 9 | "tag: breaking change": ":boom: Breaking Change", 10 | "tag: bug fix": ":bug: Bug Fix", 11 | "tag: enhancement": ":nail_care: Enhancement", 12 | "tag: documentation": ":memo: Documentation", 13 | "tag: internal": ":house: Internal" 14 | }, 15 | "cacheDir": ".changelog" 16 | }, 17 | "command": { 18 | "publish": { 19 | "message": "chore(release): publish %s" 20 | } 21 | }, 22 | "packages": [ 23 | "packages/*" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "workspaces": [ 4 | "packages/*" 5 | ], 6 | "description": "viser is a toolkit fit for data vis engineer.", 7 | "bugs": { 8 | "url": "https://github.com/viserjs/viser/issues" 9 | }, 10 | "homepage": "https://github.com/viserjs/viser#readme", 11 | "scripts": { 12 | "bootstrap": "lerna bootstrap", 13 | "publish": "./scripts/publish.sh" 14 | }, 15 | "devDependencies": { 16 | "lerna": "^3.4.0", 17 | "lerna-changelog": "^0.8.0", 18 | "lint-staged": "^7.3.0", 19 | "prettier": "1.6.1" 20 | }, 21 | "lint-staged": { 22 | "*.ts": [ 23 | "prettier --parser typescript --trailing-comma --single-quote --write", 24 | "git add" 25 | ], 26 | "yarn.lock": [ 27 | "git rm --cached" 28 | ] 29 | }, 30 | "engines": { 31 | "node": ">=8" 32 | }, 33 | "repository": { 34 | "type": "git", 35 | "url": "git@github.com:viserjs/viser.git" 36 | }, 37 | "author": "DT-FE", 38 | "license": "MIT" 39 | } 40 | -------------------------------------------------------------------------------- /packages/viser-cell-vue/.babelrc.js: -------------------------------------------------------------------------------- 1 | const BABEL_ENV = process.env.BABEL_ENV 2 | const building = BABEL_ENV != undefined && BABEL_ENV !== 'cjs' 3 | 4 | const plugins = [ 5 | "@babel/plugin-proposal-export-default-from", 6 | "@babel/plugin-proposal-export-namespace-from", 7 | ["@babel/plugin-proposal-class-properties", { "loose": true }], 8 | "@babel/plugin-proposal-object-rest-spread", 9 | ]; 10 | 11 | if (BABEL_ENV === 'umd') { 12 | plugins.push('@babel/plugin-external-helpers'); 13 | } 14 | 15 | module.exports = { 16 | plugins: plugins, 17 | presets: [ 18 | [ "@babel/preset-env", { 19 | modules: building ? false : 'commonjs', 20 | targets: { 21 | "browsers": ["last 2 versions"] 22 | } 23 | } ] 24 | ], 25 | }; 26 | -------------------------------------------------------------------------------- /packages/viser-cell-vue/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 80, 3 | "tabWidth": 2, 4 | "useTabs": false, 5 | "semi": true, 6 | "singleQuote": true, 7 | "trailingComma": "es5", 8 | "bracketSpacing": true 9 | } 10 | -------------------------------------------------------------------------------- /packages/viser-cell-vue/README.md: -------------------------------------------------------------------------------- 1 | # viser-cell-vue [![npm](https://img.shields.io/npm/v/viser-cell-vue.svg)](https://www.npmjs.com/package/viser-cell-vue) [![Dependency Status](https://david-dm.org/viserjs/viser-vue.svg?path=packages/viser-cell-vue)](https://david-dm.org/viserjs/viser-vue.svg?path=packages/viser-cell-vue) 2 | 3 | > A toolkit fit for data vis engineer (vue version). 4 | 5 | ## Install 6 | 7 | ```sh 8 | $ npm install --save viser-cell-vue 9 | ``` 10 | 11 | ## Usage 12 | 13 | ```vue 14 | 24 | 25 | 58 | ``` 59 | -------------------------------------------------------------------------------- /packages/viser-cell-vue/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "viser-cell-vue", 3 | "version": "2.0.3", 4 | "description": "viser-cell-vue is vue of viser-cell.", 5 | "repository": "viserjs/viser-cell-vue", 6 | "license": "MIT", 7 | "authors": "DT-FE", 8 | "files": [ 9 | "umd", 10 | "es", 11 | "lib" 12 | ], 13 | "main": "lib/index.js", 14 | "module": "es/index.js", 15 | "types": "es/index.d.ts", 16 | "scripts": { 17 | "prepare": "npm run build", 18 | "build": "npm run build:ts && npm run build:cjs && npm run build:umd", 19 | "build:ts": "rimraf es && tsc", 20 | "build:cjs": "rimraf lib && cross-env NODE_ENV=commonjs BABEL_ENV=cjs babel ./es -d lib", 21 | "build:umd": "rimraf umd && cross-env BABEL_ENV=umd webpack --config webpack.config.js", 22 | "clean": "git clean -fdX .", 23 | "lint": "tslint src", 24 | "analyse": "cross-env NODE_ENV=analyse webpack --progress --config webpack.config.js" 25 | }, 26 | "peerDependencies": { 27 | "vue": ">=1" 28 | }, 29 | "dependencies": { 30 | "@types/node": "*", 31 | "viser-cell": "^2.0.0", 32 | "vue": "^2.5.3" 33 | }, 34 | "devDependencies": { 35 | "@babel/cli": "^7.1.0", 36 | "@babel/core": "^7.0.0", 37 | "@babel/plugin-proposal-class-properties": "^7.0.0", 38 | "@babel/plugin-proposal-export-default-from": "^7.0.0", 39 | "@babel/plugin-proposal-export-namespace-from": "^7.0.0", 40 | "@babel/plugin-proposal-object-rest-spread": "^7.0.0", 41 | "@babel/plugin-external-helpers": "^7.0.0", 42 | "@babel/polyfill": "^7.0.0", 43 | "@babel/preset-env": "^7.0.0", 44 | "@babel/runtime": "^7.0.0", 45 | "babel-loader": "^8.0.0", 46 | "colors": "^1.1.2", 47 | "cross-env": "^5.2.0", 48 | "gzip-size": "^4.0.0", 49 | "ora": "^1.3.0", 50 | "pretty-bytes": "^4.0.2", 51 | "rimraf": "^2.6.2", 52 | "ts-loader": "^3.1.1", 53 | "tslint": "^5.5.0", 54 | "typescript": "~3.2.0", 55 | "webpack": "^4.20.0", 56 | "webpack-bundle-analyzer": "^3.6.0", 57 | "webpack-cli": "^3.1.0" 58 | }, 59 | "keywords": [ 60 | "f2", 61 | "chart", 62 | "vue", 63 | "datavis" 64 | ] 65 | } 66 | -------------------------------------------------------------------------------- /packages/viser-cell-vue/src/typed.ts: -------------------------------------------------------------------------------- 1 | const props: any = [ 2 | // axis 3 | 'dataKey', 'show', 'position', 'grid', 'label', 'line', 'tickLine', 'labelOffset', 4 | // chart 5 | 'id', 'el', 'height', 'width', 'padding', 'pixelRatio', 'animate', 'padding', 6 | // coord 7 | 'type', 'transposed', 'start', 'end', 'isRect', 'radius', 'innerRadius', 'startAngle', 'endAngle', 'isPolar', 'center', 'circleRadius', 8 | // guide 9 | 'type', 'position', 'vStyle', 'content', 'offsetX', 'offsetY', 'top', 'start', 'end', 'alignX', 'alignY', 'html', 'direct', 'side', 'background', 'textStyle', 'withPoint', 'pointStyle', 10 | // legend 11 | 'dataKey', 'show', 'showTitle', 'align', 'verticalAlign', 'position', 'titleGap', 'custom', 'offsetX', 'offsetY', 'itemGap', 'itemMarginBottom', 'itemWidth', 'unCheckColor', 12 | 'itemFormatter', 'marker', 'textStyle', 'onClick', 'nameStyle', 'valueStyle', 'wordSpace', 13 | // main 14 | 'data', 'scale', 15 | // series 16 | 'quickType', 'position', 'gemo', 'adjust', 'color', 'shape', 'size', 'vStyle', 'animate', 17 | // tooltip 18 | 'items', 'show', 'triggerOn', 'triggerOff', 'showTitle', 'showCrosshairs', 'crosshairsStyle', 'items', 'showTooltipMarker', 'background', 'titleStyle', 'nameStyle', 'valueStyle', 19 | 'showItemMarker', 'itemMarkerStyle', 'custom', 'onShow', 'onHide', 'onChange', 20 | // lite 21 | 'pie', 'sector', 'line', 'smoothLine', 'dashLine', 'area', 'stackArea', 'smoothArea', 'bar', 'stackBar', 'dodgeBar', 'interval', 'stackInterval', 'dodgeInterval', 22 | 'point', 'schema', 'box', 'candle', 'polygon', 23 | ]; 24 | 25 | function unique(array: any) { 26 | let res = []; 27 | for (let i = 0, len = array.length; i < len; i++) { 28 | const current = array[i]; 29 | if (res.indexOf(current) === -1) { 30 | res.push(current); 31 | } 32 | } 33 | 34 | return res; 35 | } 36 | 37 | function changeObj(array: any) { 38 | const uniqueProps = unique(array); 39 | const propsObject: any = {}; 40 | 41 | for (const res of uniqueProps) { 42 | propsObject[res] = null; 43 | } 44 | 45 | return propsObject; 46 | } 47 | 48 | export default changeObj(props); 49 | -------------------------------------------------------------------------------- /packages/viser-cell-vue/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "es2015", 4 | "moduleResolution": "node", 5 | "outDir": "es", 6 | "strict": true, 7 | "noImplicitAny": true, 8 | "noUnusedLocals": true, 9 | "removeComments": true, 10 | "preserveConstEnums": true, 11 | "experimentalDecorators": true, 12 | "sourceMap": true, 13 | "declaration": true, 14 | "lib": [ 15 | "es6", 16 | "scripthost", 17 | "dom" 18 | ] 19 | }, 20 | "include": [ 21 | "src/**/*" 22 | ], 23 | "exclude": [ 24 | "node_modules" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /packages/viser-cell-vue/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpack = require('webpack'); 3 | const env = process.env.NODE_ENV; 4 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; 5 | 6 | let config = { 7 | mode: 'production', 8 | 9 | entry: './lib/index', 10 | 11 | output: { 12 | path: path.resolve(__dirname, 'umd'), 13 | filename: 'viser-cell-vue.min.js', 14 | library: 'ViserCellVue', 15 | libraryTarget: 'umd', 16 | }, 17 | 18 | resolve: { 19 | extensions: ['.js', '.json'], 20 | }, 21 | 22 | externals: { 23 | 'vue': 'Vue', 24 | }, 25 | 26 | module: { 27 | rules: [{ 28 | test: /\.js?$/, 29 | exclude: /node_modules/, 30 | use: { 31 | loader: "babel-loader" 32 | } 33 | }], 34 | }, 35 | 36 | plugins: [], 37 | }; 38 | 39 | if (env === 'analyse') { 40 | config.plugins.push(new BundleAnalyzerPlugin()); 41 | } 42 | 43 | module.exports = config; 44 | -------------------------------------------------------------------------------- /packages/viser-cell/.babelrc.js: -------------------------------------------------------------------------------- 1 | const BABEL_ENV = process.env.BABEL_ENV 2 | const building = BABEL_ENV != undefined && BABEL_ENV !== 'cjs' 3 | 4 | const plugins = [ 5 | 'lodash', 6 | "@babel/plugin-proposal-export-default-from", 7 | "@babel/plugin-proposal-export-namespace-from", 8 | ["@babel/plugin-proposal-class-properties", { "loose": true }], 9 | "@babel/plugin-proposal-object-rest-spread", 10 | ]; 11 | 12 | if (BABEL_ENV === 'umd') { 13 | plugins.push('@babel/plugin-external-helpers'); 14 | } 15 | 16 | module.exports = { 17 | plugins: plugins, 18 | presets: [ 19 | [ "@babel/preset-env", { 20 | modules: building ? false : 'commonjs', 21 | targets: { 22 | "browsers": ["last 2 versions"] 23 | } 24 | } ] 25 | ], 26 | }; 27 | -------------------------------------------------------------------------------- /packages/viser-cell/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 80, 3 | "tabWidth": 2, 4 | "useTabs": false, 5 | "semi": true, 6 | "singleQuote": true, 7 | "trailingComma": "es5", 8 | "bracketSpacing": true 9 | } 10 | -------------------------------------------------------------------------------- /packages/viser-cell/README.md: -------------------------------------------------------------------------------- 1 | # viser-cell [![npm](https://img.shields.io/npm/v/viser-cell.svg)](https://www.npmjs.com/package/viser-cell) [![Dependency Status](https://david-dm.org/viserjs/viser-cell.svg?path=packages/viser)](https://david-dm.org/viserjs/viser-cell.svg?path=packages/viser) 2 | 3 | > A toolkit fit for data vis engineer. 4 | 5 | ## Install 6 | 7 | ```sh 8 | $ npm install --save viser-cell 9 | ``` 10 | 11 | ## Usage 12 | 13 | ```js 14 | import viser from 'viser-cell'; 15 | 16 | const data = [ 17 | { name: 'London', 月份: 'Jan.', 月均降雨量: 18.9 }, 18 | { name: 'London', 月份: 'Feb.', 月均降雨量: 28.8 }, 19 | { name: 'London', 月份: 'Mar.', 月均降雨量: 39.3 }, 20 | { name: 'London', 月份: 'Apr.', 月均降雨量: 81.4 }, 21 | { name: 'London', 月份: 'May.', 月均降雨量: 47 }, 22 | { name: 'London', 月份: 'Jun.', 月均降雨量: 20.3 }, 23 | { name: 'London', 月份: 'Jul.', 月均降雨量: 24 }, 24 | { name: 'London', 月份: 'Aug.', 月均降雨量: 35.6 }, 25 | { name: 'Berlin', 月份: 'Jan.', 月均降雨量: 12.4 }, 26 | { name: 'Berlin', 月份: 'Feb.', 月均降雨量: 23.2 }, 27 | { name: 'Berlin', 月份: 'Mar.', 月均降雨量: 34.5 }, 28 | { name: 'Berlin', 月份: 'Apr.', 月均降雨量: 99.7 }, 29 | { name: 'Berlin', 月份: 'May.', 月均降雨量: 52.6 }, 30 | { name: 'Berlin', 月份: 'Jun.', 月均降雨量: 35.5 }, 31 | { name: 'Berlin', 月份: 'Jul.', 月均降雨量: 37.4 }, 32 | { name: 'Berlin', 月份: 'Aug.', 月均降雨量: 42.4 } 33 | ]; 34 | 35 | viser({ 36 | data: data, 37 | axis: true, 38 | tooltip: true, 39 | legend: true, 40 | series: [{ 41 | quickType: 'bar', 42 | position: '月份*月均降雨量', 43 | color: 'name', 44 | adjust: { 45 | type: 'dodge', 46 | marginRatio: 0.05, 47 | }, 48 | }], 49 | chart: { 50 | id: 'mountNode', 51 | height: 400, 52 | width: 200, 53 | pixelRatio: window.devicePixelRatio, 54 | }, 55 | }); 56 | ``` 57 | -------------------------------------------------------------------------------- /packages/viser-cell/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "viser-cell", 3 | "version": "2.0.2", 4 | "description": "viser-cell is a toolkit fit for data vis engineer based on f2.", 5 | "repository": "viserjs/viser-cell", 6 | "license": "MIT", 7 | "authors": "DT-FE", 8 | "files": [ 9 | "lib", 10 | "es", 11 | "umd" 12 | ], 13 | "main": "lib/index.js", 14 | "module": "es/index.js", 15 | "types": "es/index.d.ts", 16 | "scripts": { 17 | "prepare": "npm run build", 18 | "build": "npm run build:ts && npm run build:cjs && npm run build:umd", 19 | "build:ts": "rimraf es && tsc", 20 | "build:cjs": "rimraf lib && cross-env NODE_ENV=commonjs BABEL_ENV=cjs babel ./es -d lib", 21 | "build:umd": "rimraf umd && cross-env BABEL_ENV=umd webpack --config webpack.config.js", 22 | "clean": "git clean -fdX .", 23 | "lint": "tslint src/**/*", 24 | "analyse": "cross-env NODE_ENV=analyse webpack --progress --config webpack.config.js" 25 | }, 26 | "dependencies": { 27 | "@antv/f2": "^3.2.0", 28 | "@types/d3-format": "*", 29 | "@types/lodash": "*", 30 | "@types/node": "^8.0.53", 31 | "d3-format": "^1.3.0", 32 | "lodash": "^4.17.4" 33 | }, 34 | "devDependencies": { 35 | "@babel/cli": "^7.1.0", 36 | "@babel/core": "^7.0.0", 37 | "@babel/plugin-proposal-class-properties": "^7.0.0", 38 | "@babel/plugin-proposal-export-default-from": "^7.0.0", 39 | "@babel/plugin-proposal-export-namespace-from": "^7.0.0", 40 | "@babel/plugin-proposal-object-rest-spread": "^7.0.0", 41 | "@babel/plugin-external-helpers": "^7.0.0", 42 | "@babel/polyfill": "^7.0.0", 43 | "@babel/preset-env": "^7.0.0", 44 | "@babel/runtime": "^7.0.0", 45 | "babel-loader": "^8.0.0", 46 | "babel-plugin-lodash": "^3.3.0", 47 | "colors": "^1.1.2", 48 | "cross-env": "^5.2.0", 49 | "gzip-size": "^4.0.0", 50 | "ora": "^1.3.0", 51 | "pretty-bytes": "^4.0.2", 52 | "rimraf": "^2.6.2", 53 | "tslint": "^5.5.0", 54 | "typescript": "~3.2.0", 55 | "webpack": "^4.20.0", 56 | "webpack-bundle-analyzer": "^3.6.0", 57 | "webpack-cli": "^3.1.0" 58 | }, 59 | "keywords": [ 60 | "f2", 61 | "chart", 62 | "datavis" 63 | ] 64 | } 65 | -------------------------------------------------------------------------------- /packages/viser-cell/src/components/setAxisConfig.ts: -------------------------------------------------------------------------------- 1 | import * as _ from 'lodash'; 2 | import * as setCustomFormatter from './setCustomFormatter'; 3 | 4 | export const process = (chart: any, config: any) => { 5 | const cAxis = _.cloneDeep(config.axis); 6 | const isArr = _.isArray(cAxis); 7 | 8 | if (_.isNil(cAxis) || cAxis === false || 9 | (isArr && cAxis.length === 0)) { 10 | return chart.axis(false); 11 | } 12 | 13 | if (cAxis === true) { return chart.axis(true); } 14 | 15 | const arrAxis = isArr ? cAxis : [cAxis]; 16 | 17 | for (const res of arrAxis) { 18 | if (res.label) { 19 | res.label = setCustomFormatter.supportD3Formatter(res.label); 20 | } 21 | 22 | if (res.dataKey) { 23 | if (res.show === false) { 24 | chart.axis(res.dataKey, false); 25 | } else { 26 | const options = _.omit(res, ['show', 'dataKey']); 27 | chart.axis(res.dataKey, options); 28 | } 29 | } else { 30 | chart.axis(res); 31 | } 32 | } 33 | 34 | return chart; 35 | }; 36 | -------------------------------------------------------------------------------- /packages/viser-cell/src/components/setCoordConfig.ts: -------------------------------------------------------------------------------- 1 | import * as _ from 'lodash'; 2 | import { degreeToRadian } from '../utils/PolarUtils'; 3 | 4 | function setPolarCoord(chart: any, coord: any) { 5 | let newCoord = {}; 6 | 7 | if (coord.radius && (coord.radius < 0 || coord.radius > 1) || 8 | coord.innerRadius && (coord.innerRadius < 0 || coord.innerRadius > 1)) { 9 | throw new Error('please set correct radius or innerRadius'); 10 | } 11 | 12 | if (coord.radius) { 13 | newCoord = { ...newCoord, radius: coord.radius }; 14 | } 15 | 16 | if (coord.innerRadius) { 17 | newCoord = { ...newCoord, innerRadius: coord.innerRadius }; 18 | } 19 | 20 | if (coord.startAngle || coord.endAngle) { 21 | if (coord.startAngle && (coord.startAngle < -360 || coord.startAngle > 360)) { 22 | throw new Error('please set correct starAngle'); 23 | } else { 24 | newCoord = { 25 | ...newCoord, 26 | startAngle: degreeToRadian(coord.startAngle), 27 | }; 28 | } 29 | 30 | if (coord.endAngle && (coord.endAngle < -360 || coord.endAngle > 360)) { 31 | throw new Error('please set correct endAngle'); 32 | } else { 33 | newCoord = { 34 | ...newCoord, 35 | endAngle: degreeToRadian(coord.endAngle), 36 | }; 37 | } 38 | } 39 | 40 | return chart.coord(coord.type, { ...newCoord }); 41 | } 42 | 43 | function setRectCoord(chart: any, coord: any) { 44 | if (!coord.direction) { 45 | return chart.coord('rect'); 46 | } 47 | 48 | return chart; 49 | } 50 | 51 | export const process = (chart: any, config: any) => { 52 | const cCoord = _.cloneDeep(config.coord); 53 | 54 | if (!cCoord || !cCoord.type) { 55 | return chart.coord('rect'); 56 | } 57 | 58 | const type = cCoord.type; 59 | 60 | if (type === 'polar') { 61 | return setPolarCoord(chart, cCoord); 62 | } 63 | 64 | if (type === 'rect') { 65 | return setRectCoord(chart, cCoord); 66 | } 67 | 68 | return chart.coord(type); 69 | }; 70 | -------------------------------------------------------------------------------- /packages/viser-cell/src/components/setCustomFormatter.ts: -------------------------------------------------------------------------------- 1 | import * as d3 from 'd3-format'; 2 | import * as _ from 'lodash'; 3 | 4 | export const supportD3Formatter = (obj: any) => { 5 | for (const item in obj) { 6 | if (obj.hasOwnProperty(item)) { 7 | const formatter = _.get(obj[item], 'formatter'); 8 | 9 | if (_.isString(formatter)) { 10 | obj[item].formatter = (val: number) => { 11 | return d3.format(formatter)(val); 12 | }; 13 | } 14 | } 15 | } 16 | 17 | return obj; 18 | }; 19 | -------------------------------------------------------------------------------- /packages/viser-cell/src/components/setGuideConfig.ts: -------------------------------------------------------------------------------- 1 | import * as _ from 'lodash'; 2 | 3 | // add two type of guide line 4 | // parallel and normal 5 | function setGuideLine(chart: any, item: any) { 6 | if (item.quickType === 'parallel') { 7 | const data = item.data; 8 | chart.guide().line({ 9 | start: ['min', data], 10 | end: ['max', data], 11 | ...item, 12 | }); 13 | } else if (item.quickType === 'normal') { 14 | const data = item.data; 15 | chart.guide().line({ 16 | start: [data, 'min'], 17 | end: [data, 'max'], 18 | ...item, 19 | }); 20 | } else { 21 | chart.guide().line(item); 22 | } 23 | } 24 | 25 | // add two type of guide line 26 | // parallel and normal 27 | function setGuideArc(chart: any, item: any) { 28 | if (item.quickType === 'parallel') { 29 | const data = item.data; 30 | chart.guide().arc({ 31 | start: ['min', data], 32 | end: ['max', data], 33 | ...item, 34 | }); 35 | chart.guide().arc({ 36 | start: ['max', data], 37 | end: ['min', data], 38 | ...item, 39 | }); 40 | } else if (item.quickType === 'normal') { 41 | const data = item.data; 42 | chart.guide().line({ 43 | start: [data, 'min'], 44 | end: [data, 'max'], 45 | ...item, 46 | }); 47 | } else { 48 | chart.guide().arc(item); 49 | } 50 | } 51 | 52 | export const process = (chart: any, config: any) => { 53 | const cGuide = _.cloneDeep(config.guide); 54 | const isArr = Array.isArray(cGuide); 55 | 56 | if (_.isNil(cGuide) || _.isEmpty(cGuide)) { return; } 57 | 58 | const arrGuide = isArr ? cGuide : [cGuide]; 59 | 60 | arrGuide.forEach((res: any) => { 61 | if (res.type === 'line') { 62 | setGuideLine(chart, res); 63 | } else if (res.type === 'rect') { 64 | chart.guide().rect(res); 65 | } else if (res.type === 'arc') { 66 | setGuideArc(chart, res); 67 | } else if (res.type === 'text') { 68 | chart.guide().text(res); 69 | } else if (res.type === 'tag') { 70 | chart.guide().tag(res); 71 | } else if (res.type === 'html') { 72 | chart.guide().html(res); 73 | } 74 | }); 75 | 76 | return chart; 77 | }; 78 | -------------------------------------------------------------------------------- /packages/viser-cell/src/components/setLegendConfig.ts: -------------------------------------------------------------------------------- 1 | import * as _ from 'lodash'; 2 | 3 | export const process = (chart: any, config: any) => { 4 | const cLegend = _.cloneDeep(config.legend); 5 | const isArr = Array.isArray(cLegend); 6 | 7 | if (_.isNil(cLegend) || cLegend === false || 8 | (isArr && cLegend.length === 0)) { 9 | return chart.legend(false); 10 | } 11 | 12 | if (cLegend === true) { return chart.legend(true); } 13 | 14 | const arrLegend = isArr ? cLegend : [cLegend]; 15 | 16 | for (const res of arrLegend) { 17 | for (const item in res) { 18 | // Due to lack of legend:click event support in F2.chart, 19 | // unlike other component, 20 | // we have to use onClick on Legend. 21 | if (item === 'onClick') { 22 | const content = res.onClick; 23 | res.onClick = (ev?: any) => { 24 | content(ev, chart); 25 | }; 26 | } 27 | } 28 | 29 | if (res.dataKey) { 30 | if (res.show === false) { 31 | chart.legend(res.dataKey, false); 32 | } else { 33 | const option = _.omit(res, ['dataKey', 'show']); 34 | chart.legend(res.dataKey, option); 35 | } 36 | } else { 37 | chart.legend(res); 38 | } 39 | } 40 | return chart; 41 | }; 42 | -------------------------------------------------------------------------------- /packages/viser-cell/src/components/setScaleConfig.ts: -------------------------------------------------------------------------------- 1 | import * as _ from 'lodash'; 2 | import * as setCustomFormatter from './setCustomFormatter'; 3 | 4 | export const process = (chart: any, config: any) => { 5 | const cScale = _.cloneDeep(config.scale); 6 | const isArr = _.isArray(cScale); 7 | 8 | if (_.isEmpty(cScale)) { return; } 9 | 10 | const arrScale = isArr ? cScale : [cScale]; 11 | let options: any = {}; 12 | 13 | for (const res of arrScale) { 14 | if (res.dataKey) { 15 | const currOption = _.omit(res, 'dataKey'); 16 | options[res.dataKey] = currOption; 17 | } 18 | } 19 | 20 | options = setCustomFormatter.supportD3Formatter(options); 21 | return chart.scale(options); 22 | }; 23 | -------------------------------------------------------------------------------- /packages/viser-cell/src/components/setTooltipConfig.ts: -------------------------------------------------------------------------------- 1 | import * as _ from 'lodash'; 2 | 3 | export const process = (chart: any, config: any) => { 4 | const cTooltip = _.cloneDeep(config.tooltip); 5 | 6 | if (_.isNil(cTooltip) || cTooltip === false || cTooltip.show === false) { 7 | return chart.tooltip(false); 8 | } 9 | 10 | for (const item in cTooltip) { 11 | if (item === 'onShow' || item === 'onHide' || item === 'onChange') { 12 | const content = cTooltip[item]; 13 | cTooltip[item] = (ev: any) => { 14 | content(ev, chart); 15 | }; 16 | } 17 | } 18 | 19 | return chart.tooltip(cTooltip); 20 | }; 21 | -------------------------------------------------------------------------------- /packages/viser-cell/src/index.ts: -------------------------------------------------------------------------------- 1 | import * as _ from 'lodash'; 2 | import CommonChart from './core/CommonChart'; 3 | import IAxisConfig, { IAxis } from './typed/IAxis'; 4 | import IChart from './typed/IChart'; 5 | import ICoord, { IPolarCoord, IRectCoord } from './typed/ICoord'; 6 | import IGuideConfig, { IArcGuide, IGuide, ILineGuide, IRectGuide, ITagGuide, ITextGuide } from './typed/IGuide'; 7 | import ILegendConfig, { ILegend } from './typed/ILegend'; 8 | import IMain from './typed/IMain'; 9 | import IScale from './typed/IScale'; 10 | import ISeriesConfig, { ISeries } from './typed/ISeries'; 11 | import ITooltipConfig, { ITooltip } from './typed/ITooltip'; 12 | import * as CustomizeUtils from './utils/CustomizeUtils'; 13 | declare const require: any; 14 | // tslint:disable-next-line:no-var-requires 15 | const F2 = require('@antv/f2'); 16 | 17 | export { 18 | IAxis, 19 | IAxisConfig, 20 | IChart, 21 | ICoord, 22 | IRectCoord, 23 | IPolarCoord, 24 | IGuide, 25 | IGuideConfig, 26 | ILineGuide, 27 | ITextGuide, 28 | ITagGuide, 29 | IRectGuide, 30 | IArcGuide, 31 | ILegend, 32 | ILegendConfig, 33 | ISeries, 34 | ISeriesConfig, 35 | ITooltip, 36 | ITooltipConfig, 37 | IScale, 38 | IMain, 39 | }; 40 | 41 | export const registerAnimation = CustomizeUtils.registerAnimation; 42 | export const registerShape = CustomizeUtils.registerShape; 43 | export const registerGesture = CustomizeUtils.registerGesture; 44 | export const Global = F2.Global; 45 | 46 | function hasDataCondition(config: any) { 47 | let hasData = false; 48 | 49 | if (!_.isEmpty(config.data)) { 50 | hasData = true; 51 | } 52 | 53 | if (!_.isNil(config.views)) { 54 | if (_.isPlainObject(config.views) && !_.isEmpty(config.views.data)) { 55 | hasData = true; 56 | } 57 | 58 | if (_.isArray(config.views)) { 59 | for (const item of config.views) { 60 | if (!_.isEmpty(item.data)) { 61 | hasData = true; 62 | } 63 | } 64 | } 65 | } 66 | 67 | return hasData; 68 | } 69 | 70 | export default function(config: any) { 71 | if (_.isNil(config) || _.isEmpty(config)) { return; } 72 | 73 | const hasData = hasDataCondition(config); 74 | if (!hasData) { return; } 75 | const commonChart = new CommonChart(config); 76 | commonChart.render(); 77 | 78 | return commonChart; 79 | } 80 | -------------------------------------------------------------------------------- /packages/viser-cell/src/typed/IAxis.ts: -------------------------------------------------------------------------------- 1 | import * as IStyle from './IStyle'; 2 | 3 | export interface IAxis { 4 | dataKey?: string; 5 | show?: boolean; 6 | line?: IStyle.ILineStyle; 7 | position?: string; 8 | labelOffset?: number; 9 | tickLine?: IStyle.ILineStyle; 10 | grid?: (text: string, index: number) => any; 11 | label?: (text: string, index: number, total: number) => any; 12 | } 13 | 14 | type IAxisConfig = boolean | IAxis | IAxis[]; 15 | 16 | export default IAxisConfig; 17 | -------------------------------------------------------------------------------- /packages/viser-cell/src/typed/IChart.ts: -------------------------------------------------------------------------------- 1 | export interface IChart { 2 | id?: any; 3 | el?: any; 4 | height?: number; 5 | width?: number; 6 | context?: any; 7 | animate?: boolean | object; 8 | pixelRatio?: number; 9 | plugins?: any; 10 | padding?: number | object | number[]; 11 | } 12 | 13 | export default IChart; 14 | -------------------------------------------------------------------------------- /packages/viser-cell/src/typed/ICoord.ts: -------------------------------------------------------------------------------- 1 | export interface IRectCoord { 2 | type?: 'rect'; 3 | transposed?: boolean; 4 | start?: object; 5 | end?: object; 6 | isRect?: boolean; 7 | } 8 | 9 | export interface IPolarCoord { 10 | type?: 'polar'; 11 | radius?: number; 12 | innerRadius?: number; 13 | startAngle?: number; 14 | endAngle?: number; 15 | isPolar?: boolean; 16 | transposed?: boolean; 17 | center?: object; 18 | circleRadius?: number; 19 | } 20 | 21 | type ICoord = IRectCoord | IPolarCoord; 22 | 23 | export default ICoord; 24 | -------------------------------------------------------------------------------- /packages/viser-cell/src/typed/IGuide.ts: -------------------------------------------------------------------------------- 1 | 2 | import * as IStyle from './IStyle'; 3 | 4 | type func = () => void; 5 | 6 | export interface ILineGuide { 7 | type?: 'line'; 8 | top?: boolean; 9 | start?: object | Array | func; 10 | end?: object | Array | func; 11 | style?: IStyle.ILineStyle; 12 | } 13 | 14 | export interface ITextGuide { 15 | type?: 'text'; 16 | top?: boolean; 17 | position?: object | Array | func; 18 | content?: string; 19 | style?: IStyle.ITextStyle; 20 | offsetX?: number; 21 | offsetY?: number; 22 | } 23 | 24 | export interface ITagGuide { 25 | type?: 'tag'; 26 | top?: boolean; 27 | position?: object | Array | func; 28 | content?: string; 29 | direct?: string; 30 | side?: number; 31 | offsetX?: number; 32 | offsetY?: number; 33 | background?: object; 34 | textStyle?: IStyle.ITextStyle; 35 | withPoint?: boolean; 36 | pointStyle?: IStyle.IPointStyle; 37 | } 38 | 39 | interface IRegionStyle { 40 | lineWidth?: number; 41 | fill?: string; 42 | fillOpacity?: number; 43 | stroke?: string; 44 | } 45 | 46 | export interface IRectGuide { 47 | type?: 'rect'; 48 | start?: object | Array | func; 49 | end?: object | Array | func; 50 | style?: IRegionStyle; 51 | } 52 | 53 | export interface IHtmlGuide { 54 | type?: 'html'; 55 | position?: object | Array | func; 56 | alignX?: string; 57 | alignY?: string; 58 | offsetX?: number; 59 | offsetY?: number; 60 | html?: string; 61 | } 62 | 63 | export interface IArcGuide { 64 | type?: 'arc'; 65 | top?: boolean; 66 | start?: object | Array | func; 67 | end?: object | Array | func; 68 | style?: object; 69 | } 70 | 71 | export type IGuide = ILineGuide | ITextGuide | ITagGuide | IRectGuide | IArcGuide | IHtmlGuide; 72 | type IGuideConfig = IGuide | IGuide[]; 73 | 74 | export default IGuideConfig; 75 | -------------------------------------------------------------------------------- /packages/viser-cell/src/typed/ILegend.ts: -------------------------------------------------------------------------------- 1 | import * as IStyle from './IStyle'; 2 | 3 | type func = () => void; 4 | type formatterFunc = (val: number) => string | number; 5 | type eventFunc = (ev: any, chart: any) => void; 6 | 7 | export interface ILegend { 8 | dataKey?: string; 9 | show?: boolean; 10 | position?: string; 11 | align?: string; 12 | verticalAlign?: string; 13 | itemWidth?: number | 'auto'; 14 | showTitle?: boolean; 15 | titleStyle?: IStyle.ITextStyle; 16 | offsetX?: number; 17 | offsetY?: number; 18 | titleGap?: number; 19 | itemGap?: number; 20 | itemMarginBottom?: number; 21 | wordSpace?: number; 22 | unCheckColor?: string; 23 | itemFormatter?: formatterFunc; 24 | marker?: string | object | func; 25 | nameStyle?: IStyle.ITextStyle; 26 | valueStyle?: IStyle.ITextStyle; 27 | custom?: boolean; 28 | onClick?: eventFunc; 29 | } 30 | 31 | type ILegendConfig = boolean | ILegend; 32 | 33 | export default ILegendConfig; 34 | -------------------------------------------------------------------------------- /packages/viser-cell/src/typed/IMain.ts: -------------------------------------------------------------------------------- 1 | import IAxis from './IAxis'; 2 | import IChart from './IChart'; 3 | import ICoord from './ICoord'; 4 | import IGuide from './IGuide'; 5 | import ILegend from './ILegend'; 6 | import IScale from './IScale'; 7 | import ISeries from './ISeries'; 8 | import ITooltip from './ITooltip'; 9 | 10 | export interface ISMain { 11 | data?: any; 12 | chart?: IChart; 13 | legend?: ILegend; 14 | coord?: ICoord; 15 | series?: ISeries; 16 | tooltip?: ITooltip; 17 | scale?: IScale; 18 | axis?: IAxis; 19 | guide?: IGuide; 20 | } 21 | 22 | type IMainConfig = ISMain; 23 | 24 | export default IMainConfig; 25 | -------------------------------------------------------------------------------- /packages/viser-cell/src/typed/IScale.ts: -------------------------------------------------------------------------------- 1 | type formatterFunc = (val: number) => string | number; 2 | 3 | interface ICommonScale { 4 | dataKey: string; 5 | type?: string; 6 | formatter?: string | formatterFunc; 7 | range?: number[]; 8 | alias?: string; 9 | tickCount?: number; 10 | ticks?: number[]; 11 | } 12 | 13 | interface ILinearCommonScale { 14 | nice?: boolean; 15 | min?: number; 16 | max?: number; 17 | tickInterval?: number; 18 | } 19 | 20 | export type ILinearScale = ICommonScale & ILinearCommonScale; 21 | 22 | interface ISCatScale { 23 | values?: string; 24 | } 25 | 26 | export type ICatScale = ILinearCommonScale & ISCatScale; 27 | 28 | interface ISTimeCatScale { 29 | nice?: boolean; 30 | mask?: string; 31 | values?: string; 32 | } 33 | 34 | export type ITimeCatScale = ILinearCommonScale & ISTimeCatScale; 35 | 36 | export type IScale = ILinearScale | ICatScale | ITimeCatScale; 37 | 38 | type IScaleConfig = IScale | IScale[]; 39 | 40 | export default IScaleConfig; 41 | -------------------------------------------------------------------------------- /packages/viser-cell/src/typed/ISeries.ts: -------------------------------------------------------------------------------- 1 | export interface ISeries { 2 | quickType?: string; 3 | position?: string | string[]; 4 | gemo?: string; 5 | adjust?: string | string[] | object[]; 6 | color?: any; 7 | shape?: any; 8 | size?: any; 9 | style?: any; 10 | animate?: object; 11 | } 12 | 13 | type ISeriesConfig = ISeries | ISeries[]; 14 | 15 | export default ISeriesConfig; 16 | -------------------------------------------------------------------------------- /packages/viser-cell/src/typed/IStyle.ts: -------------------------------------------------------------------------------- 1 | export interface ITextStyle { 2 | fontSize?: number | string; 3 | fontFamily?: string; 4 | fontWeight?: number | string; 5 | textAlign?: string; 6 | fill?: string; 7 | lineHeight?: number; 8 | textBaseline?: string; 9 | rotate?: number; 10 | shadowBlur?: number; 11 | shadowColor?: string; 12 | } 13 | 14 | export interface ILineStyle { 15 | stroke?: string; 16 | strokeOpacity?: number; 17 | lineWidth?: number; 18 | lineHeight?: number; 19 | lineDash?: number[]; 20 | length?: number; 21 | textAlign?: string; 22 | } 23 | 24 | export interface IPointStyle { 25 | fill: string; 26 | r: number; 27 | lineWidth: number; 28 | stroke: string; 29 | } 30 | -------------------------------------------------------------------------------- /packages/viser-cell/src/typed/ITooltip.ts: -------------------------------------------------------------------------------- 1 | import * as IStyle from './IStyle'; 2 | 3 | type eventFunc = (ev: any, chart: any) => void; 4 | 5 | export interface ITooltip { 6 | offsetX?: number; 7 | offsetY?: number; 8 | items?: object[]; 9 | show?: boolean; 10 | triggerOn?: string | string[]; 11 | triggerOff?: string | string[]; 12 | showTitle?: boolean; 13 | showCrosshairs?: boolean; 14 | crosshairsStyle?: IStyle.ILineStyle; 15 | showTooltipMarker?: boolean; 16 | background?: any; 17 | titleStyle?: IStyle.ITextStyle; 18 | nameStyle?: IStyle.ITextStyle; 19 | valueStyle?: IStyle.ITextStyle; 20 | showItemMarker?: boolean; 21 | itemMarkerStyle?: any; 22 | custom?: boolean; 23 | onShow?: eventFunc; 24 | onHide?: eventFunc; 25 | onChange?: eventFunc; 26 | } 27 | 28 | type ITooltipConfig = boolean | ITooltip; 29 | 30 | export default ITooltipConfig; 31 | -------------------------------------------------------------------------------- /packages/viser-cell/src/utils/CustomizeUtils.ts: -------------------------------------------------------------------------------- 1 | declare const require: any; 2 | // tslint:disable-next-line:no-var-requires 3 | const F2 = require('@antv/f2'); 4 | 5 | export const registerShape = (geoName: string, shapeName: string, shapeFun: any) => { 6 | F2.Shape.registerShape(geoName, shapeName, shapeFun); 7 | }; 8 | 9 | export const registerAnimation = (animationName: string, animationFun: any) => { 10 | F2.Animate.registerAnimation(animationName, animationFun); 11 | }; 12 | 13 | export const registerGesture = (gestureFun: any) => { 14 | F2.Chart.plugins.register(gestureFun); 15 | }; 16 | -------------------------------------------------------------------------------- /packages/viser-cell/src/utils/MathUtils.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Calculate the vertor normal to the specified verctor 3 | * @param vector number[] 4 | */ 5 | export const calculateUnitNormal = (vector: number[]) => { 6 | const [a = 0, b = 0] = vector; 7 | const magnitud = Math.pow(a, 2) + Math.pow(b, 2); 8 | 9 | if (magnitud <= 0) { 10 | return [0, 0]; 11 | } 12 | 13 | if (a === 0) { return [1, 0]; } 14 | const tanTheta = b / a; 15 | const theta = Math.atan(tanTheta); 16 | const normalTheta = theta + Math.PI / 2; 17 | 18 | return [Math.cos(normalTheta), Math.sin(normalTheta)]; 19 | }; 20 | -------------------------------------------------------------------------------- /packages/viser-cell/src/utils/PolarUtils.ts: -------------------------------------------------------------------------------- 1 | export const degreeToRadian = (angle: number): number => { 2 | return angle * Math.PI / 180; 3 | }; 4 | 5 | export const radianToDegree = (angleInRadian: number): number => { 6 | return angleInRadian * 180 / Math.PI; 7 | }; 8 | 9 | export const polarToCartesian = (cx: number, cy: number, radius: number, angle: number) => { 10 | const radian = degreeToRadian(angle); 11 | return { 12 | x: cx + Math.cos(radian) * radius, 13 | y: cy + Math.sin(radian) * radius, 14 | }; 15 | }; 16 | -------------------------------------------------------------------------------- /packages/viser-cell/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "es2015", 4 | "outDir": "es", 5 | "strict": true, 6 | "noImplicitAny": true, 7 | "noUnusedLocals": true, 8 | "removeComments": true, 9 | "preserveConstEnums": true, 10 | "sourceMap": true, 11 | "moduleResolution": "node", 12 | "declaration": true, 13 | "lib": [ 14 | "dom", 15 | "es2015" 16 | ] 17 | }, 18 | "include": [ 19 | "src/**/*" 20 | ], 21 | "exclude": [ 22 | "node_modules" 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /packages/viser-cell/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "error", 3 | "extends": [ 4 | "tslint:latest" 5 | ], 6 | "jsRules": {}, 7 | "rules": { 8 | "quotemark": [true, "single"], 9 | "no-console": [true, "log", "warn"], 10 | "object-literal-sort-keys": false 11 | }, 12 | "rulesDirectory": [] 13 | } 14 | -------------------------------------------------------------------------------- /packages/viser-cell/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpack = require('webpack'); 3 | const env = process.env.NODE_ENV; 4 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; 5 | 6 | let config = { 7 | mode: 'production', 8 | 9 | entry: './lib/index.js', 10 | 11 | output: { 12 | path: path.resolve(__dirname, 'umd'), 13 | filename: 'viser-cell.min.js', 14 | library: 'ViserCell', 15 | libraryTarget: 'umd', 16 | }, 17 | 18 | resolve: { 19 | extensions: ['.js', '.json'], 20 | }, 21 | 22 | module: { 23 | rules: [{ 24 | test: /\.js?$/, 25 | exclude: /node_modules/, 26 | use: { 27 | loader: "babel-loader" 28 | } 29 | }] 30 | }, 31 | 32 | plugins: [], 33 | }; 34 | 35 | if (env === 'analyse') { 36 | config.plugins.push(new BundleAnalyzerPlugin()); 37 | } 38 | 39 | module.exports = config; 40 | -------------------------------------------------------------------------------- /packages/viser-graph-ng/.babelrc.js: -------------------------------------------------------------------------------- 1 | const BABEL_ENV = process.env.BABEL_ENV 2 | const building = BABEL_ENV != undefined && BABEL_ENV !== 'cjs' 3 | 4 | const plugins = [ 5 | "@babel/plugin-proposal-export-default-from", 6 | "@babel/plugin-proposal-export-namespace-from", 7 | ["@babel/plugin-proposal-class-properties", { "loose": true }], 8 | "@babel/plugin-proposal-object-rest-spread", 9 | ]; 10 | 11 | if (BABEL_ENV === 'umd') { 12 | plugins.push('@babel/plugin-external-helpers'); 13 | } 14 | 15 | module.exports = { 16 | plugins: plugins, 17 | presets: [ 18 | [ "@babel/preset-env", { 19 | modules: building ? false : 'commonjs', 20 | targets: { 21 | "browsers": ["last 2 versions"] 22 | } 23 | } ] 24 | ], 25 | }; 26 | -------------------------------------------------------------------------------- /packages/viser-graph-ng/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 80, 3 | "tabWidth": 2, 4 | "useTabs": false, 5 | "semi": true, 6 | "singleQuote": true, 7 | "trailingComma": "es5", 8 | "bracketSpacing": true 9 | } 10 | -------------------------------------------------------------------------------- /packages/viser-graph-ng/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "viser-graph-ng", 3 | "version": "1.0.1", 4 | "description": "viser-graph-ng is angular of viser-graph.", 5 | "repository": "viserjs/viser-graph-ng", 6 | "license": "MIT", 7 | "authors": "DT-FE", 8 | "files": [ 9 | "lib", 10 | "es", 11 | "umd" 12 | ], 13 | "main": "lib/index.js", 14 | "module": "es/index.js", 15 | "types": "es/index.d.ts", 16 | "scripts": { 17 | "prepare": "npm run build", 18 | "build": "npm run build:ts && npm run build:cjs && npm run build:umd", 19 | "build:ts": "rimraf es && ngc", 20 | "build:cjs": "rimraf lib && cross-env NODE_ENV=commonjs BABEL_ENV=cjs babel ./es -d lib", 21 | "build:umd": "rimraf umd && cross-env BABEL_ENV=umd webpack --config webpack.config.js", 22 | "clean": "git clean -fdX .", 23 | "lint": "tslint src/**/*", 24 | "analyse": "cross-env NODE_ENV=analyse webpack --progress --config webpack.config.js" 25 | }, 26 | "peerDependencies": { 27 | "@angular/common": "^8.2.11", 28 | "@angular/core": "^8.2.11", 29 | "reflect-metadata": "^0.1.13", 30 | "zone.js": "^0.10.2" 31 | }, 32 | "dependencies": { 33 | "@types/core-js": "*", 34 | "@types/node": "*", 35 | "rxjs": "^6.5.3", 36 | "viser-graph": "*" 37 | }, 38 | "devDependencies": { 39 | "@angular/common": "^8.2.11", 40 | "@angular/compiler": "^8.2.11", 41 | "@angular/compiler-cli": "^8.2.11", 42 | "@angular/core": "^8.2.11", 43 | "@babel/cli": "^7.6.4", 44 | "@babel/core": "^7.6.4", 45 | "@babel/plugin-external-helpers": "^7.2.0", 46 | "@babel/plugin-proposal-class-properties": "^7.5.5", 47 | "@babel/plugin-proposal-export-default-from": "^7.5.2", 48 | "@babel/plugin-proposal-export-namespace-from": "^7.5.2", 49 | "@babel/plugin-proposal-object-rest-spread": "^7.6.2", 50 | "@babel/polyfill": "^7.6.0", 51 | "@babel/preset-env": "^7.6.3", 52 | "@babel/runtime": "^7.6.3", 53 | "babel-loader": "^8.0.6", 54 | "babel-plugin-lodash": "^3.3.4", 55 | "colors": "^1.4.0", 56 | "cross-env": "^6.0.3", 57 | "gzip-size": "^5.1.1", 58 | "ora": "^4.0.2", 59 | "pretty-bytes": "^5.3.0", 60 | "rimraf": "^3.0.0", 61 | "tslint": "^5.20.0", 62 | "typescript": "<3.6.0", 63 | "webpack": "^4.41.2", 64 | "webpack-bundle-analyzer": "^3.6.0", 65 | "webpack-cli": "^3.3.9", 66 | "zone.js": "^0.8.5" 67 | }, 68 | "keywords": [ 69 | "g6", 70 | "chart", 71 | "angular", 72 | "datavis" 73 | ] 74 | } 75 | -------------------------------------------------------------------------------- /packages/viser-graph-ng/src/components/Edge.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input } from '@angular/core'; 2 | import { Graph } from './Graph'; 3 | 4 | @Component({ 5 | selector: 'v-edge', 6 | template: `
`, 7 | }) 8 | class Edge extends Graph { 9 | @Input() public shape?: string; 10 | @Input() public color?: string; 11 | @Input() public label?: string; 12 | 13 | @Input() public formatter?: any; 14 | 15 | @Input() public events?: any; 16 | } 17 | 18 | export { Edge }; 19 | -------------------------------------------------------------------------------- /packages/viser-graph-ng/src/components/GraphService.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | @Injectable() 4 | export class GraphContext { 5 | public config: any = {}; 6 | public timer: any; 7 | public graph: any; 8 | public graphDivElement: any; 9 | 10 | } 11 | -------------------------------------------------------------------------------- /packages/viser-graph-ng/src/components/Node.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input } from '@angular/core'; 2 | import { Graph } from './Graph'; 3 | 4 | @Component({ 5 | selector: 'v-node', 6 | template: `
`, 7 | }) 8 | class Node extends Graph { 9 | @Input() public formatter?: (node: any) => any; 10 | 11 | @Input() public events?: any; 12 | } 13 | 14 | export { Node }; 15 | -------------------------------------------------------------------------------- /packages/viser-graph-ng/src/components/Zoom.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input } from '@angular/core'; 2 | import { Graph } from './Graph'; 3 | 4 | @Component({ 5 | selector: 'v-zoom', 6 | template: `
`, 7 | }) 8 | class Zoom extends Graph { 9 | @Input() public max?: number; 10 | @Input() public min?: number; 11 | @Input() public current?: number; 12 | } 13 | 14 | export { Zoom }; 15 | -------------------------------------------------------------------------------- /packages/viser-graph-ng/src/components/index.ts: -------------------------------------------------------------------------------- 1 | import {Edge} from './Edge'; 2 | import {Graph} from './Graph'; 3 | import {Node} from './Node'; 4 | import {Zoom} from './Zoom'; 5 | 6 | export { 7 | Graph, 8 | Zoom, 9 | Node, 10 | Edge, 11 | }; 12 | -------------------------------------------------------------------------------- /packages/viser-graph-ng/src/components/utils.ts: -------------------------------------------------------------------------------- 1 | export const firstLowerCase = (str: string) => { 2 | return str.replace(/^\S/, (s: any) => { 3 | return s.toLowerCase(); 4 | }); 5 | }; 6 | 7 | export const generateRandomNum = () => { 8 | return (Math.floor(new Date().getTime() + Math.random() * 10000)).toString(); 9 | }; 10 | 11 | export const isOwnEmpty = (obj: any) => { 12 | for (const name in obj) { 13 | if (obj.hasOwnProperty(name)) { 14 | return false; 15 | } 16 | } 17 | return true; 18 | }; 19 | 20 | export const retain = (obj: any, attr: string[]) => { 21 | const newObj = Object.create(null); 22 | 23 | for (const item in obj) { 24 | if (obj.hasOwnProperty(item)) { 25 | const arrAttr = Array.isArray(attr) ? attr : [attr]; 26 | 27 | if (arrAttr.indexOf(item) >= 0) { 28 | newObj[item] = obj[item]; 29 | } 30 | } 31 | } 32 | 33 | return newObj; 34 | }; 35 | 36 | export const omit = (obj: any, attr: string) => { 37 | const newObj = Object.create(null); 38 | 39 | for (const item in obj) { 40 | if (obj.hasOwnProperty(item)) { 41 | const arrAttr = Array.isArray(attr) ? attr : [attr]; 42 | 43 | if (arrAttr.indexOf(item) < 0) { 44 | newObj[item] = obj[item]; 45 | } 46 | } 47 | } 48 | 49 | return newObj; 50 | }; 51 | 52 | export const uniqComponentIdArray = (configs: any[]) => { 53 | const componentIds: any = {}; 54 | const newConfigs = [] as any; 55 | for (let i = (configs.length - 1); i >= 0; i--) { 56 | const config = configs[i]; 57 | if (!componentIds[config.componentId]) { 58 | newConfigs.push(config); 59 | componentIds[config.componentId] = true; 60 | } 61 | } 62 | newConfigs.sort((ca: any, cb: any) => { 63 | return parseInt(ca.componentId, 10) - parseInt(cb.componentId, 10); 64 | }); 65 | return newConfigs; 66 | }; 67 | -------------------------------------------------------------------------------- /packages/viser-graph-ng/src/index.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { NgModule } from '@angular/core'; 3 | import { GlobalG6, registerBehavior, registerEdge, 4 | registerLayout, registerNode, utils, ViserGraph } from 'viser-graph'; 5 | import { Edge, Graph, Node, Zoom } from './components/index'; 6 | 7 | @NgModule({ 8 | imports: [CommonModule], 9 | declarations: [ 10 | Graph, 11 | Zoom, 12 | Node, 13 | Edge, 14 | ], 15 | exports: [ 16 | Graph, 17 | Zoom, 18 | Node, 19 | Edge, 20 | ], 21 | }) 22 | 23 | export class ViserGraphModule { 24 | } 25 | 26 | export { 27 | GlobalG6, 28 | registerBehavior, 29 | registerEdge, 30 | registerLayout, 31 | registerNode, 32 | 33 | utils, 34 | ViserGraph, 35 | }; 36 | -------------------------------------------------------------------------------- /packages/viser-graph-ng/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "es2015", 4 | "moduleResolution": "node", 5 | "outDir": "es", 6 | "emitDecoratorMetadata": true, 7 | "declaration": true, 8 | "noImplicitAny": false, 9 | "noUnusedLocals": true, 10 | "strict": true, 11 | "removeComments": true, 12 | "preserveConstEnums": true, 13 | "experimentalDecorators": true, 14 | "skipLibCheck": true, 15 | "allowJs": false, 16 | "sourceMap": true, 17 | "lib": [ 18 | "dom", 19 | "es2017" 20 | ] 21 | }, 22 | "angularCompilerOptions": { 23 | "genDir": "es", 24 | "skipTemplateCodegen": true, 25 | "debug": false 26 | }, 27 | "include": ["src/**/*"], 28 | "exclude": ["node_modules"] 29 | } 30 | -------------------------------------------------------------------------------- /packages/viser-graph-ng/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "error", 3 | "extends": [ 4 | "tslint:latest" 5 | ], 6 | "jsRules": {}, 7 | "rules": { 8 | "quotemark": [true, "single"], 9 | "no-console": [true, "log", "warn"], 10 | "object-literal-sort-keys": false 11 | }, 12 | "rulesDirectory": [] 13 | } 14 | -------------------------------------------------------------------------------- /packages/viser-graph-ng/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpack = require('webpack'); 3 | const env = process.env.NODE_ENV; 4 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; 5 | 6 | let config = { 7 | mode: 'production', 8 | 9 | entry: './lib/index', 10 | 11 | output: { 12 | path: path.resolve(__dirname, 'umd'), 13 | filename: 'viser-graph-ng.min.js', 14 | library: 'ViserGraphNg', 15 | libraryTarget: 'umd', 16 | }, 17 | 18 | resolve: { 19 | extensions: ['.js', '.json'] 20 | }, 21 | 22 | externals: {}, 23 | 24 | module: { 25 | rules: [{ 26 | test: /\.js?$/, 27 | exclude: /node_modules/, 28 | use: { 29 | loader: "babel-loader" 30 | } 31 | }], 32 | }, 33 | 34 | plugins: [], 35 | }; 36 | 37 | if (env === 'analyse') { 38 | config.plugins.push(new BundleAnalyzerPlugin()); 39 | } 40 | 41 | module.exports = config; 42 | -------------------------------------------------------------------------------- /packages/viser-graph-react/.babelrc.js: -------------------------------------------------------------------------------- 1 | const BABEL_ENV = process.env.BABEL_ENV 2 | const building = BABEL_ENV != undefined && BABEL_ENV !== 'cjs' 3 | 4 | const plugins = [ 5 | "@babel/plugin-proposal-export-default-from", 6 | "@babel/plugin-proposal-export-namespace-from", 7 | ["@babel/plugin-proposal-class-properties", { "loose": true }], 8 | "@babel/plugin-proposal-object-rest-spread", 9 | ]; 10 | 11 | if (BABEL_ENV === 'umd') { 12 | plugins.push('@babel/plugin-external-helpers'); 13 | } 14 | 15 | module.exports = { 16 | plugins: plugins, 17 | presets: [ 18 | [ "@babel/preset-env", { 19 | modules: building ? false : 'commonjs', 20 | targets: { 21 | "browsers": ["last 2 versions"] 22 | } 23 | } ], 24 | '@babel/preset-react' 25 | ], 26 | }; 27 | -------------------------------------------------------------------------------- /packages/viser-graph-react/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 80, 3 | "tabWidth": 2, 4 | "useTabs": false, 5 | "semi": true, 6 | "singleQuote": true, 7 | "trailingComma": "es5", 8 | "bracketSpacing": true 9 | } 10 | -------------------------------------------------------------------------------- /packages/viser-graph-react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "viser-graph-react", 3 | "version": "1.0.1", 4 | "description": "viser-graph-react is react of viser-graph.", 5 | "repository": "viserjs/viser-graph-react", 6 | "license": "MIT", 7 | "authors": "DT-FE", 8 | "files": [ 9 | "umd", 10 | "es", 11 | "lib" 12 | ], 13 | "main": "lib/index.js", 14 | "module": "es/index.js", 15 | "types": "es/index.d.ts", 16 | "scripts": { 17 | "prepare": "npm run build", 18 | "build": "npm run build:ts && npm run build:cjs && npm run build:umd", 19 | "build:ts": "rimraf es && tsc", 20 | "build:cjs": "rimraf lib && cross-env NODE_ENV=commonjs BABEL_ENV=cjs babel ./es -d lib", 21 | "build:umd": "rimraf umd && cross-env BABEL_ENV=umd webpack --config webpack.config.js", 22 | "clean": "git clean -fdX .", 23 | "lint": "tslint src/**/*", 24 | "analyse": "cross-env NODE_ENV=analyse webpack --progress --config webpack.config.js" 25 | }, 26 | "peerDependencies": { 27 | "react": ">15", 28 | "react-dom": ">15" 29 | }, 30 | "dependencies": { 31 | "@types/node": "*", 32 | "@types/prop-types": "*", 33 | "prop-types": "^15.6.0", 34 | "viser-graph": "*" 35 | }, 36 | "devDependencies": { 37 | "@types/react": "^16.3.16", 38 | "@types/react-dom": "16.0.4", 39 | "@babel/cli": "^7.1.0", 40 | "@babel/core": "^7.0.0", 41 | "@babel/plugin-proposal-class-properties": "^7.0.0", 42 | "@babel/plugin-proposal-export-default-from": "^7.0.0", 43 | "@babel/plugin-proposal-export-namespace-from": "^7.0.0", 44 | "@babel/plugin-proposal-object-rest-spread": "^7.0.0", 45 | "@babel/plugin-external-helpers": "^7.0.0", 46 | "@babel/polyfill": "^7.0.0", 47 | "@babel/preset-env": "^7.0.0", 48 | "@babel/preset-react": "^7.0.0", 49 | "@babel/runtime": "^7.0.0", 50 | "babel-loader": "^8.0.0", 51 | "colors": "^1.1.2", 52 | "cross-env": "^5.2.0", 53 | "gzip-size": "^4.0.0", 54 | "ora": "^1.3.0", 55 | "pretty-bytes": "^4.0.2", 56 | "react": "^16.0.0", 57 | "react-dom": "^16.0.0", 58 | "rimraf": "^2.6.2", 59 | "tslint": "^5.5.0", 60 | "typescript": "~3.2.0", 61 | "webpack": "^4.20.0", 62 | "webpack-bundle-analyzer": "^3.6.0", 63 | "webpack-cli": "^3.1.0" 64 | }, 65 | "keywords": [ 66 | "g6", 67 | "chart", 68 | "react", 69 | "datavis" 70 | ] 71 | } 72 | -------------------------------------------------------------------------------- /packages/viser-graph-react/src/components/SubComponent.tsx: -------------------------------------------------------------------------------- 1 | import * as PropTypes from 'prop-types'; 2 | import * as React from 'react'; 3 | import { IEdge, INode, ITooltip, IZoom } from 'viser-graph'; 4 | 5 | class Props {} 6 | 7 | // tslint:disable-next-line:max-classes-per-file 8 | class SubComponent extends React.Component { 9 | public static contextTypes = { 10 | centralizedUpdates: PropTypes.func, 11 | hasInViews: PropTypes.bool, 12 | viewId: PropTypes.string, 13 | viewType: PropTypes.string, 14 | }; 15 | 16 | public displayName = 'SubComponent'; 17 | 18 | constructor(props: Props & T) { 19 | super(props); 20 | } 21 | 22 | public componentDidUpdate() { 23 | this.context.centralizedUpdates(this); 24 | } 25 | 26 | public componentDidMount() { 27 | this.context.centralizedUpdates(this); 28 | } 29 | 30 | public render() { 31 | return null; 32 | } 33 | } 34 | 35 | // tslint:disable-next-line:max-classes-per-file 36 | export class Zoom extends SubComponent { public displayName = 'Zoom'; } 37 | // tslint:disable-next-line:max-classes-per-file 38 | export class Node extends SubComponent { public displayName = 'Node'; } 39 | // tslint:disable-next-line:max-classes-per-file 40 | export class Edge extends SubComponent { public displayName = 'Edge'; } 41 | // tslint:disable-next-line:max-classes-per-file 42 | export class Tooltip extends SubComponent { public displayName = 'Tooltip'; } 43 | -------------------------------------------------------------------------------- /packages/viser-graph-react/src/index.ts: -------------------------------------------------------------------------------- 1 | import { GlobalG6, registerBehavior, registerEdge, registerLayout, registerNode, utils } from 'viser-graph'; 2 | import { default as Graph } from './components/Graph'; 3 | import { Edge, Node, Tooltip, Zoom } from './components/SubComponent'; 4 | 5 | export { 6 | Graph, 7 | Zoom, 8 | Node, 9 | Edge, 10 | Tooltip, 11 | 12 | registerNode, 13 | registerEdge, 14 | registerBehavior, 15 | registerLayout, 16 | 17 | utils, 18 | GlobalG6, 19 | }; 20 | -------------------------------------------------------------------------------- /packages/viser-graph-react/src/typed/IGraph.ts: -------------------------------------------------------------------------------- 1 | export default interface IGraph { 2 | data: any; 3 | container: any; 4 | width?: number | string; 5 | height?: number | string; 6 | fitView?: 'tl' | 'lc' | 'bl' | 'cc' | 'tc' | 'tr' | 'rc' | 'br' | 'bc' | 'autoZoom'; 7 | fitViewPadding?: boolean | number | number[]; 8 | animate?: boolean; 9 | minZoom?: number; 10 | maxZoom?: number; 11 | type?: 'tree' | 'graph'; 12 | modes?: any; 13 | mode?: string; 14 | plugins?: any[]; 15 | layout?: any; 16 | } 17 | -------------------------------------------------------------------------------- /packages/viser-graph-react/src/typed/IZoom.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viserjs/viser/625d52c2b2799cce9b1289857e61577e1f71b167/packages/viser-graph-react/src/typed/IZoom.ts -------------------------------------------------------------------------------- /packages/viser-graph-react/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "es2015", 4 | "moduleResolution": "node", 5 | "outDir": "es", 6 | "jsx": "react", 7 | "strict": true, 8 | "noUnusedLocals": true, 9 | "noImplicitAny": false, 10 | "removeComments": true, 11 | "preserveConstEnums": true, 12 | "sourceMap": true, 13 | "declaration": true, 14 | "lib": [ 15 | "dom", 16 | "es5", 17 | "es6", 18 | "scripthost" 19 | ] 20 | }, 21 | "include": [ 22 | "src/**/*" 23 | ], 24 | "exclude": [ 25 | "node_modules" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /packages/viser-graph-react/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "error", 3 | "extends": [ 4 | "tslint:latest" 5 | ], 6 | "jsRules": {}, 7 | "rules": { 8 | "quotemark": [true, "single"], 9 | "no-console": [true, "log", "warn"], 10 | "object-literal-sort-keys": false 11 | }, 12 | "rulesDirectory": [] 13 | } 14 | -------------------------------------------------------------------------------- /packages/viser-graph-react/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpack = require('webpack'); 3 | const env = process.env.NODE_ENV; 4 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; 5 | 6 | let config = { 7 | mode: 'production', 8 | 9 | entry: './lib/index.js', 10 | 11 | output: { 12 | path: path.resolve(__dirname, 'umd'), 13 | filename: 'viser-graph-react.min.js', 14 | library: 'ViserGraphReact', 15 | libraryTarget: 'umd', 16 | }, 17 | 18 | resolve: { 19 | extensions: ['.js', '.json'], 20 | }, 21 | 22 | externals: { 23 | 'react': 'React', 24 | 'react-dom': 'ReactDOM', 25 | }, 26 | 27 | module: { 28 | rules: [{ 29 | test: /\.js?$/, 30 | exclude: /node_modules/, 31 | use: { 32 | loader: "babel-loader" 33 | } 34 | }], 35 | }, 36 | 37 | plugins: [], 38 | }; 39 | 40 | if (env === 'analyse') { 41 | config.plugins.push(new BundleAnalyzerPlugin()); 42 | } 43 | 44 | module.exports = config; 45 | -------------------------------------------------------------------------------- /packages/viser-graph-vue/.babelrc.js: -------------------------------------------------------------------------------- 1 | const BABEL_ENV = process.env.BABEL_ENV 2 | const building = BABEL_ENV != undefined && BABEL_ENV !== 'cjs' 3 | 4 | const plugins = [ 5 | "@babel/plugin-proposal-export-default-from", 6 | "@babel/plugin-proposal-export-namespace-from", 7 | ["@babel/plugin-proposal-class-properties", { "loose": true }], 8 | "@babel/plugin-proposal-object-rest-spread", 9 | ]; 10 | 11 | if (BABEL_ENV === 'umd') { 12 | plugins.push('@babel/plugin-external-helpers'); 13 | } 14 | 15 | module.exports = { 16 | plugins: plugins, 17 | presets: [ 18 | [ "@babel/preset-env", { 19 | modules: building ? false : 'commonjs', 20 | targets: { 21 | "browsers": ["last 2 versions"] 22 | } 23 | } ] 24 | ], 25 | }; 26 | -------------------------------------------------------------------------------- /packages/viser-graph-vue/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 80, 3 | "tabWidth": 2, 4 | "useTabs": false, 5 | "semi": true, 6 | "singleQuote": true, 7 | "trailingComma": "es5", 8 | "bracketSpacing": true 9 | } 10 | -------------------------------------------------------------------------------- /packages/viser-graph-vue/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "viser-graph-vue", 3 | "version": "1.0.1", 4 | "description": "viser-graph-vue is vue of viser-graph.", 5 | "repository": "viserjs/viser-graph-vue", 6 | "license": "MIT", 7 | "authors": "DT-FE", 8 | "files": [ 9 | "umd", 10 | "es", 11 | "lib" 12 | ], 13 | "main": "lib/index.js", 14 | "module": "es/index.js", 15 | "types": "es/index.d.ts", 16 | "scripts": { 17 | "prepublish": "npm run build", 18 | "build": "npm run build:ts && npm run build:cjs && npm run build:umd", 19 | "build:ts": "rimraf es && tsc", 20 | "build:cjs": "rimraf lib && cross-env NODE_ENV=commonjs BABEL_ENV=cjs babel ./es -d lib", 21 | "build:umd": "rimraf umd && cross-env BABEL_ENV=umd webpack --config webpack.config.js", 22 | "clean": "git clean -fdX .", 23 | "lint": "tslint src/**/*", 24 | "analyse": "cross-env NODE_ENV=analyse webpack --progress --config webpack.config.js" 25 | }, 26 | "peerDependencies": { 27 | "vue": ">=1" 28 | }, 29 | "dependencies": { 30 | "@types/node": "*", 31 | "viser-graph": "*", 32 | "vue": "^2.5.3" 33 | }, 34 | "devDependencies": { 35 | "@babel/cli": "^7.1.0", 36 | "@babel/core": "^7.0.0", 37 | "@babel/plugin-proposal-class-properties": "^7.0.0", 38 | "@babel/plugin-proposal-export-default-from": "^7.0.0", 39 | "@babel/plugin-proposal-export-namespace-from": "^7.0.0", 40 | "@babel/plugin-proposal-object-rest-spread": "^7.0.0", 41 | "@babel/plugin-external-helpers": "^7.0.0", 42 | "@babel/polyfill": "^7.0.0", 43 | "@babel/preset-env": "^7.0.0", 44 | "@babel/runtime": "^7.0.0", 45 | "babel-loader": "^8.0.0", 46 | "colors": "^1.1.2", 47 | "cross-env": "^5.2.0", 48 | "gzip-size": "^4.0.0", 49 | "ora": "^1.3.0", 50 | "pretty-bytes": "^4.0.2", 51 | "rimraf": "^2.6.2", 52 | "ts-loader": "^3.1.1", 53 | "tslint": "^5.5.0", 54 | "typescript": "~3.2.0", 55 | "webpack": "^4.20.0", 56 | "webpack-bundle-analyzer": "^3.6.0", 57 | "webpack-cli": "^3.1.0" 58 | }, 59 | "keywords": [ 60 | "g6", 61 | "chart", 62 | "react", 63 | "datavis" 64 | ] 65 | } 66 | -------------------------------------------------------------------------------- /packages/viser-graph-vue/src/typed.ts: -------------------------------------------------------------------------------- 1 | const graphProps = [ 2 | 'data', 'type', 'nodeStateStyles', 'edgeStateStyles', 3 | 'defaultNode', 'defaultEdge', 'plugins', 'layout', 4 | 'fixedRoot', 'moveTo', 'focusItem', 'hideItem', 'showItem', 5 | 'events', 'modes', 'width', 'height', 'pixelRatio', 'fitView', 6 | ]; 7 | 8 | const zoomProps = ['min', 'max', 'current']; 9 | const nodePros = ['formatter']; 10 | const edgeProps = ['shape', 'color', 'label', 'formatter', 'events']; 11 | 12 | const eventProps = [ 13 | 'onMouseDown', 'onMouseMove', 'onMouseUp', 'onMouseenter', 'onMouseleave', 14 | 'onClick', 'onDbClick', 15 | 'onDragstart', 'onDrag', 'onDragend', 'onDragleave', 'onDragenter', 16 | 'onContextmenu', 'onBeforepaint', 'onBeforelayout', 'onAfterlayout', 17 | ]; 18 | 19 | const props: any = graphProps.concat(zoomProps).concat(eventProps) 20 | .concat(nodePros).concat(edgeProps); 21 | 22 | const unique = (array: any) => { 23 | const res = [] as any; 24 | for (let i = 0, len = array.length; i < len; i++) { 25 | const current = array[i]; 26 | if (res.indexOf(current) === -1) { 27 | res.push(current); 28 | } 29 | } 30 | 31 | return res; 32 | }; 33 | 34 | const changeObj = (array: any) => { 35 | const uniqueProps = unique(array); 36 | const propsObject: any = {}; 37 | 38 | for (const res of uniqueProps) { 39 | propsObject[res] = null; 40 | } 41 | 42 | return propsObject; 43 | }; 44 | 45 | export { 46 | changeObj, 47 | unique, 48 | props, 49 | graphProps, 50 | zoomProps, 51 | nodePros, 52 | edgeProps, 53 | eventProps, 54 | }; 55 | -------------------------------------------------------------------------------- /packages/viser-graph-vue/src/utils.ts: -------------------------------------------------------------------------------- 1 | export const camelCase: any = (() => { 2 | const DEFAULT_REGEX = /[-_]+(.)?/g; 3 | 4 | function toUpper(match: string, group1: string) { 5 | return group1 ? group1.toUpperCase() : ''; 6 | } 7 | return (str: string, delimiters?: string) => { 8 | return str.replace( 9 | delimiters ? new RegExp('[' + delimiters + ']+(.)?', 'g') : DEFAULT_REGEX, 10 | toUpper, 11 | ); 12 | }; 13 | })(); 14 | export const safePush = (obj: any, key: string, value: any) => { 15 | if (!obj[key]) { 16 | obj[key] = []; 17 | } 18 | 19 | cleanUndefined(value); 20 | 21 | obj[key].push(value); 22 | }; 23 | 24 | export const oneObjectMoreArray = (obj: any, key: string, value: any) => { 25 | if (!obj[key]) { 26 | obj[key] = value; 27 | return; 28 | } 29 | 30 | if (obj[key] && obj[key].constructor.name === 'Object') { 31 | obj[key] = [obj[key]]; 32 | } 33 | 34 | let indexOfSameObject = -1; 35 | if (value && value.viewId) { 36 | obj[key].forEach((o: any, i: number) => { 37 | if (o && o.viewId && o.viewId === value.viewId) { 38 | indexOfSameObject = i; 39 | } 40 | }); 41 | } else if (value && value.componentId) { 42 | obj[key].forEach((o: any, i: number) => { 43 | if (o && o.componentId && o.componentId === value.componentId) { 44 | indexOfSameObject = i; 45 | } 46 | }); 47 | } 48 | 49 | if (indexOfSameObject === -1) { 50 | obj[key].push(value); 51 | } else { 52 | obj[key][indexOfSameObject] = { 53 | ...obj[key][indexOfSameObject], 54 | ...value, 55 | }; 56 | } 57 | }; 58 | 59 | export const cleanUndefined = (value: any) => { 60 | const newValue = { ...value }; 61 | 62 | // delete value's undefined key 63 | for (const key in newValue) { 64 | if (newValue[key] === undefined) { 65 | delete newValue[key]; 66 | } 67 | } 68 | 69 | return newValue; 70 | }; 71 | 72 | export const isAllUndefined = (value: any) => { 73 | return Object.keys(value).every((key) => value[key] === undefined); 74 | }; 75 | 76 | export const camelize = (str: string) => { 77 | return str.replace(/(?:^\w|[A-Z]|\b\w)/g, (letter, index) => { 78 | return index === 0 ? letter.toLowerCase() : letter.toUpperCase(); 79 | }).replace(/\s+/g, ''); 80 | }; 81 | 82 | /** 83 | * special props for vue 84 | */ 85 | export const normalizeProps = (props: any, include: string[] = [], exclude: string[] = []) => { 86 | const newProps = { ...props }; 87 | 88 | if (newProps.vStyle) { 89 | newProps.style = newProps.vStyle; 90 | delete newProps.vStyle; 91 | } 92 | 93 | if (exclude.length) { 94 | exclude.forEach((propsKey) => { 95 | delete newProps[propsKey]; 96 | }); 97 | } 98 | 99 | if (include.length) { 100 | Object.keys(newProps).forEach((propsKey) => { 101 | if (include.indexOf(propsKey) === -1) { 102 | delete newProps[propsKey]; 103 | } 104 | }); 105 | } 106 | 107 | return newProps; 108 | }; 109 | 110 | export const generateRandomNum = () => { 111 | return (Math.floor(new Date().getTime() + Math.random() * 10000)).toString(); 112 | }; 113 | -------------------------------------------------------------------------------- /packages/viser-graph-vue/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "es2015", 4 | "moduleResolution": "node", 5 | "outDir": "es", 6 | "strict": true, 7 | "noUnusedLocals": true, 8 | "noImplicitAny": false, 9 | "removeComments": true, 10 | "preserveConstEnums": true, 11 | "sourceMap": true, 12 | "declaration": true, 13 | "lib": [ 14 | "dom", 15 | "es5", 16 | "es6", 17 | "scripthost" 18 | ] 19 | }, 20 | "include": [ 21 | "src/**/*" 22 | ], 23 | "exclude": [ 24 | "node_modules" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /packages/viser-graph-vue/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "error", 3 | "extends": [ 4 | "tslint:latest" 5 | ], 6 | "jsRules": {}, 7 | "rules": { 8 | "quotemark": [true, "single"], 9 | "no-console": [true, "log", "warn"], 10 | "object-literal-sort-keys": false 11 | }, 12 | "rulesDirectory": [] 13 | } 14 | -------------------------------------------------------------------------------- /packages/viser-graph-vue/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpack = require('webpack'); 3 | const env = process.env.NODE_ENV; 4 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; 5 | 6 | let config = { 7 | mode: 'production', 8 | 9 | entry: './lib/index', 10 | 11 | output: { 12 | path: path.resolve(__dirname, 'umd'), 13 | filename: 'viser-graph-vue.min.js', 14 | library: 'ViserGraphVue', 15 | libraryTarget: 'umd', 16 | }, 17 | 18 | resolve: { 19 | extensions: ['.js', '.json'], 20 | }, 21 | 22 | externals: { 23 | 'vue': 'Vue', 24 | }, 25 | 26 | module: { 27 | rules: [{ 28 | test: /\.js?$/, 29 | exclude: /node_modules/, 30 | use: { 31 | loader: "babel-loader" 32 | } 33 | }], 34 | }, 35 | 36 | plugins: [], 37 | }; 38 | 39 | if (env === 'analyse') { 40 | config.plugins.push(new BundleAnalyzerPlugin()); 41 | } 42 | 43 | module.exports = config; 44 | -------------------------------------------------------------------------------- /packages/viser-graph/.babelrc.js: -------------------------------------------------------------------------------- 1 | const BABEL_ENV = process.env.BABEL_ENV 2 | const building = BABEL_ENV != undefined && BABEL_ENV !== 'cjs' 3 | 4 | const plugins = [ 5 | "@babel/plugin-proposal-export-default-from", 6 | "@babel/plugin-proposal-export-namespace-from", 7 | ["@babel/plugin-proposal-class-properties", { "loose": true }], 8 | "@babel/plugin-proposal-object-rest-spread", 9 | ]; 10 | 11 | if (BABEL_ENV === 'umd') { 12 | plugins.push('@babel/plugin-external-helpers'); 13 | } 14 | 15 | module.exports = { 16 | plugins: plugins, 17 | presets: [ 18 | [ "@babel/preset-env", { 19 | modules: building ? false : 'commonjs', 20 | targets: { 21 | "browsers": ["last 2 versions"] 22 | } 23 | } ] 24 | ], 25 | }; 26 | -------------------------------------------------------------------------------- /packages/viser-graph/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 80, 3 | "tabWidth": 2, 4 | "useTabs": false, 5 | "semi": true, 6 | "singleQuote": true, 7 | "trailingComma": "es5", 8 | "bracketSpacing": true 9 | } 10 | -------------------------------------------------------------------------------- /packages/viser-graph/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "viser-graph", 3 | "version": "1.0.2", 4 | "description": "viser is a toolkit fit for data vis engineer.", 5 | "license": "MIT", 6 | "authors": "DT-FE", 7 | "files": [ 8 | "umd", 9 | "es", 10 | "lib" 11 | ], 12 | "main": "lib/index.js", 13 | "module": "es/index.js", 14 | "types": "es/index.d.ts", 15 | "scripts": { 16 | "prepare": "npm run build", 17 | "build": "npm run build:ts && npm run build:cjs && npm run build:umd", 18 | "build:ts": "rimraf es && tsc", 19 | "build:cjs": "rimraf lib && cross-env NODE_ENV=commonjs BABEL_ENV=cjs babel ./es -d lib", 20 | "build:umd": "rimraf umd && cross-env BABEL_ENV=umd webpack --config webpack.config.js", 21 | "clean": "git clean -fdX .", 22 | "lint": "tslint src/**/*", 23 | "analyse": "cross-env NODE_ENV=analyse webpack --progress --config webpack.config.js" 24 | }, 25 | "dependencies": { 26 | "@antv/g6": "3.3.0-beta.6", 27 | "@types/lodash": "^4.14.149", 28 | "@types/node": "*", 29 | "csstype": "^2.6.7", 30 | "lodash": "^4.17.15" 31 | }, 32 | "devDependencies": { 33 | "@babel/cli": "^7.1.0", 34 | "@babel/core": "^7.0.0", 35 | "@babel/plugin-proposal-class-properties": "^7.0.0", 36 | "@babel/plugin-proposal-export-default-from": "^7.0.0", 37 | "@babel/plugin-proposal-export-namespace-from": "^7.0.0", 38 | "@babel/plugin-proposal-object-rest-spread": "^7.0.0", 39 | "@babel/plugin-external-helpers": "^7.0.0", 40 | "@babel/polyfill": "^7.0.0", 41 | "@babel/preset-env": "^7.0.0", 42 | "@babel/runtime": "^7.0.0", 43 | "babel-loader": "^8.0.0", 44 | "colors": "^1.1.2", 45 | "cross-env": "^5.2.0", 46 | "gzip-size": "^4.0.0", 47 | "ora": "^1.3.0", 48 | "pretty-bytes": "^4.0.2", 49 | "rimraf": "^2.6.2", 50 | "tslint": "^5.5.0", 51 | "typescript": "~3.2.0", 52 | "webpack": "^4.20.0", 53 | "webpack-bundle-analyzer": "^3.6.0", 54 | "webpack-cli": "^3.1.0" 55 | }, 56 | "keywords": [ 57 | "g6", 58 | "chart", 59 | "react", 60 | "datavis" 61 | ] 62 | } 63 | -------------------------------------------------------------------------------- /packages/viser-graph/src/graph.ts: -------------------------------------------------------------------------------- 1 | import G6 from '@antv/g6'; 2 | import * as _ from 'lodash'; 3 | import { IConfig, IGraph } from './typed'; 4 | 5 | export class ViserGraph { 6 | public config: any; 7 | public graph: any; 8 | constructor(config: IConfig) { 9 | this.config = config; 10 | } 11 | 12 | public reRender(config: any) { 13 | this.config = config; 14 | this.setData(); 15 | this.setZoom(); 16 | } 17 | 18 | public render() { 19 | this.setGraph(); 20 | this.setNode(); 21 | this.setEdge(); 22 | this.setData(); 23 | this.setZoom(); 24 | this.graph.render(); 25 | 26 | this.setEvent(); 27 | } 28 | 29 | public setGraph() { 30 | if (!this.config.graph.container) { 31 | console.error('please set container'); 32 | return; 33 | } 34 | let graphConfig: IGraph = { 35 | container: this.config.graph.container, 36 | ...this.config.graph, 37 | }; 38 | 39 | if (this.config.zoom) { 40 | graphConfig = { 41 | ...graphConfig, 42 | minZoom: _.get(this.config, 'zoom.min', 1), 43 | maxZoom: _.get(this.config, 'zoom.max', 2), 44 | }; 45 | } 46 | 47 | switch (this.config.graph.type) { 48 | case 'tree': 49 | this.graph = new G6.TreeGraph(graphConfig as any); 50 | break; 51 | case 'graph': 52 | this.graph = new G6.Graph(graphConfig as any); 53 | break; 54 | default: 55 | this.graph = new G6.Graph(graphConfig as any); 56 | } 57 | 58 | } 59 | 60 | public setData() { 61 | if (!this.config.data) { 62 | console.error('please set data'); 63 | return ; 64 | } 65 | this.graph.data(this.config.data); 66 | } 67 | 68 | public setNode() { 69 | if (!this.config.node) { 70 | return; 71 | } 72 | delete this.config.node.componentId; 73 | if (_.get(this.config, 'node.formatter')) { 74 | this.graph.node(this.config.node.formatter); 75 | } 76 | } 77 | 78 | public setEdge() { 79 | if (!this.config.edge) { 80 | return; 81 | } 82 | delete this.config.edge.componentId; 83 | if (_.get(this.config, 'edge.formatter')) { 84 | this.graph.edge(this.config.edge.formatter); 85 | } 86 | } 87 | 88 | public setZoom() { 89 | if (!this.config.zoom || !this.config.zoom.current) { 90 | return; 91 | } 92 | this.graph.zoom(this.config.zoom.current); 93 | } 94 | 95 | public setEvent() { 96 | this.bindEvent(_.get(this.config, 'graph.events', {}), ''); 97 | this.bindEvent(_.get(this.config, 'node.events', {}), 'node'); 98 | this.bindEvent(_.get(this.config, 'edge.events', {}), 'edge'); 99 | } 100 | 101 | protected bindEvent(events: any, type: string) { 102 | Object.keys(events || []).forEach((k) => { 103 | const eventName = k.replace('on', '').toLocaleLowerCase(); 104 | this.graph.on(type === '' ? eventName : `${type}:${eventName}`, (ev: any) => { 105 | events[k](ev, this.graph); 106 | }); 107 | }); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /packages/viser-graph/src/index.ts: -------------------------------------------------------------------------------- 1 | import G6 from '@antv/g6'; 2 | 3 | const { registerNode, registerEdge, registerBehavior, registerLayout} = G6; 4 | 5 | /** 全局 G6 可获取所有属性 */ 6 | const GlobalG6 = G6; 7 | 8 | import { ViserGraph } from './graph'; 9 | import { 10 | IEdge, 11 | IGraph, 12 | INode, 13 | ITooltip, 14 | IZoom, 15 | } from './typed'; 16 | 17 | import * as utils from './utils'; 18 | 19 | export { 20 | ViserGraph, 21 | IEdge, 22 | IGraph, 23 | INode, 24 | IZoom, 25 | ITooltip, 26 | 27 | registerNode, 28 | registerEdge, 29 | registerBehavior, 30 | registerLayout, 31 | 32 | GlobalG6, 33 | 34 | utils, 35 | }; 36 | -------------------------------------------------------------------------------- /packages/viser-graph/src/typed/IEdge.ts: -------------------------------------------------------------------------------- 1 | import IEvent from './IEvent'; 2 | 3 | export default interface IEdge { 4 | shape?: string; 5 | color?: string; 6 | label?: string; 7 | 8 | formatter?: any; 9 | 10 | events?: IEvent; 11 | } 12 | -------------------------------------------------------------------------------- /packages/viser-graph/src/typed/IEvent.ts: -------------------------------------------------------------------------------- 1 | type func = (ev: any, graph: any) => void; 2 | 3 | export default interface IEvent { 4 | onClick?: func; 5 | onDbclick?: func; 6 | 7 | onMousedown?: func; 8 | onMousemove?: func; 9 | onMouseenter?: func; 10 | onMouseleave?: func; 11 | onMouseup?: func; 12 | 13 | onDragstart?: func; 14 | onDrag?: func; 15 | onDragend?: func; 16 | onDragleave?: func; 17 | onDragenter?: func; 18 | 19 | onContextmenu?: func; 20 | onBeforepaint?: func; 21 | onBeforelayout?: func; 22 | onAfterlayout?: func; 23 | } 24 | -------------------------------------------------------------------------------- /packages/viser-graph/src/typed/IGraph.ts: -------------------------------------------------------------------------------- 1 | import { GraphOptions } from '@antv/g6/lib/interface/graph.d'; 2 | import IEvent from './IEvent'; 3 | 4 | type ILayoutFunc = (node: any) => number; 5 | interface ILayout { 6 | type: string; 7 | direction?: string; 8 | // H / V / LR / RL / TB / BT 9 | nodeSep?: number; 10 | rankSep?: number; 11 | radial?: boolean; 12 | ranksep?: number; 13 | defalutPosition?: string[]; 14 | preventOverlap?: boolean; 15 | unitRadius?: number; 16 | indent?: number; 17 | gravity?: number; 18 | speed?: number; 19 | nodeSize?: number; 20 | divisions?: number; 21 | radius?: number; 22 | startAngle?: number; 23 | endAngle?: number; 24 | startRadius?: number; 25 | endRadius?: number; 26 | ordering?: 'degree' | string; 27 | strictRadial?: boolean; 28 | maxPreventOverlapIteration?: number; 29 | clustering?: boolean; 30 | rankdir?: 'LR' | string; 31 | align?: 'DL' | string; 32 | maxLevelDiff?: number; 33 | sortBy?: 'degree' | string; 34 | linkDistance?: number | ILayoutFunc; 35 | nodeStrength?: ILayoutFunc; 36 | edgeStrength?: ILayoutFunc | number; 37 | getHeight?: () => number; 38 | getWidth?: () => number; 39 | getVGap?: () => number; 40 | getHGap?: () => number; 41 | getId?: (d: any) => string | number; 42 | getSide?: (d: any) => string; 43 | nodesepFunc?: ILayoutFunc; 44 | ranksepFunc?: ILayoutFunc; 45 | } 46 | /** 仅定义更限制的类型,未定义的遵循 G6 的定义 */ 47 | export default interface IGraph extends GraphOptions { 48 | container: string | HTMLElement; 49 | type?: 'tree' | 'graph'; 50 | plugins?: any[]; 51 | layout?: ILayout; 52 | pixelRatio?: number; 53 | 54 | fixedRoot?: boolean; 55 | // TODO 待实现 api 56 | // moveTo?: number[]; 57 | // focusItem?: any; 58 | // hideItem?: any; 59 | // showItem?: any; 60 | 61 | events?: IEvent; 62 | } 63 | -------------------------------------------------------------------------------- /packages/viser-graph/src/typed/ILayout.ts: -------------------------------------------------------------------------------- 1 | export default interface ILayout { 2 | type?: string; 3 | } 4 | -------------------------------------------------------------------------------- /packages/viser-graph/src/typed/INode.ts: -------------------------------------------------------------------------------- 1 | import { INodeConfig } from './common'; 2 | import IEvent from './IEvent'; 3 | export default interface INode { 4 | /** 生成node config */ 5 | formatter?: (node: any) => INodeConfig; 6 | 7 | events?: IEvent; 8 | } 9 | -------------------------------------------------------------------------------- /packages/viser-graph/src/typed/ITooltip.ts: -------------------------------------------------------------------------------- 1 | 2 | import { IOffset } from './common'; 3 | 4 | export default interface ITooltip { 5 | show?: boolean; 6 | offset?: IOffset; 7 | } 8 | -------------------------------------------------------------------------------- /packages/viser-graph/src/typed/IZoom.ts: -------------------------------------------------------------------------------- 1 | interface IPosition { 2 | x?: number; 3 | y?: number; 4 | } 5 | 6 | export default interface IZoom { 7 | /** 是否相对于画布 */ 8 | isCanvasRelative?: boolean; 9 | /** 当前 zoom */ 10 | ratio: number; 11 | /** min max zoom */ 12 | min?: number; 13 | max?: number; 14 | /** zoom 中心点 */ 15 | center?: IPosition; 16 | } 17 | -------------------------------------------------------------------------------- /packages/viser-graph/src/typed/common.ts: -------------------------------------------------------------------------------- 1 | import * as CSS from 'csstype'; 2 | 3 | interface IOffset { 4 | left?: string; 5 | top?: string; 6 | } 7 | 8 | interface INodeConfig { 9 | size?: number | number[]; 10 | anchorPoints?: any[]; 11 | style?: CSS.Properties; 12 | label?: string; 13 | labelCfg?: any; 14 | shape?: string; 15 | } 16 | 17 | export { 18 | IOffset, 19 | INodeConfig, 20 | }; 21 | -------------------------------------------------------------------------------- /packages/viser-graph/src/typed/index.ts: -------------------------------------------------------------------------------- 1 | import IEdge from './IEdge'; 2 | import IGraph from './IGraph'; 3 | import INode from './INode'; 4 | import ITooltip from './ITooltip'; 5 | import IZoom from './IZoom'; 6 | 7 | interface INodeData { 8 | id: string; 9 | [key: string]: any; 10 | } 11 | 12 | interface IEdgeData { 13 | source: string; 14 | target: string; 15 | value?: number; 16 | [key: string]: any; 17 | } 18 | 19 | interface IGraphData { 20 | nodes: INodeData[]; 21 | edges?: IEdgeData[]; 22 | } 23 | 24 | interface ITreeData { 25 | [key: string]: any; 26 | } 27 | 28 | interface IConfig { 29 | data: IGraphData | ITreeData; 30 | graph: IGraph; 31 | node?: INode; 32 | edge?: IEdge; 33 | zoom?: IZoom; 34 | plugin?: any; 35 | tooltip?: any; 36 | } 37 | 38 | export { 39 | IConfig, 40 | IGraph, 41 | INode, 42 | IEdge, 43 | IZoom, 44 | ITooltip, 45 | }; 46 | -------------------------------------------------------------------------------- /packages/viser-graph/src/utils.ts: -------------------------------------------------------------------------------- 1 | /** 计算字符长度 */ 2 | function strLen(str: string) { 3 | let len = 0; 4 | for (let i = 0; i < str.length; i++) { 5 | if (str.charCodeAt(i) > 0 && str.charCodeAt(i) < 128) { 6 | len++; 7 | } else { 8 | len += 2; 9 | } 10 | } 11 | return len; 12 | } 13 | /** 字符串过长以...呈现 */ 14 | function ellipsisString(str: string, maxWidth: number, fontSize: number) { 15 | const fontWidth = fontSize * 1.3; // 字号+边距 16 | maxWidth = maxWidth * 2; // 需要根据自己项目调整 17 | const width = strLen(str) * fontWidth; 18 | const ellipsis = '…'; 19 | if (width > maxWidth) { 20 | const actualLen = Math.floor((maxWidth - 10) / fontWidth); 21 | const result = str.substring(0, actualLen) + ellipsis; 22 | return result; 23 | } 24 | return str; 25 | } 26 | 27 | export { 28 | strLen, 29 | ellipsisString, 30 | }; 31 | -------------------------------------------------------------------------------- /packages/viser-graph/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "es2015", 4 | "outDir": "es", 5 | "noUnusedLocals": true, 6 | "strict": true, 7 | "removeComments": true, 8 | "preserveConstEnums": true, 9 | "sourceMap": true, 10 | "moduleResolution": "node", 11 | "noImplicitAny": false, 12 | "declaration": false, 13 | "lib": [ 14 | "dom", 15 | "es2015" 16 | ] 17 | }, 18 | "include": [ 19 | "src/**/*" 20 | ], 21 | "exclude": [ 22 | "node_modules" 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /packages/viser-graph/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "error", 3 | "extends": [ 4 | "tslint:latest" 5 | ], 6 | "jsRules": {}, 7 | "rules": { 8 | "quotemark": [true, "single"], 9 | "no-console": [true, "log", "warn"], 10 | "object-literal-sort-keys": false 11 | }, 12 | "rulesDirectory": [] 13 | } 14 | -------------------------------------------------------------------------------- /packages/viser-graph/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpack = require('webpack'); 3 | const env = process.env.NODE_ENV; 4 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; 5 | 6 | let config = { 7 | mode: 'production', 8 | 9 | entry: './lib/index.js', 10 | 11 | output: { 12 | path: path.resolve(__dirname, 'umd'), 13 | filename: 'viser-graph.min.js', 14 | library: 'ViserGraph', 15 | libraryTarget: 'umd', 16 | }, 17 | 18 | resolve: { 19 | extensions: ['.js', '.json'], 20 | }, 21 | 22 | module: { 23 | rules: [{ 24 | test: /\.js?$/, 25 | exclude: /node_modules/, 26 | use: { 27 | loader: "babel-loader" 28 | } 29 | }] 30 | }, 31 | 32 | plugins: [], 33 | }; 34 | 35 | if (env === 'analyse') { 36 | config.plugins.push(new BundleAnalyzerPlugin()); 37 | } 38 | 39 | module.exports = config; 40 | -------------------------------------------------------------------------------- /packages/viser-ng/.babelrc.js: -------------------------------------------------------------------------------- 1 | const BABEL_ENV = process.env.BABEL_ENV 2 | const building = BABEL_ENV != undefined && BABEL_ENV !== 'cjs' 3 | 4 | const plugins = [ 5 | "@babel/plugin-proposal-export-default-from", 6 | "@babel/plugin-proposal-export-namespace-from", 7 | ["@babel/plugin-proposal-class-properties", { "loose": true }], 8 | "@babel/plugin-proposal-object-rest-spread", 9 | ]; 10 | 11 | if (BABEL_ENV === 'umd') { 12 | plugins.push('@babel/plugin-external-helpers'); 13 | } 14 | 15 | module.exports = { 16 | plugins: plugins, 17 | presets: [ 18 | [ "@babel/preset-env", { 19 | modules: building ? false : 'commonjs', 20 | targets: { 21 | "browsers": ["last 2 versions"] 22 | } 23 | } ] 24 | ], 25 | }; 26 | -------------------------------------------------------------------------------- /packages/viser-ng/README.md: -------------------------------------------------------------------------------- 1 | # viser-ng [![npm](https://img.shields.io/npm/v/viser-ng.svg)](https://www.npmjs.com/package/viser-ng) [![Dependency Status](https://david-dm.org/viserjs/viser-ng.svg?path=packages/viser-ng)](https://david-dm.org/viserjs/viser-ng.svg?path=packages/viser-ng) 2 | 3 | > A toolkit fit for data vis engineer (angular version). 4 | 5 | ## Install 6 | 7 | ```sh 8 | $ npm install --save viser-ng 9 | ``` 10 | 11 | ## Usage 12 | 13 | ```ts 14 | import 'zone.js'; 15 | import 'reflect-metadata'; 16 | import { Component, enableProdMode, NgModule } from '@angular/core'; 17 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 18 | import { BrowserModule } from '@angular/platform-browser'; 19 | import { ViserModule } from 'viser-ng'; 20 | const DataSet = require('@antv/data-set'); 21 | 22 | const sourceData = [ 23 | { month: 'Jan', Tokyo: 7.0, London: 3.9 }, 24 | { month: 'Feb', Tokyo: 6.9, London: 4.2 }, 25 | { month: 'Mar', Tokyo: 9.5, London: 5.7 }, 26 | { month: 'Apr', Tokyo: 14.5, London: 8.5 }, 27 | { month: 'May', Tokyo: 18.4, London: 11.9 }, 28 | { month: 'Jun', Tokyo: 21.5, London: 15.2 }, 29 | { month: 'Jul', Tokyo: 25.2, London: 17.0 }, 30 | { month: 'Aug', Tokyo: 26.5, London: 16.6 }, 31 | { month: 'Sep', Tokyo: 23.3, London: 14.2 }, 32 | { month: 'Oct', Tokyo: 18.3, London: 10.3 }, 33 | { month: 'Nov', Tokyo: 13.9, London: 6.6 }, 34 | { month: 'Dec', Tokyo: 9.6, London: 4.8 }, 35 | ]; 36 | 37 | const dv = new DataSet.View().source(sourceData); 38 | dv.transform({ 39 | type: 'fold', 40 | fields: ['Tokyo', 'London'], 41 | key: 'city', 42 | value: 'temperature', 43 | }); 44 | const data = dv.rows; 45 | 46 | const scale = [{ 47 | dataKey: 'percent', 48 | min: 0, 49 | formatter: '.2%', 50 | }]; 51 | 52 | @Component({ 53 | selector: '#mount', 54 | template: ` 55 |
56 | 57 | 58 | 59 | 60 | 61 |
62 | ` 63 | }) 64 | 65 | class AppComponent { 66 | forceFit: boolean = true; 67 | height: number = 400; 68 | data = data; 69 | scale = scale; 70 | } 71 | 72 | @NgModule({ 73 | declarations: [ 74 | AppComponent 75 | ], 76 | imports: [ 77 | BrowserModule, 78 | ViserModule 79 | ], 80 | providers: [], 81 | bootstrap: [ 82 | AppComponent 83 | ] 84 | }) 85 | export class AppModule { } 86 | platformBrowserDynamic().bootstrapModule(AppModule); 87 | ``` 88 | -------------------------------------------------------------------------------- /packages/viser-ng/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "viser-ng", 3 | "version": "2.5.2", 4 | "description": "viser-ng is angular of viser.", 5 | "repository": "viserjs/viser-ng", 6 | "license": "MIT", 7 | "authors": "DT-FE", 8 | "files": [ 9 | "lib", 10 | "es", 11 | "umd" 12 | ], 13 | "main": "lib/index.js", 14 | "module": "es/index.js", 15 | "types": "es/index.d.ts", 16 | "scripts": { 17 | "prepublish": "npm run build", 18 | "build": "npm run build:ts && npm run build:cjs && npm run build:umd", 19 | "build:ts": "rimraf es && ngc", 20 | "build:cjs": "rimraf lib && cross-env NODE_ENV=commonjs BABEL_ENV=cjs babel ./es -d lib", 21 | "build:umd": "rimraf umd && cross-env BABEL_ENV=umd webpack --config webpack.config.js", 22 | "clean": "git clean -fdX .", 23 | "lint": "tslint src", 24 | "analyse": "cross-env NODE_ENV=analyse webpack --progress --config webpack.config.js" 25 | }, 26 | "peerDependencies": { 27 | "@angular/common": "^8.2.11", 28 | "@angular/core": "^8.2.11", 29 | "reflect-metadata": "^0.1.13", 30 | "zone.js": "^0.10.2" 31 | }, 32 | "dependencies": { 33 | "@types/core-js": "*", 34 | "@types/node": "*", 35 | "rxjs": "^6.5.3", 36 | "viser": "^2.0.0" 37 | }, 38 | "devDependencies": { 39 | "@angular/common": "^8.2.11", 40 | "@angular/compiler": "^8.2.11", 41 | "@angular/compiler-cli": "^8.2.11", 42 | "@angular/core": "^8.2.11", 43 | "@babel/cli": "^7.6.4", 44 | "@babel/core": "^7.6.4", 45 | "@babel/plugin-external-helpers": "^7.2.0", 46 | "@babel/plugin-proposal-class-properties": "^7.5.5", 47 | "@babel/plugin-proposal-export-default-from": "^7.5.2", 48 | "@babel/plugin-proposal-export-namespace-from": "^7.5.2", 49 | "@babel/plugin-proposal-object-rest-spread": "^7.6.2", 50 | "@babel/polyfill": "^7.6.0", 51 | "@babel/preset-env": "^7.6.3", 52 | "@babel/runtime": "^7.6.3", 53 | "babel-loader": "^8.0.6", 54 | "colors": "^1.4.0", 55 | "cross-env": "^6.0.3", 56 | "gzip-size": "^5.1.1", 57 | "ora": "^4.0.2", 58 | "pretty-bytes": "^5.3.0", 59 | "rimraf": "^3.0.0", 60 | "tslint": "^5.20.0", 61 | "typescript": "<3.6.0", 62 | "webpack": "^4.41.2", 63 | "webpack-bundle-analyzer": "^3.6.0", 64 | "webpack-cli": "^3.3.9", 65 | "zone.js": "^0.8.5" 66 | }, 67 | "keywords": [ 68 | "g2", 69 | "chart", 70 | "angular", 71 | "datavis" 72 | ] 73 | } 74 | -------------------------------------------------------------------------------- /packages/viser-ng/src/chartService.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | function generateRandomNum() { 4 | return (Math.floor(new Date().getTime() + Math.random() * 10000)).toString(); 5 | } 6 | 7 | @Injectable() 8 | export class ChartContext { 9 | public viewId: string; 10 | public lastFacetId: string = ''; 11 | public config: any = {}; 12 | public views: any = {}; 13 | public facetviews: any = {}; 14 | public timer: any; 15 | public chart: any; 16 | public chartDivElement: any; 17 | 18 | constructor() { 19 | this.viewId = generateRandomNum(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/viser-ng/src/components/Brush.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input } from '@angular/core'; 2 | import { Chart } from '../Chart'; 3 | 4 | type eventFunc = (ev: any, chart: any) => void; 5 | 6 | @Component({ 7 | selector: 'v-brush', 8 | template: `
`, 9 | }) 10 | 11 | class Brush extends Chart { 12 | @Input() public canvas: any; 13 | @Input() public startPoint?: object; 14 | @Input() public brushing?: boolean; 15 | @Input() public dragging?: boolean; 16 | @Input() public brushShape?: any; 17 | @Input() public container?: any; 18 | @Input() public polygonPath?: string; 19 | @Input() public style?: object; 20 | @Input() public type?: string; 21 | @Input() public dragable?: boolean; 22 | @Input() public dragoffX?: number; 23 | @Input() public dragoffY?: number; 24 | @Input() public inPlot?: boolean; 25 | @Input() public xField?: string; 26 | @Input() public yField?: string; 27 | // @Input() public filter?: boolean; 28 | @Input() public onBrushstart?: eventFunc; 29 | @Input() public onBrushmove?: eventFunc; 30 | @Input() public onBrushend?: eventFunc; 31 | @Input() public onDragstart?: eventFunc; 32 | @Input() public onDragmove?: eventFunc; 33 | @Input() public onDragend?: eventFunc; 34 | } 35 | 36 | export { Brush }; 37 | -------------------------------------------------------------------------------- /packages/viser-ng/src/components/Coord.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input } from '@angular/core'; 2 | import { Chart } from '../Chart'; 3 | 4 | @Component({ 5 | selector: 'v-coord', 6 | template: `
`, 7 | }) 8 | 9 | class Coord extends Chart { 10 | @Input() public type?: 'polar' | 'theta' | 'helix' | 'rect'; 11 | @Input() public direction?: string; 12 | @Input() public radius?: number; 13 | @Input() public innerRadius?: number; 14 | @Input() public startAngle?: number; 15 | @Input() public endAngle?: number; 16 | @Input() public rotate?: number; 17 | } 18 | 19 | export { Coord }; 20 | -------------------------------------------------------------------------------- /packages/viser-ng/src/components/Facet.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input } from '@angular/core'; 2 | import { Chart } from '../Chart'; 3 | import * as IStyle from './Style'; 4 | 5 | interface IColTitleProps { 6 | offsetY?: number; 7 | style?: IStyle.ITextStyle; 8 | } 9 | 10 | interface IRowTitleProps { 11 | offsetX?: number; 12 | style?: IStyle.ITextStyle; 13 | } 14 | 15 | @Component({ 16 | selector: 'v-facet', 17 | template: `
`, 18 | }) 19 | class Facet extends Chart { 20 | @Input() public type?: string; 21 | @Input() public fields?: string[]; 22 | @Input() public cols?: number; 23 | @Input() public rows?: number; 24 | @Input() public colField?: string | string[]; 25 | @Input() public rowField?: string | string[]; 26 | @Input() public colValue?: number; 27 | @Input() public rowValue?: number; 28 | @Input() public colIndex?: number; 29 | @Input() public rowIndex?: number; 30 | @Input() public showTitle?: boolean; 31 | @Input() public colTitle?: IColTitleProps; 32 | @Input() public rowTitle?: IRowTitleProps; 33 | @Input() public autoSetAxis?: boolean; 34 | @Input() public padding?: number | number[]; 35 | @Input() public transpose?: boolean; 36 | @Input() public lineSmooth?: boolean; 37 | @Input() public line?: IStyle.ILineStyle; 38 | @Input() public views?: any; 39 | @Input() public eachView?: (views: any, facet: any) => void; 40 | } 41 | 42 | export { Facet }; 43 | -------------------------------------------------------------------------------- /packages/viser-ng/src/components/Guide.ts: -------------------------------------------------------------------------------- 1 | 2 | import { Component, Input } from '@angular/core'; 3 | import { Chart } from '../Chart'; 4 | import * as Style from './Style'; 5 | 6 | type func = () => void; 7 | type eventFunc = (ev: any, chart: any) => void; 8 | 9 | interface ILineText { 10 | position?: string | number; 11 | autoRotate?: number; 12 | style?: Style.ILineStyle; 13 | content?: string; 14 | offsetX?: number; 15 | offsetY?: number; 16 | } 17 | 18 | interface IRegionStyle { 19 | lineWidth?: number; 20 | fill?: string; 21 | fillOpacity?: number; 22 | stroke?: string; 23 | } 24 | 25 | @Component({ 26 | selector: 'v-guide', 27 | template: `
`, 28 | }) 29 | class Guide extends Chart { 30 | @Input() public type?: 'line' | 'text' | 'image' | 'region' | 'arc' | 'regionFilter' | 'dataMarker' | 'dataRegion'; 31 | @Input() public top?: boolean; 32 | @Input() public zIndex?: number; 33 | @Input() public start?: object | Array | func; 34 | @Input() public end?: object | Array | func; 35 | @Input() public position?: object | Array | func; 36 | @Input() public lineStyle?: Style.ILineStyle; 37 | @Input() public content?: string; 38 | @Input() public style?: object | Style.ITextStyle | IRegionStyle; 39 | @Input() public text?: ILineText; 40 | @Input() public src?: string; 41 | @Input() public width?: number; 42 | @Input() public height?: number; 43 | @Input() public offsetX?: number; 44 | @Input() public offsetY?: number; 45 | @Input() public alignX?: string; 46 | @Input() public alignY?: string; 47 | @Input() public html?: string; 48 | @Input() public color?: string; 49 | @Input() public apply?: string[]; 50 | @Input() public lineLength?: number; 51 | @Input() public direction?: string; 52 | @Input() public display?: object; 53 | @Input() public onMouseDown?: eventFunc; 54 | @Input() public onMouseMove?: eventFunc; 55 | @Input() public onMouseLeave?: eventFunc; 56 | @Input() public onMouseUp?: eventFunc; 57 | @Input() public onClick?: eventFunc; 58 | @Input() public onDblClick?: eventFunc; 59 | @Input() public onTouchStart?: eventFunc; 60 | @Input() public onTouchMove?: eventFunc; 61 | @Input() public onTouchEnd?: eventFunc; 62 | } 63 | 64 | export { Guide }; 65 | -------------------------------------------------------------------------------- /packages/viser-ng/src/components/Style.ts: -------------------------------------------------------------------------------- 1 | export interface ITextStyle { 2 | fontSize?: number | string; 3 | textAlign?: string; 4 | fill?: string; 5 | fontWeight?: string; 6 | textBaseline?: string; 7 | rotate?: number; 8 | shadowBlur?: number; 9 | shadowColor?: string; 10 | } 11 | 12 | export interface ILineStyle { 13 | stroke?: string; 14 | strokeOpacity?: string; 15 | lineWidth?: number; 16 | lineHeight?: number; 17 | lineDash?: number[]; 18 | } 19 | -------------------------------------------------------------------------------- /packages/viser-ng/src/components/Tooltip.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input } from '@angular/core'; 2 | import { Chart } from '../Chart'; 3 | import * as IStyle from './Style'; 4 | 5 | type eventFunc = (ev: any, chart: any) => void; 6 | 7 | type triggerType = 'mousemove' | 'click' | 'none'; 8 | 9 | interface ICrosshairs { 10 | type?: string; 11 | style?: IStyle.ILineStyle; 12 | } 13 | 14 | @Component({ 15 | selector: 'v-tooltip', 16 | template: `
`, 17 | }) 18 | class Tooltip extends Chart { 19 | @Input() public x?: number; 20 | @Input() public y?: number; 21 | @Input() public items?: object[]; 22 | @Input() public show?: boolean; 23 | 24 | @Input() public triggerOn?: triggerType; 25 | @Input() public showTitle?: boolean; 26 | @Input() public title?: string; 27 | @Input() public crosshairs?: boolean | string | ICrosshairs; 28 | @Input() public offset?: number; 29 | @Input() public inPlot?: boolean; 30 | @Input() public follow?: boolean; 31 | @Input() public shared?: boolean; 32 | @Input() public enterable?: boolean; 33 | @Input() public position?: string; 34 | @Input() public hideMarkers?: boolean; 35 | @Input() public containerTpl?: string; 36 | @Input() public itemTpl?: string; 37 | @Input() public g2Tooltip?: any; 38 | @Input() public g2TooltipTitle?: any; 39 | @Input() public g2TooltipList?: any; 40 | @Input() public g2TooltipListItem?: any; 41 | @Input() public g2TooltipMarker?: any; 42 | 43 | @Input() public htmlContent?: any; 44 | @Input() public useHtml?: boolean; 45 | @Input() public type?: string; 46 | 47 | @Input() public onShow?: eventFunc; 48 | @Input() public onHide?: eventFunc; 49 | @Input() public onChange?: eventFunc; 50 | 51 | @Input() public defaultPoint?: any; 52 | 53 | // Deprecated 54 | @Input() public timeStamp?: number; 55 | @Input() public plotRange?: object; 56 | } 57 | 58 | export { Tooltip }; 59 | -------------------------------------------------------------------------------- /packages/viser-ng/src/components/View.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input } from '@angular/core'; 2 | import { IFilter, IScale } from 'viser'; 3 | import { Chart } from '../Chart'; 4 | 5 | @Component({ 6 | selector: 'v-view', 7 | template: `
`, 8 | }) 9 | class View extends Chart { 10 | @Input() public data?: any; 11 | @Input() public dataPre?: { 12 | connector?: string; 13 | source?: any; 14 | transform?: object[] | object; 15 | }; 16 | @Input() public scale?: object[]; 17 | @Input() public dataView?: any; 18 | @Input() public start?: any; 19 | @Input() public end?: any; 20 | } 21 | 22 | // tslint:disable-next-line:max-classes-per-file 23 | @Component({ 24 | selector: 'v-facet-view', 25 | template: `
`, 26 | }) 27 | class FacetView extends Chart { 28 | @Input() public dataPre?: { 29 | connector?: string; 30 | source?: any; 31 | transform?: object[] | object; 32 | }; 33 | @Input() public dataView?: any; 34 | @Input() public scale?: IScale; 35 | @Input() public filter?: IFilter; 36 | } 37 | 38 | export { View, FacetView }; 39 | -------------------------------------------------------------------------------- /packages/viser-ng/src/components/index.ts: -------------------------------------------------------------------------------- 1 | import { Axis } from './Axis'; 2 | import { Brush } from './Brush'; 3 | import { Coord } from './Coord'; 4 | import { Facet } from './Facet'; 5 | import { Guide } from './Guide'; 6 | import { Legend } from './Legend'; 7 | import { Area, Bar, Box, Candle, Contour, DashLine, DodgeBar, DodgeInterval, Edge, ErrorBar, Funnel, Heatmap, 8 | Interval, JitterPoint, Line, Path, Pie, Point, Polygon, Pyramid, Sankey, Schema, Sector, Series, SmoothArea, 9 | SmoothLine, StackArea, StackBar, StackInterval, Venn } from './Series'; 10 | import { Tooltip } from './Tooltip'; 11 | import { FacetView, View } from './View'; 12 | 13 | export { 14 | Axis, 15 | Brush, 16 | Coord, 17 | Facet, 18 | Guide, 19 | Legend, 20 | Tooltip, 21 | View, 22 | FacetView, 23 | Series, 24 | Pie, 25 | Sector, 26 | Line, 27 | SmoothLine, 28 | DashLine, 29 | Area, 30 | StackArea, 31 | SmoothArea, 32 | Bar, 33 | StackBar, 34 | DodgeBar, 35 | Interval, 36 | StackInterval, 37 | DodgeInterval, 38 | Point, 39 | Funnel, 40 | Pyramid, 41 | Schema, 42 | Box, 43 | Candle, 44 | Polygon, 45 | Contour, 46 | Heatmap, 47 | Edge, 48 | Sankey, 49 | ErrorBar, 50 | JitterPoint, 51 | Path, 52 | Venn, 53 | }; 54 | -------------------------------------------------------------------------------- /packages/viser-ng/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './module'; 2 | -------------------------------------------------------------------------------- /packages/viser-ng/src/module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { NgModule } from '@angular/core'; 3 | import * as viser from 'viser'; 4 | import { Chart } from './Chart'; 5 | import { Area, Axis, Bar, Box, Brush, Candle, Contour, Coord, DashLine, DodgeBar, DodgeInterval, 6 | Edge, ErrorBar, Facet, FacetView, Funnel, Guide, Heatmap, 7 | Interval, JitterPoint, Legend, Line, Path, Pie, Point, Polygon, 8 | Pyramid, Sankey, Schema, Sector, Series, SmoothArea, SmoothLine, 9 | StackArea, StackBar, StackInterval, Tooltip, Venn, View } from './components/index'; 10 | import { LiteChart } from './LiteChart'; 11 | import { PluginComponent } from './plugins/Plugin'; 12 | import { Slider } from './plugins/Slider'; 13 | 14 | @NgModule({ 15 | imports: [CommonModule], 16 | declarations: [ 17 | Chart, 18 | LiteChart, 19 | Axis, 20 | Brush, 21 | Coord, 22 | Facet, 23 | Guide, 24 | Legend, 25 | Tooltip, 26 | View, 27 | FacetView, 28 | Series, 29 | Pie, 30 | Sector, 31 | Line, 32 | SmoothLine, 33 | DashLine, 34 | Area, 35 | StackArea, 36 | SmoothArea, 37 | Bar, 38 | StackBar, 39 | DodgeBar, 40 | Point, 41 | Funnel, 42 | Pyramid, 43 | Schema, 44 | Box, 45 | Candle, 46 | Polygon, 47 | Contour, 48 | Heatmap, 49 | Edge, 50 | Sankey, 51 | ErrorBar, 52 | JitterPoint, 53 | StackInterval, 54 | DodgeInterval, 55 | Interval, 56 | Path, 57 | Venn, 58 | PluginComponent, 59 | Slider, 60 | ], 61 | exports: [ 62 | Chart, 63 | LiteChart, 64 | Axis, 65 | Brush, 66 | Coord, 67 | Facet, 68 | Guide, 69 | Legend, 70 | Tooltip, 71 | View, 72 | FacetView, 73 | Series, 74 | Pie, 75 | Sector, 76 | Line, 77 | SmoothLine, 78 | DashLine, 79 | Area, 80 | StackArea, 81 | SmoothArea, 82 | Bar, 83 | StackBar, 84 | DodgeBar, 85 | Point, 86 | Funnel, 87 | Pyramid, 88 | Schema, 89 | Box, 90 | Candle, 91 | Polygon, 92 | Contour, 93 | Heatmap, 94 | Edge, 95 | Sankey, 96 | ErrorBar, 97 | JitterPoint, 98 | StackInterval, 99 | DodgeInterval, 100 | Interval, 101 | Path, 102 | Venn, 103 | PluginComponent, 104 | Slider, 105 | ], 106 | }) 107 | export class ViserModule { 108 | } 109 | export const registerAnimation = viser.registerAnimation; 110 | export const registerShape = viser.registerShape; 111 | export const Global = viser.Global; 112 | -------------------------------------------------------------------------------- /packages/viser-ng/src/plugins/Plugin.ts: -------------------------------------------------------------------------------- 1 | import { AfterViewInit, Component, OnChanges, SimpleChanges, ViewContainerRef } from '@angular/core'; 2 | import * as viser from 'viser'; 3 | import { PluginContext } from './PluginService'; 4 | 5 | @Component({ 6 | providers: [PluginContext], 7 | selector: 'v-plugin', 8 | template: `
9 | 10 |
`, 11 | }) 12 | export class PluginComponent implements AfterViewInit, OnChanges { 13 | public context: PluginContext; 14 | public vcRef: any; 15 | private config: any = {}; 16 | 17 | constructor(context: PluginContext, vcRef: ViewContainerRef) { 18 | this.context = context; 19 | this.vcRef = vcRef; 20 | } 21 | 22 | public ngAfterViewInit() { 23 | this.initPlugin(); 24 | } 25 | 26 | public ngOnChanges(changes: SimpleChanges) { 27 | this.initPlugin(); 28 | } 29 | 30 | private combineContentConfig(displayName: string, props: any, config: any) { 31 | const nameLowerCase = displayName.toLowerCase(); 32 | 33 | config[nameLowerCase] = props; 34 | } 35 | 36 | private getProps(allProps: any) { 37 | const strippingProperties = ['chartDiv', 'combineContentConfig', 'config', 'constructor', 'context', 'vcRef', 38 | 'getProps', 'initPlugin', 'renderPlugin', 39 | 'ngOnInit', 'ngAfterViewInit', 'ngOnChanges']; 40 | if (allProps) { 41 | const properties: { 42 | [key: string]: string, 43 | } = {}; 44 | for (const key in allProps) { 45 | if (strippingProperties.indexOf(key) === -1) { 46 | properties[key] = allProps[key]; 47 | } 48 | } 49 | return properties; 50 | } 51 | 52 | return allProps; 53 | } 54 | 55 | private initPlugin() { 56 | const name = this.constructor.name; 57 | const props = this.getProps(this); 58 | this.config = this.context.config; 59 | 60 | if (name === 'PluginComponent') { 61 | this.renderPlugin(true); 62 | } else if (name === 'Slider') { 63 | // reserve this logical to avoid not set container attribute 64 | props.container = this.context.container; 65 | this.combineContentConfig(name, props, this.config); 66 | } 67 | } 68 | 69 | private renderPlugin(rerender?: boolean) { 70 | viser.Plugin(this.config); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /packages/viser-ng/src/plugins/PluginService.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | function generateRandomNum() { 4 | return (Math.floor(new Date().getTime() + Math.random() * 10000)).toString(); 5 | } 6 | 7 | @Injectable() 8 | export class PluginContext { 9 | public config: any = {}; 10 | public container: string = 'viser-slider-' + generateRandomNum(); 11 | } 12 | -------------------------------------------------------------------------------- /packages/viser-ng/src/plugins/Slider.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input } from '@angular/core'; 2 | import { PluginComponent } from './Plugin'; 3 | 4 | @Component({ 5 | selector: 'v-slider', 6 | template: `
`, 7 | }) 8 | class Slider extends PluginComponent { 9 | @Input() public xAxis: any; 10 | @Input() public yAxis: any; 11 | @Input() public data: any; 12 | @Input() public container: any; 13 | @Input() public width?: number | string; 14 | @Input() public height?: number | string; 15 | @Input() public padding?: number | number[]; 16 | @Input() public start?: string; 17 | @Input() public end?: string; 18 | @Input() public minSpan?: number; 19 | @Input() public maxSpan?: number; 20 | @Input() public scales?: any; 21 | @Input() public fillerStyle?: any; 22 | @Input() public backgroundStyle?: any; 23 | @Input() public textStyle?: any; 24 | @Input() public handleStyle?: any; 25 | @Input() public backgroundChart?: any; 26 | @Input() public onChange?: any; 27 | } 28 | 29 | export { Slider }; 30 | -------------------------------------------------------------------------------- /packages/viser-ng/src/typed/IRChart.ts: -------------------------------------------------------------------------------- 1 | import { IChart, ICoord, IFilter, IScale } from 'viser'; 2 | 3 | interface ISChartProps { 4 | data?: any; 5 | viewId?: string; 6 | coord?: ICoord; 7 | filter?: IFilter; 8 | scale?: IScale; 9 | start?: any; 10 | end?: any; 11 | } 12 | 13 | type IRChart = IChart & ISChartProps; 14 | 15 | export { IRChart }; 16 | -------------------------------------------------------------------------------- /packages/viser-ng/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "es2015", 4 | "moduleResolution": "node", 5 | "outDir": "es", 6 | "emitDecoratorMetadata": true, 7 | "declaration": true, 8 | "noImplicitAny": true, 9 | "noUnusedLocals": true, 10 | "strict": true, 11 | "removeComments": true, 12 | "preserveConstEnums": true, 13 | "experimentalDecorators": true, 14 | "skipLibCheck": true, 15 | "allowJs": false, 16 | "sourceMap": true, 17 | "lib": [ 18 | "dom", 19 | "es2017" 20 | ] 21 | }, 22 | "angularCompilerOptions": { 23 | "genDir": "es", 24 | "skipTemplateCodegen": true, 25 | "debug": false 26 | }, 27 | "include": ["src/**/*"], 28 | "exclude": ["node_modules"] 29 | } 30 | -------------------------------------------------------------------------------- /packages/viser-ng/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "error", 3 | "extends": [ 4 | "tslint:latest" 5 | ], 6 | "jsRules": {}, 7 | "rules": { 8 | "quotemark": [true, "single"], 9 | "no-console": [true, "log", "warn"], 10 | "object-literal-sort-keys": false 11 | }, 12 | "rulesDirectory": [] 13 | } 14 | -------------------------------------------------------------------------------- /packages/viser-ng/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpack = require('webpack'); 3 | const env = process.env.NODE_ENV; 4 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; 5 | 6 | let config = { 7 | mode: 'production', 8 | 9 | entry: './lib/index', 10 | 11 | output: { 12 | path: path.resolve(__dirname, 'umd'), 13 | filename: 'viser-ng.min.js', 14 | library: 'ViserNg', 15 | libraryTarget: 'umd', 16 | }, 17 | 18 | resolve: { 19 | extensions: ['.js', '.json'] 20 | }, 21 | 22 | externals: {}, 23 | 24 | module: { 25 | rules: [{ 26 | test: /\.js?$/, 27 | exclude: /node_modules/, 28 | use: { 29 | loader: "babel-loader" 30 | } 31 | }], 32 | }, 33 | 34 | plugins: [], 35 | }; 36 | 37 | if (env === 'analyse') { 38 | config.plugins.push(new BundleAnalyzerPlugin()); 39 | } 40 | 41 | module.exports = config; 42 | -------------------------------------------------------------------------------- /packages/viser-react/.babelrc.js: -------------------------------------------------------------------------------- 1 | const BABEL_ENV = process.env.BABEL_ENV 2 | const building = BABEL_ENV != undefined && BABEL_ENV !== 'cjs' 3 | 4 | const plugins = [ 5 | "@babel/plugin-proposal-export-default-from", 6 | "@babel/plugin-proposal-export-namespace-from", 7 | ["@babel/plugin-proposal-class-properties", { "loose": true }], 8 | "@babel/plugin-proposal-object-rest-spread", 9 | ]; 10 | 11 | if (BABEL_ENV === 'umd') { 12 | plugins.push('@babel/plugin-external-helpers'); 13 | } 14 | 15 | module.exports = { 16 | plugins: plugins, 17 | presets: [ 18 | [ "@babel/preset-env", { 19 | modules: building ? false : 'commonjs', 20 | targets: { 21 | "browsers": ["last 2 versions"] 22 | } 23 | } ], 24 | '@babel/preset-react' 25 | ], 26 | }; 27 | -------------------------------------------------------------------------------- /packages/viser-react/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 80, 3 | "tabWidth": 2, 4 | "useTabs": false, 5 | "semi": true, 6 | "singleQuote": true, 7 | "trailingComma": "es5", 8 | "bracketSpacing": true 9 | } 10 | -------------------------------------------------------------------------------- /packages/viser-react/README.md: -------------------------------------------------------------------------------- 1 | # viser-react [![npm](https://img.shields.io/npm/v/viser-react.svg)](https://www.npmjs.com/package/viser-react) [![Dependency Status](https://david-dm.org/viserjs/viser-react.svg?path=packages/viser-react)](https://david-dm.org/viserjs/viser-react.svg?path=packages/viser-react) 2 | 3 | > A toolkit fit for data vis engineer (react version). 4 | 5 | ## Install 6 | 7 | ```sh 8 | $ npm install --save viser-react 9 | ``` 10 | 11 | ## Usage 12 | 13 | ```jsx 14 | import { Chart, SmoothLine, Point, Tooltip, Legend, Axis } from 'viser-react'; 15 | import * as ReactDOM from 'react-dom'; 16 | import * as React from 'react'; 17 | const DataSet = require('@antv/data-set'); 18 | 19 | const sourceData = [ 20 | { month: 'Jan', Tokyo: 7.0, London: 3.9 }, 21 | { month: 'Feb', Tokyo: 6.9, London: 4.2 }, 22 | { month: 'Mar', Tokyo: 9.5, London: 5.7 }, 23 | { month: 'Apr', Tokyo: 14.5, London: 8.5 }, 24 | { month: 'May', Tokyo: 18.4, London: 11.9 }, 25 | { month: 'Jun', Tokyo: 21.5, London: 15.2 }, 26 | { month: 'Jul', Tokyo: 25.2, London: 17.0 }, 27 | { month: 'Aug', Tokyo: 26.5, London: 16.6 }, 28 | { month: 'Sep', Tokyo: 23.3, London: 14.2 }, 29 | { month: 'Oct', Tokyo: 18.3, London: 10.3 }, 30 | { month: 'Nov', Tokyo: 13.9, London: 6.6 }, 31 | { month: 'Dec', Tokyo: 9.6, London: 4.8 }, 32 | ]; 33 | 34 | const dv = new DataSet.View().source(sourceData); 35 | dv.transform({ 36 | type: 'fold', 37 | fields: ['Tokyo', 'London'], 38 | key: 'city', 39 | value: 'temperature', 40 | }); 41 | const data = dv.rows; 42 | 43 | const scale = [{ 44 | dataKey: 'percent', 45 | min: 0, 46 | formatter: '.2%', 47 | }]; 48 | 49 | class App extends React.Component { 50 | constructor(props) { 51 | super(props); 52 | } 53 | 54 | render() { 55 | return ( 56 |
57 | 58 | 59 | 60 | 61 | 62 | 63 |
64 | ); 65 | } 66 | } 67 | 68 | ReactDOM.render(, document.getElementById('mountNode')); 69 | ``` 70 | -------------------------------------------------------------------------------- /packages/viser-react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "viser-react", 3 | "version": "2.4.8", 4 | "description": "viser-react is react of viser.", 5 | "repository": "viserjs/viser-react", 6 | "license": "MIT", 7 | "authors": "DT-FE", 8 | "files": [ 9 | "umd", 10 | "es", 11 | "lib" 12 | ], 13 | "main": "lib/index.js", 14 | "module": "es/index.js", 15 | "types": "es/index.d.ts", 16 | "scripts": { 17 | "prepare": "npm run build", 18 | "build": "npm run build:ts && npm run build:cjs && npm run build:umd", 19 | "build:ts": "rimraf es && tsc", 20 | "build:cjs": "rimraf lib && cross-env NODE_ENV=commonjs BABEL_ENV=cjs babel ./es -d lib", 21 | "build:umd": "rimraf umd && cross-env BABEL_ENV=umd webpack --config webpack.config.js", 22 | "clean": "git clean -fdX .", 23 | "lint": "tslint src/**/*", 24 | "analyse": "cross-env NODE_ENV=analyse webpack --progress --config webpack.config.js" 25 | }, 26 | "peerDependencies": { 27 | "react": ">15", 28 | "react-dom": ">15" 29 | }, 30 | "dependencies": { 31 | "@types/node": "*", 32 | "@types/prop-types": "*", 33 | "babel-loader": "^8.0.6", 34 | "prop-types": "^15.6.0", 35 | "viser": "^2.0.0" 36 | }, 37 | "devDependencies": { 38 | "@types/react": "*", 39 | "@types/react-dom": "*", 40 | "@babel/cli": "^7.1.0", 41 | "@babel/core": "^7.0.0", 42 | "@babel/plugin-proposal-class-properties": "^7.0.0", 43 | "@babel/plugin-proposal-export-default-from": "^7.0.0", 44 | "@babel/plugin-proposal-export-namespace-from": "^7.0.0", 45 | "@babel/plugin-proposal-object-rest-spread": "^7.0.0", 46 | "@babel/plugin-external-helpers": "^7.0.0", 47 | "@babel/polyfill": "^7.0.0", 48 | "@babel/preset-env": "^7.0.0", 49 | "@babel/preset-react": "^7.0.0", 50 | "@babel/runtime": "^7.0.0", 51 | "colors": "^1.1.2", 52 | "cross-env": "^5.2.0", 53 | "gzip-size": "^4.0.0", 54 | "ora": "^1.3.0", 55 | "pretty-bytes": "^4.0.2", 56 | "react": "^16.0.0", 57 | "react-dom": "^16.0.0", 58 | "rimraf": "^2.6.2", 59 | "tslint": "^5.5.0", 60 | "typescript": "~3.2.0", 61 | "webpack": "^4.20.0", 62 | "webpack-bundle-analyzer": "^3.6.0", 63 | "webpack-cli": "^3.1.0" 64 | }, 65 | "keywords": [ 66 | "g2", 67 | "chart", 68 | "react", 69 | "datavis" 70 | ] 71 | } 72 | -------------------------------------------------------------------------------- /packages/viser-react/src/components/Facet.tsx: -------------------------------------------------------------------------------- 1 | import * as PropTypes from 'prop-types'; 2 | import * as React from 'react'; 3 | import * as ReactDOM from 'react-dom'; 4 | import { IFacet } from 'viser'; 5 | 6 | const isReact16 = (ReactDOM as any).createPortal !== undefined; 7 | 8 | export default class Facet extends React.Component { 9 | public static contextTypes = { 10 | centralizedUpdates: PropTypes.func, 11 | hasInViews: PropTypes.bool, 12 | viewId: PropTypes.string, 13 | }; 14 | 15 | public displayName = 'Facet'; 16 | 17 | constructor(props: IFacet) { 18 | super(props); 19 | } 20 | 21 | public componentDidUpdate() { 22 | this.context.centralizedUpdates(this); 23 | } 24 | 25 | public componentDidMount() { 26 | this.context.centralizedUpdates(this); 27 | } 28 | 29 | public render() { 30 | if (!this.props.children) { 31 | return null; 32 | } 33 | 34 | if (isReact16) { 35 | return this.props.children as React.ReactElement; 36 | } else { 37 | return React.Children.only(this.props.children); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /packages/viser-react/src/components/FacetView.tsx: -------------------------------------------------------------------------------- 1 | import * as PropTypes from 'prop-types'; 2 | import * as React from 'react'; 3 | import * as ReactDOM from 'react-dom'; 4 | import { IView } from 'viser'; 5 | 6 | const isReact16 = (ReactDOM as any).createPortal !== undefined; 7 | 8 | function generateRandomNum() { 9 | return (Math.floor(new Date().getTime() + Math.random() * 10000)).toString(); 10 | } 11 | 12 | export default class FacetView extends React.Component { 13 | public static childContextTypes = { 14 | hasInViews: PropTypes.bool, 15 | viewId: PropTypes.string, 16 | viewType: PropTypes.string, 17 | }; 18 | 19 | public static contextTypes = { 20 | centralizedUpdates: PropTypes.func, 21 | hasInViews: PropTypes.bool, 22 | viewType: PropTypes.string, 23 | }; 24 | 25 | public displayName = 'FacetView'; 26 | 27 | constructor(props: IView) { 28 | super(props); 29 | 30 | this.state = { 31 | hasInViews: true, 32 | viewId: this.props.viewId || generateRandomNum(), 33 | viewType: 'facet', 34 | }; 35 | } 36 | 37 | public getChildContext() { 38 | return { 39 | hasInViews: this.state.hasInViews, 40 | viewId: this.state.viewId, 41 | viewType: this.state.viewType, 42 | }; 43 | } 44 | 45 | public componentDidUpdate() { 46 | this.context.centralizedUpdates(this); 47 | } 48 | 49 | public componentDidMount() { 50 | this.context.centralizedUpdates(this); 51 | } 52 | 53 | public render() { 54 | if (isReact16) { 55 | return this.props.children as React.ReactElement; 56 | } else { 57 | return React.Children.only(this.props.children); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /packages/viser-react/src/components/View.tsx: -------------------------------------------------------------------------------- 1 | import * as PropTypes from 'prop-types'; 2 | import * as React from 'react'; 3 | import * as ReactDOM from 'react-dom'; 4 | import { IView } from 'viser'; 5 | 6 | const isReact16 = (ReactDOM as any).createPortal !== undefined; 7 | 8 | function generateRandomNum() { 9 | return (Math.floor(new Date().getTime() + Math.random() * 10000)).toString(); 10 | } 11 | 12 | export default class View extends React.Component { 13 | public static childContextTypes = { 14 | hasInViews: PropTypes.bool, 15 | viewId: PropTypes.string, 16 | }; 17 | 18 | public static contextTypes = { 19 | centralizedUpdates: PropTypes.func, 20 | hasInViews: PropTypes.bool, 21 | }; 22 | 23 | public displayName = 'View'; 24 | 25 | constructor(props: IView) { 26 | super(props); 27 | 28 | this.state = { 29 | hasInViews: true, 30 | viewId: this.props.viewId || generateRandomNum(), 31 | }; 32 | } 33 | 34 | public getChildContext() { 35 | return { 36 | hasInViews: this.state.hasInViews, 37 | viewId: this.state.viewId, 38 | }; 39 | } 40 | 41 | public componentDidUpdate() { 42 | this.context.centralizedUpdates(this); 43 | } 44 | 45 | public componentDidMount() { 46 | this.context.centralizedUpdates(this); 47 | } 48 | 49 | public render() { 50 | if (isReact16) { 51 | return this.props.children as React.ReactElement; 52 | } else { 53 | return React.Children.only(this.props.children); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /packages/viser-react/src/index.tsx: -------------------------------------------------------------------------------- 1 | import * as viser from 'viser'; 2 | import { Area, Axis, Bar, Box, Brush, Candle, Contour, Coord, 3 | DashLine, DodgeBar, DodgeInterval, Edge, Funnel, Guide, Heatmap, 4 | Interval, JitterPoint, Legend, Line, Path, Pie, 5 | Point, Polygon, Pyramid, Sankey, Schema, Sector, Series, SmoothArea, SmoothLine, 6 | StackArea, StackBar, StackInterval, StackLine, Tooltip, Venn } from './components/SubComponent'; 7 | 8 | import { Slider } from './plugins/SubPlugin'; 9 | 10 | export const registerAnimation = viser.registerAnimation; 11 | export const registerShape = viser.registerShape; 12 | export const Global = viser.Global; 13 | 14 | export { default as Chart } from './components/Chart'; 15 | export { default as View } from './components/View'; 16 | export { default as FacetView } from './components/FacetView'; 17 | export { default as Facet } from './components/Facet'; 18 | export { default as LiteChart } from './components/LiteChart'; 19 | 20 | export { 21 | Coord, Tooltip, Legend, Guide, Axis, Series, Brush, Line, 22 | Pie, Sector, SmoothLine, DashLine, Area, StackArea, SmoothArea, 23 | Bar, StackBar, DodgeBar, Interval, StackInterval, DodgeInterval, 24 | Point, Funnel, Pyramid, Schema, Box, Candle, Polygon, Contour, Heatmap, 25 | Edge, Sankey, JitterPoint, Path, Venn, StackLine, 26 | }; 27 | 28 | export { default as Plugin } from './plugins/plugin'; 29 | export { Slider }; 30 | -------------------------------------------------------------------------------- /packages/viser-react/src/plugins/SubPlugin.tsx: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | import * as PropTypes from 'prop-types'; 3 | import * as React from 'react'; 4 | 5 | import { ISlider } from 'viser'; 6 | 7 | class Props { 8 | container?: string; 9 | } 10 | 11 | class SubPlugin extends React.Component { 12 | public static childContextTypes = { 13 | container: PropTypes.string, 14 | }; 15 | 16 | public static contextTypes = { 17 | centralizedUpdates: PropTypes.func, 18 | }; 19 | 20 | public displayName = 'SubPlugin'; 21 | 22 | constructor(props: Props & T) { 23 | super(props); 24 | this.state = { 25 | container: props.container, 26 | }; 27 | } 28 | 29 | public getChildContext() { 30 | return { 31 | container: this.state.container, 32 | }; 33 | } 34 | 35 | public componentDidUpdate() { 36 | this.context.centralizedUpdates(this); 37 | } 38 | 39 | public componentDidMount() { 40 | this.context.centralizedUpdates(this); 41 | } 42 | 43 | public render() { 44 | const container = this.state.container; 45 | return
as React.ReactElement; 46 | } 47 | } 48 | 49 | export class Slider extends SubPlugin { public displayName = 'Slider'; } 50 | -------------------------------------------------------------------------------- /packages/viser-react/src/plugins/plugin.tsx: -------------------------------------------------------------------------------- 1 | import * as PropTypes from 'prop-types'; 2 | import * as React from 'react'; 3 | import * as viser from 'viser'; 4 | 5 | export default class PluginComponent extends React.Component { 6 | public static childContextTypes = { 7 | centralizedUpdates: PropTypes.func, 8 | }; 9 | 10 | public container: any; 11 | public config: any = {}; 12 | public plugins: any = null; 13 | 14 | public getChildContext() { 15 | return { 16 | centralizedUpdates: this.centralizedUpdates, 17 | }; 18 | } 19 | 20 | public combineContentConfig(displayName: string, props: any, config: any) { 21 | const nameLowerCase = displayName.toLowerCase(); 22 | 23 | config[nameLowerCase] = props; 24 | } 25 | 26 | public centralizedUpdates = (unit: any) => { 27 | const config = this.config; 28 | let props = unit.props; 29 | const displayName = unit.displayName; 30 | 31 | if (displayName === 'Slider') { 32 | const container = props.container; 33 | if (!container || !document.getElementById(container)) { 34 | props = { 35 | ...props, 36 | container: unit.state.containerId, 37 | }; 38 | } 39 | } 40 | 41 | this.combineContentConfig( 42 | displayName, 43 | props, 44 | config, 45 | ); 46 | 47 | this.updateSliderInstance(config); 48 | } 49 | 50 | public updateSliderInstance(config: any) { 51 | if (!this.plugins) { 52 | this.plugins = viser.Plugin(config); 53 | } 54 | if (this.plugins && this.plugins.slider && config.slider) { 55 | this.plugins = viser.Plugin(config); 56 | } 57 | 58 | } 59 | 60 | public clearConfigData() { 61 | this.config = {}; 62 | } 63 | 64 | public portalRef = (container: any) => { 65 | if (!this.container) { 66 | this.container = container; 67 | } 68 | } 69 | 70 | public render() { 71 | return
{this.props.children}
; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /packages/viser-react/src/typed/IRChart.ts: -------------------------------------------------------------------------------- 1 | import { IChart, ICoord, IFilter, IScale } from 'viser'; 2 | 3 | interface ISChartProps { 4 | data?: any; 5 | viewId?: string; 6 | coord?: ICoord; 7 | scale?: IScale; 8 | filter?: IFilter; 9 | start?: any; 10 | end?: any; 11 | } 12 | 13 | type IRChart = IChart & ISChartProps; 14 | 15 | export default IRChart; 16 | -------------------------------------------------------------------------------- /packages/viser-react/src/typed/IRLiteChart.ts: -------------------------------------------------------------------------------- 1 | import { IMain } from 'viser'; 2 | 3 | interface ISLite { 4 | pie?: boolean; 5 | sector?: boolean; 6 | line?: boolean; 7 | smoothLine?: boolean; 8 | dashLine?: boolean; 9 | area?: boolean; 10 | stackArea?: boolean; 11 | smoothArea?: boolean; 12 | bar?: boolean; 13 | stackBar?: boolean; 14 | dodgeBar?: boolean; 15 | interval?: boolean; 16 | stackInterval?: boolean; 17 | dodgeInterval?: boolean; 18 | point?: boolean; 19 | waterfall?: boolean; 20 | funnel?: boolean; 21 | pyramid?: boolean; 22 | radialBar?: boolean; 23 | schema?: boolean; 24 | box?: boolean; 25 | candle?: boolean; 26 | polygon?: boolean; 27 | contour?: boolean; 28 | heatmap?: boolean; 29 | edge?: boolean; 30 | sankey?: boolean; 31 | jitterPoint?: boolean; 32 | } 33 | 34 | type IRLiteChart = ISLite & IMain & { 35 | [key: string]: any, 36 | }; 37 | 38 | export default IRLiteChart; 39 | -------------------------------------------------------------------------------- /packages/viser-react/tools/babel-preset.js: -------------------------------------------------------------------------------- 1 | const BABEL_ENV = process.env.BABEL_ENV 2 | const building = BABEL_ENV != undefined && BABEL_ENV !== 'cjs' 3 | 4 | const plugins = [ 5 | 'lodash', 6 | "@babel/plugin-proposal-export-default-from", 7 | "@babel/plugin-proposal-export-namespace-from", 8 | ["@babel/plugin-proposal-class-properties", { "loose": true }], 9 | "@babel/plugin-proposal-object-rest-spread" 10 | ]; 11 | 12 | if (BABEL_ENV === 'umd') { 13 | plugins.push('@babel/plugin-external-helpers'); 14 | } 15 | 16 | module.exports = { 17 | presets: [ 18 | [ '@babel/preset-env', { 19 | modules: building ? false : 'commonjs', 20 | targets: { 21 | browsers: ['last 2 versions'] 22 | } 23 | } ], 24 | '@babel/preset-react' 25 | ], 26 | plugins: plugins, 27 | }; 28 | -------------------------------------------------------------------------------- /packages/viser-react/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "es2015", 4 | "moduleResolution": "node", 5 | "outDir": "es", 6 | "jsx": "react", 7 | "strict": true, 8 | "noUnusedLocals": true, 9 | "noImplicitAny": true, 10 | "removeComments": true, 11 | "preserveConstEnums": true, 12 | "sourceMap": true, 13 | "declaration": true, 14 | "lib": [ 15 | "dom", 16 | "es5", 17 | "es6", 18 | "scripthost" 19 | ] 20 | }, 21 | "include": [ 22 | "src/**/*" 23 | ], 24 | "exclude": [ 25 | "node_modules" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /packages/viser-react/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "error", 3 | "extends": [ 4 | "tslint:latest" 5 | ], 6 | "jsRules": {}, 7 | "rules": { 8 | "quotemark": [true, "single"], 9 | "no-console": [true, "log", "warn"], 10 | "object-literal-sort-keys": false 11 | }, 12 | "rulesDirectory": [] 13 | } 14 | -------------------------------------------------------------------------------- /packages/viser-react/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpack = require('webpack'); 3 | const env = process.env.NODE_ENV; 4 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; 5 | 6 | let config = { 7 | mode: 'production', 8 | 9 | entry: './lib/index.js', 10 | 11 | output: { 12 | path: path.resolve(__dirname, 'umd'), 13 | filename: 'viser-react.min.js', 14 | library: 'ViserReact', 15 | libraryTarget: 'umd', 16 | }, 17 | 18 | resolve: { 19 | extensions: ['.js', '.json'], 20 | }, 21 | 22 | externals: { 23 | 'react': 'React', 24 | 'react-dom': 'ReactDOM', 25 | }, 26 | 27 | module: { 28 | rules: [{ 29 | test: /\.js?$/, 30 | exclude: /node_modules/, 31 | use: { 32 | loader: "babel-loader" 33 | } 34 | }], 35 | }, 36 | 37 | plugins: [], 38 | }; 39 | 40 | if (env === 'analyse') { 41 | config.plugins.push(new BundleAnalyzerPlugin()); 42 | } 43 | 44 | module.exports = config; 45 | -------------------------------------------------------------------------------- /packages/viser-vue/.babelrc.js: -------------------------------------------------------------------------------- 1 | const BABEL_ENV = process.env.BABEL_ENV 2 | const building = BABEL_ENV != undefined && BABEL_ENV !== 'cjs' 3 | 4 | const plugins = [ 5 | "@babel/plugin-proposal-export-default-from", 6 | "@babel/plugin-proposal-export-namespace-from", 7 | ["@babel/plugin-proposal-class-properties", { "loose": true }], 8 | "@babel/plugin-proposal-object-rest-spread", 9 | ]; 10 | 11 | if (BABEL_ENV === 'umd') { 12 | plugins.push('@babel/plugin-external-helpers'); 13 | } 14 | 15 | module.exports = { 16 | plugins: plugins, 17 | presets: [ 18 | [ "@babel/preset-env", { 19 | modules: building ? false : 'commonjs', 20 | targets: { 21 | "browsers": ["last 2 versions"] 22 | } 23 | } ] 24 | ], 25 | }; 26 | -------------------------------------------------------------------------------- /packages/viser-vue/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 80, 3 | "tabWidth": 2, 4 | "useTabs": false, 5 | "semi": true, 6 | "singleQuote": true, 7 | "trailingComma": "es5", 8 | "bracketSpacing": true 9 | } 10 | -------------------------------------------------------------------------------- /packages/viser-vue/README.md: -------------------------------------------------------------------------------- 1 | # viser-vue [![npm](https://img.shields.io/npm/v/viser-vue.svg)](https://www.npmjs.com/package/viser-vue) [![Dependency Status](https://david-dm.org/viserjs/viser-vue.svg?path=packages/viser-vue)](https://david-dm.org/viserjs/viser-vue.svg?path=packages/viser-vue) 2 | 3 | > A toolkit fit for data vis engineer (vue version). 4 | 5 | ## Install 6 | 7 | ```sh 8 | $ npm install --save viser-vue 9 | ``` 10 | 11 | ## Usage 12 | 13 | ```vue 14 | 23 | 24 | 67 | 68 | 71 | ``` 72 | -------------------------------------------------------------------------------- /packages/viser-vue/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "viser-vue", 3 | "version": "2.4.8", 4 | "description": "viser-vue is vue of viser.", 5 | "repository": "viserjs/viser-vue", 6 | "license": "MIT", 7 | "authors": "DT-FE", 8 | "files": [ 9 | "umd", 10 | "es", 11 | "lib" 12 | ], 13 | "main": "lib/index.js", 14 | "module": "es/index.js", 15 | "types": "es/index.d.ts", 16 | "scripts": { 17 | "prepare": "npm run build", 18 | "build": "npm run build:ts && npm run build:cjs && npm run build:umd", 19 | "build:ts": "rimraf es && tsc", 20 | "build:cjs": "rimraf lib && cross-env NODE_ENV=commonjs BABEL_ENV=cjs babel ./es -d lib", 21 | "build:umd": "rimraf umd && cross-env BABEL_ENV=umd webpack --config webpack.config.js", 22 | "clean": "git clean -fdX .", 23 | "lint": "tslint src", 24 | "analyse": "cross-env NODE_ENV=analyse webpack --progress --config webpack.config.js" 25 | }, 26 | "peerDependencies": { 27 | "vue": ">=1" 28 | }, 29 | "dependencies": { 30 | "viser": "^2.0.0", 31 | "vue": "^2.5.3", 32 | "@types/node": "*" 33 | }, 34 | "devDependencies": { 35 | "@babel/cli": "^7.1.0", 36 | "@babel/core": "^7.0.0", 37 | "@babel/plugin-proposal-class-properties": "^7.0.0", 38 | "@babel/plugin-proposal-export-default-from": "^7.0.0", 39 | "@babel/plugin-proposal-export-namespace-from": "^7.0.0", 40 | "@babel/plugin-proposal-object-rest-spread": "^7.0.0", 41 | "@babel/plugin-external-helpers": "^7.0.0", 42 | "@babel/polyfill": "^7.0.0", 43 | "@babel/preset-env": "^7.0.0", 44 | "@babel/runtime": "^7.0.0", 45 | "babel-loader": "^8.0.0", 46 | "colors": "^1.1.2", 47 | "cross-env": "^5.2.0", 48 | "gzip-size": "^4.0.0", 49 | "ora": "^1.3.0", 50 | "pretty-bytes": "^4.0.2", 51 | "rimraf": "^2.6.2", 52 | "ts-loader": "^3.1.1", 53 | "tslint": "^5.5.0", 54 | "typescript": "~3.2.0", 55 | "webpack": "^4.20.0", 56 | "webpack-bundle-analyzer": "^3.6.0", 57 | "webpack-cli": "^3.1.0" 58 | }, 59 | "keywords": [ 60 | "g2", 61 | "chart", 62 | "vue", 63 | "datavis" 64 | ] 65 | } 66 | -------------------------------------------------------------------------------- /packages/viser-vue/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "es2015", 4 | "moduleResolution": "node", 5 | "outDir": "es", 6 | "strict": true, 7 | "noUnusedLocals": true, 8 | "noImplicitAny": true, 9 | "removeComments": true, 10 | "preserveConstEnums": true, 11 | "sourceMap": true, 12 | "declaration": true, 13 | "lib": [ 14 | "es6", 15 | "scripthost", 16 | "dom" 17 | ] 18 | }, 19 | "include": ["src/**/*"], 20 | "exclude": ["node_modules"] 21 | } 22 | -------------------------------------------------------------------------------- /packages/viser-vue/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpack = require('webpack'); 3 | const env = process.env.NODE_ENV; 4 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; 5 | 6 | let config = { 7 | mode: 'production', 8 | 9 | entry: './lib/index', 10 | 11 | output: { 12 | path: path.resolve(__dirname, 'umd'), 13 | filename: 'viser-vue.min.js', 14 | library: 'ViserVue', 15 | libraryTarget: 'umd', 16 | }, 17 | 18 | resolve: { 19 | extensions: ['.js', '.json'], 20 | }, 21 | 22 | externals: { 23 | 'vue': 'Vue', 24 | }, 25 | 26 | module: { 27 | rules: [{ 28 | test: /\.js?$/, 29 | exclude: /node_modules/, 30 | use: { 31 | loader: "babel-loader" 32 | } 33 | }], 34 | }, 35 | 36 | plugins: [], 37 | }; 38 | 39 | if (env === 'analyse') { 40 | config.plugins.push(new BundleAnalyzerPlugin()); 41 | } 42 | 43 | module.exports = config; 44 | -------------------------------------------------------------------------------- /packages/viser/.babelrc.js: -------------------------------------------------------------------------------- 1 | const BABEL_ENV = process.env.BABEL_ENV 2 | const building = BABEL_ENV != undefined && BABEL_ENV !== 'cjs' 3 | 4 | const plugins = [ 5 | 'lodash', 6 | "@babel/plugin-proposal-export-default-from", 7 | "@babel/plugin-proposal-export-namespace-from", 8 | ["@babel/plugin-proposal-class-properties", { "loose": true }], 9 | "@babel/plugin-proposal-object-rest-spread", 10 | ]; 11 | 12 | if (BABEL_ENV === 'umd') { 13 | plugins.push('@babel/plugin-external-helpers'); 14 | } 15 | 16 | module.exports = { 17 | plugins: plugins, 18 | presets: [ 19 | [ "@babel/preset-env", { 20 | modules: building ? false : 'commonjs', 21 | targets: { 22 | "browsers": ["last 2 versions"] 23 | } 24 | } ] 25 | ], 26 | }; 27 | -------------------------------------------------------------------------------- /packages/viser/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 80, 3 | "tabWidth": 2, 4 | "useTabs": false, 5 | "semi": true, 6 | "singleQuote": true, 7 | "trailingComma": "es5", 8 | "bracketSpacing": true 9 | } 10 | -------------------------------------------------------------------------------- /packages/viser/README.md: -------------------------------------------------------------------------------- 1 | # viser [![npm](https://img.shields.io/npm/v/viser.svg)](https://www.npmjs.com/package/viser) [![Dependency Status](https://david-dm.org/viserjs/viser.svg?path=packages/viser)](https://david-dm.org/viserjs/viser.svg?path=packages/viser) 2 | 3 | > A toolkit fit for data vis engineer. 4 | 5 | ## Install 6 | 7 | ```sh 8 | $ npm install --save viser 9 | ``` 10 | 11 | ## Usage 12 | 13 | ```jsx 14 | import viser from 'viser'; 15 | const DataSet = require('@antv/data-set'); 16 | 17 | const sourceData = [ 18 | { month: 'Jan', Tokyo: 7.0, London: 3.9 }, 19 | { month: 'Feb', Tokyo: 6.9, London: 4.2 }, 20 | { month: 'Mar', Tokyo: 9.5, London: 5.7 }, 21 | { month: 'Apr', Tokyo: 14.5, London: 8.5 }, 22 | { month: 'May', Tokyo: 18.4, London: 11.9 }, 23 | { month: 'Jun', Tokyo: 21.5, London: 15.2 }, 24 | { month: 'Jul', Tokyo: 25.2, London: 17.0 }, 25 | { month: 'Aug', Tokyo: 26.5, London: 16.6 }, 26 | { month: 'Sep', Tokyo: 23.3, London: 14.2 }, 27 | { month: 'Oct', Tokyo: 18.3, London: 10.3 }, 28 | { month: 'Nov', Tokyo: 13.9, London: 6.6 }, 29 | { month: 'Dec', Tokyo: 9.6, London: 4.8 }, 30 | ]; 31 | 32 | const dv = new DataSet.View().source(sourceData); 33 | dv.transform({ 34 | type: 'fold', 35 | fields: ['Tokyo', 'London'], 36 | key: 'city', 37 | value: 'temperature', 38 | }); 39 | const data = dv.rows; 40 | 41 | viser({ 42 | data, 43 | axis: true, 44 | legend: true, 45 | tooltip: true, 46 | series: [{ 47 | quickType: 'smoothLine', 48 | position: 'month*temperature', 49 | color: "city", 50 | size: 2, 51 | }, { 52 | quickType: 'point', 53 | position: 'month*temperature', 54 | color: "city", 55 | size: 4, 56 | style: { 57 | stroke: '#fff', 58 | lineWidth: 1, 59 | }, 60 | }], 61 | chart: { 62 | container: 'mountNode', 63 | width: 800, 64 | height: 400, 65 | }, 66 | }); 67 | ``` 68 | -------------------------------------------------------------------------------- /packages/viser/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "viser", 3 | "version": "2.4.9", 4 | "description": "viser is a toolkit fit for data vis engineer.", 5 | "repository": "viserjs/viser", 6 | "license": "MIT", 7 | "authors": "DT-FE", 8 | "files": [ 9 | "lib", 10 | "es", 11 | "umd" 12 | ], 13 | "main": "lib/index.js", 14 | "module": "es/index.js", 15 | "types": "es/index.d.ts", 16 | "scripts": { 17 | "prepare": "npm run build", 18 | "build": "npm run build:ts && npm run build:cjs && npm run build:umd", 19 | "build:ts": "rimraf es && tsc", 20 | "build:cjs": "rimraf lib && cross-env NODE_ENV=commonjs BABEL_ENV=cjs babel ./es -d lib", 21 | "build:umd": "rimraf umd && cross-env BABEL_ENV=umd webpack --config webpack.config.js", 22 | "clean": "git clean -fdX .", 23 | "lint": "tslint src/**/*", 24 | "analyse": "cross-env NODE_ENV=analyse webpack --progress --config webpack.config.js" 25 | }, 26 | "dependencies": { 27 | "@antv/g2": "~3.5.3", 28 | "@antv/g2-brush": "^0.0.2", 29 | "@antv/g2-plugin-slider": "^2.1.0", 30 | "@types/d3-format": "*", 31 | "@types/lodash": "*", 32 | "@types/node": "^8.0.53", 33 | "d3-format": "^1.3.0", 34 | "lodash": "^4.17.4" 35 | }, 36 | "devDependencies": { 37 | "@babel/cli": "^7.1.0", 38 | "@babel/core": "^7.0.0", 39 | "@babel/plugin-proposal-class-properties": "^7.0.0", 40 | "@babel/plugin-proposal-export-default-from": "^7.0.0", 41 | "@babel/plugin-proposal-export-namespace-from": "^7.0.0", 42 | "@babel/plugin-proposal-object-rest-spread": "^7.0.0", 43 | "@babel/plugin-external-helpers": "^7.0.0", 44 | "@babel/polyfill": "^7.0.0", 45 | "@babel/preset-env": "^7.0.0", 46 | "@babel/runtime": "^7.0.0", 47 | "babel-loader": "^8.0.0", 48 | "babel-plugin-lodash": "^3.3.0", 49 | "colors": "^1.1.2", 50 | "cross-env": "^5.2.0", 51 | "gzip-size": "^4.0.0", 52 | "ora": "^1.3.0", 53 | "pretty-bytes": "^4.0.2", 54 | "rimraf": "^2.6.2", 55 | "tslint": "^5.5.0", 56 | "typescript": "~3.2.0", 57 | "webpack": "^4.20.0", 58 | "webpack-bundle-analyzer": "^3.6.0", 59 | "webpack-cli": "^3.1.0" 60 | }, 61 | "keywords": [ 62 | "g2", 63 | "chart", 64 | "datavis" 65 | ] 66 | } 67 | -------------------------------------------------------------------------------- /packages/viser/src/components/setCustomFormatter.ts: -------------------------------------------------------------------------------- 1 | import * as d3 from 'd3-format'; 2 | import * as _ from 'lodash'; 3 | 4 | export const supportD3Formatter = (obj: any) => { 5 | const objFormatter = _.get(obj, 'formatter'); 6 | if (_.isString(objFormatter)) { 7 | obj.formatter = (val: number) => { 8 | return d3.format(objFormatter)(val); 9 | }; 10 | return obj; 11 | } 12 | 13 | for (const item in obj) { 14 | if (obj.hasOwnProperty(item)) { 15 | const formatter = _.get(obj[item], 'formatter'); 16 | 17 | if (_.isString(formatter)) { 18 | obj[item].formatter = (val: number) => { 19 | return d3.format(formatter)(val); 20 | }; 21 | } 22 | } 23 | } 24 | 25 | return obj; 26 | }; 27 | -------------------------------------------------------------------------------- /packages/viser/src/components/setFilterConfig.ts: -------------------------------------------------------------------------------- 1 | import * as _ from 'lodash'; 2 | 3 | export const process = (chart: any, config: any) => { 4 | const cFilter = _.cloneDeep(config.filter); 5 | const isArr = _.isArray(cFilter); 6 | 7 | if (_.isEmpty(cFilter)) { return; } 8 | 9 | const arrFilter = isArr ? cFilter : [cFilter]; 10 | 11 | for (const res of arrFilter) { 12 | if (res.dataKey && res.callback) { 13 | chart.filter(res.dataKey, res.callback); 14 | } 15 | } 16 | 17 | return chart; 18 | }; 19 | -------------------------------------------------------------------------------- /packages/viser/src/components/setGuideConfig.ts: -------------------------------------------------------------------------------- 1 | import * as _ from 'lodash'; 2 | import * as EventUtils from '../utils/EventUtils'; 3 | 4 | // add two type of guide line 5 | // parallel and normal 6 | function setGuideLine(chart: any, item: any) { 7 | if (item.quickType === 'parallel') { 8 | const data = item.data; 9 | chart.guide().line({ 10 | start: ['min', data], 11 | end: ['max', data], 12 | ...item, 13 | }); 14 | } else if (item.quickType === 'normal') { 15 | const data = item.data; 16 | chart.guide().line({ 17 | start: [data, 'min'], 18 | end: [data, 'max'], 19 | ...item, 20 | }); 21 | } else { 22 | chart.guide().line(item); 23 | } 24 | } 25 | 26 | // add two type of guide line 27 | // parallel and normal 28 | function setGuideArc(chart: any, item: any) { 29 | if (item.quickType === 'parallel') { 30 | const data = item.data; 31 | chart.guide().arc({ 32 | start: ['min', data], 33 | end: ['max', data], 34 | ...item, 35 | }); 36 | chart.guide().arc({ 37 | start: ['max', data], 38 | end: ['min', data], 39 | ...item, 40 | }); 41 | } else if (item.quickType === 'normal') { 42 | const data = item.data; 43 | chart.guide().line({ 44 | start: [data, 'min'], 45 | end: [data, 'max'], 46 | ...item, 47 | }); 48 | } else { 49 | chart.guide().arc(item); 50 | } 51 | } 52 | 53 | export const process = (chart: any, config: any, isUpdate: boolean = false) => { 54 | const cGuide = _.cloneDeep(config.guide); 55 | const isArr = Array.isArray(cGuide); 56 | 57 | if (_.isNil(cGuide) || _.isEmpty(cGuide)) { return; } 58 | 59 | const arrGuide = isArr ? cGuide : [cGuide]; 60 | 61 | arrGuide.forEach((res: any) => { 62 | if (!isUpdate) { 63 | EventUtils.setEvent(chart, `guide-${res.type}`, res); 64 | } 65 | 66 | if (res.type === 'line') { 67 | setGuideLine(chart, res); 68 | } else if (res.type === 'region') { 69 | chart.guide().region(res); 70 | } else if (res.type === 'arc') { 71 | setGuideArc(chart, res); 72 | } else if (res.type === 'text') { 73 | chart.guide().text(res); 74 | } else if (res.type === 'image') { 75 | chart.guide().image(res); 76 | } else if (res.type === 'html') { 77 | chart.guide().html(res); 78 | } else if (res.type === 'dataMarker') { 79 | chart.guide().dataMarker(res); 80 | } else if (res.type === 'regionFilter') { 81 | chart.guide().regionFilter(res); 82 | } else if (res.type === 'dataRegion') { 83 | chart.guide().dataRegion(res); 84 | } 85 | }); 86 | 87 | return chart; 88 | }; 89 | -------------------------------------------------------------------------------- /packages/viser/src/components/setLegendConfig.ts: -------------------------------------------------------------------------------- 1 | import * as _ from 'lodash'; 2 | import * as EventUtils from '../utils/EventUtils'; 3 | 4 | function setHighlight(item: any) { 5 | item.onHover = (ev: any) => { 6 | const shapes = ev.shapes; 7 | const geom = ev.geom; 8 | geom.highlightShapes(shapes); 9 | }; 10 | 11 | return item; 12 | } 13 | 14 | export const process = (chart: any, config: any, isUpdate: boolean = false) => { 15 | const cLegend = _.cloneDeep(config.legend); 16 | const isArr = Array.isArray(cLegend); 17 | 18 | if (_.isNil(cLegend) || cLegend === false || 19 | (isArr && cLegend.length === 0)) { 20 | return chart.legend(false); 21 | } 22 | 23 | if (cLegend === true) { return chart.legend(); } 24 | 25 | const arrLegend = isArr ? cLegend : [cLegend]; 26 | 27 | for (let res of arrLegend) { 28 | if (res.highlight) { 29 | res = setHighlight(res); 30 | } 31 | 32 | for (const item in res) { 33 | if (res.hasOwnProperty(item)) { 34 | // Due to lack of legend:click event support in G2.chart, 35 | // unlike other component, 36 | // we have to use onClick on Legend. 37 | if (item === 'onClick') { 38 | const content = res.onClick; 39 | res.onClick = (ev?: any) => { 40 | content(ev, chart); 41 | }; 42 | } 43 | 44 | if (!isUpdate) { 45 | EventUtils.setSEvent(chart, 'legend', item, res[item]); 46 | } 47 | } 48 | } 49 | 50 | if (!_.isNil(res.legendMarker)) { 51 | res['g2-legend-marker'] = res.legendMarker; 52 | } 53 | 54 | if (!_.isNil(res.legendListItem)) { 55 | res['g2-legend-list-item'] = res.legendListItem; 56 | } 57 | 58 | if (!_.isNil(res.legendTitle)) { 59 | res['g2-legend-title'] = res.legendTitle; 60 | } 61 | 62 | if (!_.isNil(res.legendList)) { 63 | res['g2-legend-list'] = res.legendList; 64 | } 65 | 66 | res = _.omit(res, ['legendMarker', 'legendListItem', 'legendTitle', 'legendList']); 67 | 68 | if (res.dataKey) { 69 | if (res.show === false) { 70 | chart.legend(res.dataKey, false); 71 | } else { 72 | const option = _.omit(res, ['dataKey', 'show']); 73 | chart.legend(res.dataKey, option); 74 | } 75 | } else { 76 | chart.legend(res); 77 | } 78 | } 79 | return chart; 80 | }; 81 | -------------------------------------------------------------------------------- /packages/viser/src/components/setScaleConfig.ts: -------------------------------------------------------------------------------- 1 | import * as _ from 'lodash'; 2 | import * as setCustomFormatter from './setCustomFormatter'; 3 | 4 | export const process = (chart: any, config: any) => { 5 | const cScale = _.cloneDeep(config.scale); 6 | const isArr = _.isArray(cScale); 7 | 8 | if (_.isEmpty(cScale)) { return; } 9 | 10 | const arrScale = isArr ? cScale : [cScale]; 11 | let options: any = {}; 12 | 13 | for (const res of arrScale) { 14 | if (res.dataKey) { 15 | const currOption = _.omit(res, 'dataKey'); 16 | options[res.dataKey] = currOption; 17 | } 18 | } 19 | 20 | options = setCustomFormatter.supportD3Formatter(options); 21 | return chart.scale(options); 22 | }; 23 | -------------------------------------------------------------------------------- /packages/viser/src/components/setTooltipConfig.ts: -------------------------------------------------------------------------------- 1 | import * as _ from 'lodash'; 2 | import * as EventUtils from '../utils/EventUtils'; 3 | 4 | export const process = (chart: any, config: any, isUpdate: boolean = false) => { 5 | let cTooltip = _.cloneDeep(config.tooltip); 6 | 7 | if (_.isNil(cTooltip) || cTooltip === false || cTooltip.show === false) { 8 | return chart.tooltip(false); 9 | } 10 | 11 | for (const item in cTooltip) { 12 | if (cTooltip.hasOwnProperty(item)) { 13 | if (item === 'g2Tooltip') { 14 | cTooltip['g2-tooltip'] = cTooltip[item]; 15 | cTooltip = _.omit(cTooltip, 'g2Tooltip'); 16 | } 17 | 18 | if (item === 'g2TooltipTitle') { 19 | cTooltip['g2-tooltip-title'] = cTooltip[item]; 20 | cTooltip = _.omit(cTooltip, 'g2TooltipTitle'); 21 | } 22 | 23 | if (item === 'g2TooltipList') { 24 | cTooltip['g2-tooltip-list'] = cTooltip[item]; 25 | cTooltip = _.omit(cTooltip, 'g2TooltipList'); 26 | } 27 | 28 | if (item === 'g2TooltipListItem') { 29 | cTooltip['g2-tooltip-list-item'] = cTooltip[item]; 30 | cTooltip = _.omit(cTooltip, 'g2TooltipListItem'); 31 | } 32 | 33 | if (item === 'g2TooltipMaker') { 34 | cTooltip['g2-tooltip-maker'] = cTooltip[item]; 35 | cTooltip = _.omit(cTooltip, 'g2TooltipMaker'); 36 | } 37 | } 38 | } 39 | if (!isUpdate) { 40 | EventUtils.setEvent(chart, 'tooltip', cTooltip); 41 | } 42 | 43 | return chart.tooltip(cTooltip); 44 | }; 45 | 46 | export const setDefaultPoint = (chart: any, config: any) => { 47 | const cTooltip = _.cloneDeep(config.tooltip); 48 | 49 | if ( 50 | !_.isNil(cTooltip) && cTooltip !== false && cTooltip.show !== false 51 | && cTooltip.defaultPoint 52 | ) { 53 | const defaultPoint = cTooltip.defaultPoint; 54 | const xyPoint = chart.getXY(defaultPoint); 55 | if (!!xyPoint) { 56 | chart.showTooltip(xyPoint); 57 | } 58 | } 59 | }; 60 | -------------------------------------------------------------------------------- /packages/viser/src/index.ts: -------------------------------------------------------------------------------- 1 | import * as _ from 'lodash'; 2 | import CommonChart from './core/CommonChart'; 3 | import IAxisConfig, { IAxis } from './typed/IAxis'; 4 | import IBrush from './typed/IBrush'; 5 | import IChart from './typed/IChart'; 6 | import ICoord, { IPolarCoord, IRectCoord } from './typed/ICoord'; 7 | import IFacet from './typed/IFacet'; 8 | import IFilter from './typed/IFilter'; 9 | import IGuideConfig, { IArcGuide, IGuide, IImageGuide, ILineGuide, IRegionGuide, ITextGuide } from './typed/IGuide'; 10 | import ILegendConfig, { ILegend } from './typed/ILegend'; 11 | import IMain from './typed/IMain'; 12 | import IScale from './typed/IScale'; 13 | import ISeriesConfig, { ISeries } from './typed/ISeries'; 14 | import ISlider from './typed/ISlider'; 15 | import ITooltipConfig, { ITooltip } from './typed/ITooltip'; 16 | import IViewConfig, { IView } from './typed/IView'; 17 | import * as CustomizeUtils from './utils/CustomizeUtils'; 18 | declare const require: any; 19 | // tslint:disable-next-line:no-var-requires 20 | const G2 = require('@antv/g2'); 21 | 22 | export { 23 | IAxis, 24 | IAxisConfig, 25 | IBrush, 26 | IChart, 27 | ICoord, 28 | IRectCoord, 29 | IPolarCoord, 30 | IFacet, 31 | IFilter, 32 | IGuide, 33 | IGuideConfig, 34 | ILineGuide, 35 | ITextGuide, 36 | IImageGuide, 37 | IRegionGuide, 38 | IArcGuide, 39 | ILegend, 40 | ILegendConfig, 41 | ISeries, 42 | ISeriesConfig, 43 | ITooltip, 44 | ITooltipConfig, 45 | IView, 46 | IViewConfig, 47 | IScale, 48 | IMain, 49 | ISlider, 50 | }; 51 | 52 | export const registerAnimation = CustomizeUtils.registerAnimation; 53 | export const registerShape = CustomizeUtils.registerShape; 54 | export const Global = G2.Global; 55 | 56 | function hasDataCondition(config: any) { 57 | let hasData = false; 58 | 59 | if (!_.isEmpty(config.data)) { 60 | hasData = true; 61 | } 62 | 63 | if (!_.isNil(config.views)) { 64 | if (_.isPlainObject(config.views) && !_.isEmpty(config.views.data)) { 65 | hasData = true; 66 | } 67 | 68 | if (_.isArray(config.views)) { 69 | for (const item of config.views) { 70 | if (!_.isEmpty(item.data)) { 71 | hasData = true; 72 | } 73 | } 74 | } 75 | } 76 | 77 | return hasData; 78 | } 79 | 80 | export default function(config: any) { 81 | if (_.isNil(config) || _.isEmpty(config)) { return; } 82 | 83 | const hasData = hasDataCondition(config); 84 | if (!hasData) { return; } 85 | const commonChart = new CommonChart(config); 86 | commonChart.render(); 87 | 88 | return commonChart; 89 | } 90 | 91 | export { default as Plugin } from './plugins/index'; 92 | -------------------------------------------------------------------------------- /packages/viser/src/plugins/Slider.ts: -------------------------------------------------------------------------------- 1 | declare const require: any; 2 | // g2-plugin-slider need G2 loaded first 3 | import '@antv/g2'; 4 | // tslint:disable-next-line:no-var-requires 5 | const Slider = require('@antv/g2-plugin-slider'); 6 | 7 | import ISliderConfig from '../typed/ISlider'; 8 | 9 | export default (config: ISliderConfig) => { 10 | const container = document.getElementById(config.container); 11 | if (!container) { 12 | console.error('plugin slider container not defined'); 13 | return; 14 | } 15 | 16 | container.innerHTML = ''; 17 | const sliderInstance = new Slider(config); 18 | sliderInstance.render(); 19 | return sliderInstance; 20 | }; 21 | -------------------------------------------------------------------------------- /packages/viser/src/plugins/index.ts: -------------------------------------------------------------------------------- 1 | import Slider from './Slider'; 2 | 3 | export default (config: any) => { 4 | const plugins = {} as any; 5 | 6 | for (const pluginName in config) { 7 | if (config.hasOwnProperty(pluginName)) { 8 | const pluginConfig = config[pluginName]; 9 | switch (pluginName) { 10 | case 'slider': 11 | plugins.slider = Slider(pluginConfig); 12 | break; 13 | default: 14 | break; 15 | } 16 | } 17 | } 18 | 19 | return plugins; 20 | }; 21 | -------------------------------------------------------------------------------- /packages/viser/src/shapes/ErrorBar.ts: -------------------------------------------------------------------------------- 1 | import IShapePoints from '../typed/IShapePoints'; 2 | import * as CustomizeUtils from '../utils/CustomizeUtils'; 3 | 4 | const DEFAULT_ERRORBAR_SHAPE = 'errorbar'; 5 | 6 | function renderBarPath(points: IShapePoints[]) { 7 | return [ 8 | ['M', points[1].x, points[1].y], 9 | ['L', points[2].x, points[2].y], 10 | ['Z'], 11 | ['M', ((points[1].x || 0) + (points[2].x || 0)) / 2, ((points[1].y || 0) + (points[2].y || 0)) / 2], 12 | ['L', ((points[0].x || 0) + (points[3].x || 0)) / 2, ((points[0].y || 0) + (points[3].y || 0)) / 2], 13 | ['Z'], 14 | ['M', points[0].x, points[0].y], 15 | ['L', points[3].x, points[3].y], 16 | ['Z'], 17 | ]; 18 | } 19 | 20 | export const registerShape = () => { 21 | const barWidth = 1; 22 | const hasPoint = false; 23 | 24 | CustomizeUtils.registerShape('schema', DEFAULT_ERRORBAR_SHAPE, { 25 | // 1 -> 2 26 | // | | 27 | // 5<-4 | 28 | // | | 29 | // 0 3 30 | getPoints({ x = 0, y = [0, 0, 0] as number & number[], size = 0 }: IShapePoints) { 31 | return [ 32 | { x: x - (size / 2) * barWidth, y: y[0] }, 33 | { x: x - (size / 2) * barWidth, y: y[2] }, 34 | { x: x + (size / 2) * barWidth, y: y[2] }, 35 | { x: x + (size / 2) * barWidth, y: y[0] }, 36 | { x, y: y[1] }, 37 | { x: x - (size / 2) * barWidth , y: y[1] }, 38 | ]; 39 | }, 40 | 41 | drawShape(cfg: any, group: any) { 42 | const newGroup = group; 43 | const { points } = cfg; 44 | newGroup.addShape('path', { 45 | attrs: { 46 | stroke: cfg.color, 47 | strokeOpacity: cfg.opacity || 1, 48 | lineWidth: cfg.style.lineWidth || 1, 49 | fill: cfg.color, 50 | opacity: cfg.opacity || 1, 51 | path: this.parsePath(renderBarPath(points)), 52 | ...cfg.style, 53 | }, 54 | }); 55 | if (hasPoint) { 56 | newGroup.addShape('circle', { 57 | attrs: { 58 | stroke: cfg.color, 59 | strokeOpacity: cfg.opacity || 1, 60 | lineWidth: cfg.style.lineWidth || 1, 61 | fill: cfg.color, 62 | opacity: cfg.opacity || 1, 63 | x: this.parsePoint(points[4]).x, 64 | y: this.parsePoint(points[4]).y, 65 | r: cfg.style.lineWidth + 0.5 || 1.5, 66 | ...cfg.style, 67 | }, 68 | }); 69 | } 70 | 71 | return newGroup; 72 | }, 73 | }); 74 | }; 75 | -------------------------------------------------------------------------------- /packages/viser/src/shapes/Sankey.ts: -------------------------------------------------------------------------------- 1 | import IShapePoints from '../typed/IShapePoints'; 2 | import * as CustomizeUtils from '../utils/CustomizeUtils'; 3 | 4 | const DEFAULT_SANKEY_SHAPE = 'sankey'; 5 | 6 | function interpolationGenerator(a: number, b: number) { 7 | const ka = +a; 8 | const kb = b - ka; 9 | return (t: number) => ka + kb * t; 10 | } 11 | 12 | function getCurvePath(from: any, to: any, curvature: number) { 13 | const interpolationFunc = interpolationGenerator(from.x, to.x); 14 | const fromCtrlX = interpolationFunc(curvature); 15 | const toCtrlX = interpolationFunc(1 - curvature); 16 | 17 | const points = [ 18 | 'C', 19 | fromCtrlX, from.y, 20 | toCtrlX, to.y, 21 | to.x, to.y, 22 | ]; 23 | 24 | return points; 25 | } 26 | 27 | function getEdgePath(points: IShapePoints[], curvature: number) { 28 | const path = [ 29 | ['M', points[0].x, points[0].y], 30 | ['L', points[1].x, points[1].y], 31 | ]; 32 | const c1 = getCurvePath(points[1], points[3], curvature); 33 | path.push(c1); 34 | path.push(['L', points[3].x, points[3].y]); 35 | path.push(['L', points[2].x, points[2].y]); 36 | const c2 = getCurvePath(points[2], points[0], curvature); 37 | path.push(c2); 38 | path.push(['Z']); 39 | return path; 40 | } 41 | 42 | export const registerShape = () => { 43 | CustomizeUtils.registerShape('edge', DEFAULT_SANKEY_SHAPE, { 44 | drawShape(cfg: any, group: any) { 45 | const { points, style } = cfg; 46 | const curvature = style.curvature || 0.5; 47 | const path = this.parsePath(getEdgePath(points, curvature)); 48 | const shape = group.addShape('path', { 49 | attrs: { 50 | stroke: 'none', 51 | strokeOpacity: 0, 52 | fill: cfg.color, 53 | opacity: cfg.opacity, 54 | path, 55 | }, 56 | }); 57 | return shape; 58 | }, 59 | }); 60 | }; 61 | -------------------------------------------------------------------------------- /packages/viser/src/shapes/loadShapes.ts: -------------------------------------------------------------------------------- 1 | import * as ErrorBar from './ErrorBar'; 2 | import * as Sankey from './Sankey'; 3 | 4 | export default function() { 5 | Sankey.registerShape(); 6 | ErrorBar.registerShape(); 7 | } 8 | -------------------------------------------------------------------------------- /packages/viser/src/typed/IBrush.ts: -------------------------------------------------------------------------------- 1 | type eventFunc = (ev: any, chart: any) => void; 2 | 3 | export interface IBrush { 4 | canvas?: any; 5 | startPoint?: object; 6 | brushing?: boolean; 7 | dragging?: boolean; 8 | brushShape?: any; 9 | container?: any; 10 | polygonPath?: string; 11 | style?: object; 12 | type?: string; 13 | dragable?: boolean; 14 | dragoffX?: number; 15 | dragoffY?: number; 16 | inPlot?: boolean; 17 | xField?: string; 18 | yField?: string; 19 | filter?: boolean; 20 | onBrushstart?: eventFunc; 21 | onBrushmove?: eventFunc; 22 | onBrushend?: eventFunc; 23 | onDragstart?: eventFunc; 24 | onDragmove?: eventFunc; 25 | onDragend?: eventFunc; 26 | } 27 | 28 | export default IBrush; 29 | -------------------------------------------------------------------------------- /packages/viser/src/typed/IChart.ts: -------------------------------------------------------------------------------- 1 | import IFilter from './IFilter'; 2 | 3 | type eventFunc = (ev: any, chart: any) => void; 4 | interface IBackground { 5 | stroke?: string; 6 | strokeOpacity?: number; 7 | lineWidth?: number; 8 | fill?: string; 9 | fillOpactiy?: number; 10 | radius?: number; 11 | } 12 | 13 | export interface IChart { 14 | id?: any; 15 | container?: any; 16 | height?: number; 17 | width?: number; 18 | animate?: boolean | object; 19 | forceFit?: boolean; 20 | background?: IBackground; 21 | plotBackground?: IBackground; 22 | padding?: number | object | number[] | string; 23 | theme?: string; 24 | renderer?: string; 25 | filter?: IFilter; 26 | onMouseDown?: eventFunc; 27 | onMouseMove?: eventFunc; 28 | onMouseLeave?: eventFunc; 29 | onMouseUp?: eventFunc; 30 | onClick?: eventFunc; 31 | onDblClick?: eventFunc; 32 | onTouchStart?: eventFunc; 33 | onTouchMove?: eventFunc; 34 | onTouchEnd?: eventFunc; 35 | onPlotEnter?: eventFunc; 36 | onPlotMove?: eventFunc; 37 | onPlotLeave?: eventFunc; 38 | onPlotClick?: eventFunc; 39 | onPlotDbClick?: eventFunc; 40 | } 41 | 42 | export default IChart; 43 | -------------------------------------------------------------------------------- /packages/viser/src/typed/ICoord.ts: -------------------------------------------------------------------------------- 1 | export interface IRectCoord { 2 | type?: 'rect'; 3 | direction?: string; 4 | } 5 | 6 | export interface IPolarCoord { 7 | type?: 'polar' | 'theta' | 'helix'; 8 | direction?: string; 9 | radius?: number; 10 | innerRadius?: number; 11 | startAngle?: number; 12 | endAngle?: number; 13 | rotate?: number; 14 | } 15 | 16 | type ICoord = IRectCoord | IPolarCoord; 17 | 18 | export default ICoord; 19 | -------------------------------------------------------------------------------- /packages/viser/src/typed/IFacet.ts: -------------------------------------------------------------------------------- 1 | import * as IStyle from './IStyle'; 2 | 3 | interface IColTitleProps { 4 | offsetY?: number; 5 | style?: IStyle.ITextStyle; 6 | } 7 | 8 | interface IRowTitleProps { 9 | offsetX?: number; 10 | style?: IStyle.ITextStyle; 11 | } 12 | 13 | interface IFacet { 14 | type: string; 15 | fields?: string[]; 16 | cols?: number; 17 | rows?: number; 18 | colField?: string | string[]; 19 | rowField?: string | string[]; 20 | colValue?: number; 21 | rowValue?: number; 22 | colIndex?: number; 23 | rowIndex?: number; 24 | showTitle?: boolean; 25 | colTitle?: IColTitleProps; 26 | rowTitle?: IRowTitleProps; 27 | autoSetAxis?: boolean; 28 | padding?: number | number[]; 29 | transpose?: boolean; 30 | line?: IStyle.ILineStyle; 31 | lineSmooth?: boolean; 32 | views?: any; 33 | eachView?: (views: any, facet: any) => void; 34 | } 35 | 36 | export default IFacet; 37 | -------------------------------------------------------------------------------- /packages/viser/src/typed/IFilter.ts: -------------------------------------------------------------------------------- 1 | interface IFilter { 2 | dataKey: string; 3 | callback: (ev: any) => boolean; 4 | } 5 | 6 | type IFilterConfig = IFilter | IFilter[]; 7 | 8 | export default IFilterConfig; 9 | -------------------------------------------------------------------------------- /packages/viser/src/typed/ILegend.ts: -------------------------------------------------------------------------------- 1 | import * as IStyle from './IStyle'; 2 | 3 | type func = () => void; 4 | type itemTplFunc = (value: any, color: any, checked: any, index: any) => string; 5 | type formatterFunc = (val: number) => string | number; 6 | type eventFunc = (ev: any, chart: any) => void; 7 | 8 | export interface ILegend { 9 | dataKey?: string; 10 | show?: boolean; 11 | position?: string; 12 | title?: null | object; 13 | custom?: boolean; 14 | offset?: number | number[]; 15 | offsetX?: number; 16 | offsetY?: number; 17 | items?: object[]; 18 | itemGap?: number; 19 | titleGap?: number; 20 | itemMarginBottom?: number; 21 | itemsGroup?: object[]; 22 | layout?: string; 23 | allowAllCanceled?: boolean; 24 | backPadding?: number[]; 25 | itemWidth?: number; 26 | unCheckColor?: string; 27 | background?: object; 28 | itemFormatter?: formatterFunc; 29 | marker?: string | func; 30 | textStyle?: IStyle.ITextStyle; 31 | checkable?: boolean; 32 | clickable?: boolean; 33 | hoverable?: boolean; 34 | useHtml?: boolean; 35 | autoWrap?: boolean; 36 | autoPosition?: boolean; 37 | container?: any; 38 | containerTpl?: string; 39 | itemTpl?: string | itemTplFunc; 40 | selectedMode?: string; 41 | reversed?: boolean; 42 | slidable?: boolean; 43 | width?: number; 44 | height?: number; 45 | legendMarker?: any; 46 | legendListItem?: any; 47 | legendTitle?: any; 48 | legendList?: any; 49 | legendStyle?: any; 50 | attachLast?: boolean; 51 | flipPage?: boolean; 52 | name?: boolean; 53 | reactive?: boolean; 54 | sizeType?: string; 55 | isSegment?: boolean; 56 | onHover?: eventFunc; 57 | onClick?: eventFunc; 58 | onTitleMouseDown?: eventFunc; 59 | onTitleMouseMove?: eventFunc; 60 | onTitleMouseLeave?: eventFunc; 61 | onTitleMouseUp?: eventFunc; 62 | onTitleClick?: eventFunc; 63 | onTitleDblClick?: eventFunc; 64 | onTitleTouchStart?: eventFunc; 65 | onTitleTouchMove?: eventFunc; 66 | onTitleTouchEnd?: eventFunc; 67 | onItemMouseDown?: eventFunc; 68 | onItemMouseMove?: eventFunc; 69 | onItemMouseLeave?: eventFunc; 70 | onItemMouseUp?: eventFunc; 71 | onItemClick?: eventFunc; 72 | onItemDblClick?: eventFunc; 73 | onItemTouchStart?: eventFunc; 74 | onItemTouchMove?: eventFunc; 75 | onItemTouchEnd?: eventFunc; 76 | onMarkerMouseDown?: eventFunc; 77 | onMarkerMouseMove?: eventFunc; 78 | onMarkerMouseLeave?: eventFunc; 79 | onMarkerMouseUp?: eventFunc; 80 | onMarkerClick?: eventFunc; 81 | onMarkerDblClick?: eventFunc; 82 | onMarkerTouchStart?: eventFunc; 83 | onMarkerTouchMove?: eventFunc; 84 | onMarkerTouchEnd?: eventFunc; 85 | onTextMouseDown?: eventFunc; 86 | onTextMouseMove?: eventFunc; 87 | onTextMouseLeave?: eventFunc; 88 | onTextMouseUp?: eventFunc; 89 | onTextClick?: eventFunc; 90 | onTextDblClick?: eventFunc; 91 | onTextTouchStart?: eventFunc; 92 | onTextTouchMove?: eventFunc; 93 | onTextTouchEnd?: eventFunc; 94 | } 95 | 96 | type ILegendConfig = boolean | ILegend; 97 | 98 | export default ILegendConfig; 99 | -------------------------------------------------------------------------------- /packages/viser/src/typed/IMain.ts: -------------------------------------------------------------------------------- 1 | import IChart from './IChart'; 2 | import IFacet from './IFacet'; 3 | import ILegend from './ILegend'; 4 | import IViewConfig, { IView } from './IView'; 5 | 6 | interface ISMain { 7 | data?: any; 8 | viewId?: string; 9 | chart?: IChart; 10 | facet?: IFacet; 11 | legend?: ILegend; 12 | views?: IViewConfig; 13 | } 14 | 15 | type IMainConfig = ISMain & IView; 16 | 17 | export default IMainConfig; 18 | -------------------------------------------------------------------------------- /packages/viser/src/typed/IScale.ts: -------------------------------------------------------------------------------- 1 | type formatterFunc = (val: number) => string | number; 2 | 3 | interface ICommonScale { 4 | dataKey: string; 5 | type?: string; 6 | formatter?: string | formatterFunc; 7 | range?: number[]; 8 | alias?: string; 9 | tickCount?: number; 10 | ticks?: number[]; 11 | } 12 | 13 | interface ILinearCommonScale { 14 | nice?: boolean; 15 | min?: number; 16 | max?: number; 17 | minLimit?: number; 18 | maxLimit?: number; 19 | tickInterval?: number; 20 | } 21 | 22 | export type ILinearScale = ICommonScale & ILinearCommonScale; 23 | 24 | interface ISCatScale { 25 | values?: string; 26 | } 27 | 28 | export type ICatScale = ILinearCommonScale & ISCatScale; 29 | 30 | interface ISLogScale { 31 | base?: number; 32 | } 33 | 34 | export type ILogScale = ICommonScale & ILinearCommonScale & ISLogScale; 35 | 36 | interface ISPowScale { 37 | exponent?: number; 38 | } 39 | 40 | export type IPowScale = ICommonScale & ILinearCommonScale & ISPowScale; 41 | 42 | interface ISTimeScale { 43 | mask?: string; 44 | } 45 | 46 | export type ITimeScale = ICommonScale & ILinearCommonScale & ISTimeScale; 47 | 48 | interface ISTimeCatScale { 49 | nice?: boolean; 50 | mask?: string; 51 | values?: string; 52 | } 53 | 54 | export type ITimeCatScale = ILinearCommonScale & ISTimeCatScale; 55 | 56 | export type IScale = ILinearScale | ICatScale | ILogScale | IPowScale | ITimeScale | ITimeCatScale; 57 | 58 | type IScaleConfig = IScale | IScale[]; 59 | 60 | export default IScaleConfig; 61 | -------------------------------------------------------------------------------- /packages/viser/src/typed/ISeries.ts: -------------------------------------------------------------------------------- 1 | type eventFunc = (ev: any, chart: any) => void; 2 | 3 | export interface ISeries { 4 | quickType?: string; 5 | position?: string | string[]; 6 | gemo?: string; 7 | adjust?: string | string[] | object[]; 8 | color?: any; 9 | shape?: any; 10 | size?: any; 11 | opacity?: any; 12 | label?: any; 13 | tooltip?: any; 14 | style?: any; 15 | select?: any; 16 | active?: boolean | object | [boolean, object]; 17 | animate?: object; 18 | onMouseDown?: eventFunc; 19 | onMouseMove?: eventFunc; 20 | onMouseLeave?: eventFunc; 21 | onMouseUp?: eventFunc; 22 | onClick?: eventFunc; 23 | onDblClick?: eventFunc; 24 | onTouchStart?: eventFunc; 25 | onTouchMove?: eventFunc; 26 | onTouchEnd?: eventFunc; 27 | onLabelMouseDown?: eventFunc; 28 | onLabelMouseMove?: eventFunc; 29 | onLabelMouseLeave?: eventFunc; 30 | onLabelMouseUp?: eventFunc; 31 | onLabelClick?: eventFunc; 32 | onLabelDblClick?: eventFunc; 33 | onLableTouchStart?: eventFunc; 34 | onLabelTouchMove?: eventFunc; 35 | onLabelTouchEnd?: eventFunc; 36 | } 37 | 38 | type ISeriesConfig = ISeries | ISeries[]; 39 | 40 | export default ISeriesConfig; 41 | -------------------------------------------------------------------------------- /packages/viser/src/typed/IShapePoints.ts: -------------------------------------------------------------------------------- 1 | interface IShapePoints { 2 | x?: number; 3 | y?: number & number[]; 4 | y0?: number; 5 | size?: number; 6 | } 7 | 8 | export default IShapePoints; 9 | -------------------------------------------------------------------------------- /packages/viser/src/typed/ISlider.ts: -------------------------------------------------------------------------------- 1 | 2 | interface ISliderConfig { 3 | xAxis: string; 4 | yAxis: string; 5 | data: any[]; 6 | container: string; 7 | width?: number | string; 8 | height?: number | string; 9 | padding?: number | number[]; 10 | start?: string; 11 | end?: string; 12 | minSpan?: number; 13 | maxSpan?: number; 14 | scales?: any; 15 | fillerStyle?: any; 16 | backgroundStyle?: any; 17 | textStyle?: any; 18 | handleStyle?: any; 19 | backgroundChart?: any; 20 | onChange?: (opts: any) => void; 21 | } 22 | 23 | export default ISliderConfig; 24 | -------------------------------------------------------------------------------- /packages/viser/src/typed/IStyle.ts: -------------------------------------------------------------------------------- 1 | export interface ITextStyle { 2 | fontSize?: number | string; 3 | fontFamily?: string; 4 | fontWeight?: number | string; 5 | textAlign?: string; 6 | fill?: string; 7 | lineHeight?: number; 8 | textBaseline?: string; 9 | rotate?: number; 10 | shadowBlur?: number; 11 | shadowColor?: string; 12 | opacity?: number; 13 | } 14 | 15 | export interface ILineStyle { 16 | stroke?: string; 17 | strokeOpacity?: number; 18 | lineWidth?: number; 19 | lineHeight?: number; 20 | lineDash?: number[]; 21 | length?: number; 22 | textAlign?: string; 23 | } 24 | -------------------------------------------------------------------------------- /packages/viser/src/typed/ITooltip.ts: -------------------------------------------------------------------------------- 1 | import * as IStyle from './IStyle'; 2 | 3 | type eventFunc = (ev: any, chart: any) => void; 4 | 5 | type htmlContentFunc = (title: string, items: any) => string; 6 | 7 | type triggerType = 'mousemove' | 'click' | 'none'; 8 | 9 | interface ICrosshairs { 10 | type?: string; 11 | style?: IStyle.ILineStyle; 12 | } 13 | 14 | export interface ITooltip { 15 | x?: number; 16 | y?: number; 17 | items?: object[]; 18 | show?: boolean; 19 | 20 | triggerOn?: triggerType; 21 | showTitle?: boolean; 22 | title?: string; 23 | crosshairs?: boolean | string | ICrosshairs; 24 | offset?: number; 25 | inPlot?: boolean; 26 | follow?: boolean; 27 | shared?: boolean; 28 | enterable?: boolean; 29 | position?: string; 30 | hideMarkers?: boolean; 31 | containerTpl?: string; 32 | itemTpl?: string; 33 | type?: string; 34 | useHtml?: boolean; 35 | htmlContent?: string | htmlContentFunc; 36 | g2Tooltip?: any; 37 | g2TooltipTitle?: any; 38 | g2TooltipList?: any; 39 | g2TooltipListItem?: any; 40 | g2TooltipMarker?: any; 41 | 42 | onShow?: eventFunc; 43 | onHide?: eventFunc; 44 | onChange?: eventFunc; 45 | 46 | defaultPoint?: any; 47 | 48 | // Deprecated 49 | timeStamp?: number; 50 | plotRange?: object; 51 | } 52 | 53 | type ITooltipConfig = boolean | ITooltip; 54 | 55 | export default ITooltipConfig; 56 | -------------------------------------------------------------------------------- /packages/viser/src/typed/IView.ts: -------------------------------------------------------------------------------- 1 | import IAxis from './IAxis'; 2 | import ICoord from './ICoord'; 3 | import IFilter from './IFilter'; 4 | import IGuide from './IGuide'; 5 | import IScale from './IScale'; 6 | import ISeries from './ISeries'; 7 | import ITooltip from './ITooltip'; 8 | 9 | export interface IView { 10 | data?: any; 11 | viewId?: string; 12 | dataView?: any; 13 | coord?: ICoord; 14 | scale?: IScale; 15 | filter?: IFilter; 16 | axis?: IAxis; 17 | guide?: IGuide; 18 | series?: ISeries; 19 | tooltip?: ITooltip; 20 | start?: any; 21 | end?: any; 22 | } 23 | 24 | type IViewConfig = IView | IView[]; 25 | 26 | export default IViewConfig; 27 | -------------------------------------------------------------------------------- /packages/viser/src/utils/CustomizeUtils.ts: -------------------------------------------------------------------------------- 1 | declare const require: any; 2 | // tslint:disable-next-line:no-var-requires 3 | const G2 = require('@antv/g2'); 4 | 5 | export const registerShape = (geoName: string, shapeName: string, shapeFun: any) => { 6 | G2.Shape.registerShape(geoName, shapeName, shapeFun); 7 | }; 8 | 9 | export const registerAnimation = (animationType: string, animationName: string, animationFun: any) => { 10 | G2.Animate.registerAnimation(animationType, animationName, animationFun); 11 | }; 12 | -------------------------------------------------------------------------------- /packages/viser/src/utils/EventUtils.ts: -------------------------------------------------------------------------------- 1 | import * as _ from 'lodash'; 2 | 3 | // tslint:disable-next-line:max-line-length 4 | const regEventName = /on(.+)(MouseEnter|MouseMove|MouseLeave|Click|DdlClick|MouseDown|MouseUp|TouchStart|TouchMove|TouchEnd)/; 5 | 6 | /** 7 | * [setSEvent] 8 | * ref: https://antv.alipay.com/zh-cn/g2/3.x/tutorial/chart-event.html 9 | * Set event for single element of components, like 'onTitleClick' on Tooltip. 10 | * Notice that the component's event like 'onClick' will not be include in this method. Please use 'setEvent' instead. 11 | */ 12 | export function setSEvent(chart: any, itemname: string, keyname: string, content: any) { 13 | if (_.isEmpty(keyname)) { return; } 14 | 15 | const parseEventItem = regEventName.exec(keyname); 16 | if (!parseEventItem || parseEventItem.length <= 2) { return; } 17 | 18 | const lowerEventItem = parseEventItem[1].toLowerCase(); 19 | const lowerEventName = parseEventItem[2].toLowerCase(); 20 | const eventItem = `${itemname}-${lowerEventItem}`; 21 | 22 | chart.on(`${eventItem}:${lowerEventName}`, (ev: any) => { 23 | if (content) { 24 | content(ev, chart); 25 | } 26 | }); 27 | } 28 | 29 | /** 30 | * [setEvent] 31 | * ref: https://antv.alipay.com/zh-cn/g2/3.x/tutorial/chart-event.html 32 | * Set event for whole component, like 'onClick' on Tooltip. 33 | */ 34 | export function setEvent(chart: any, name: string, item: any) { 35 | if (_.isEmpty(item)) { return; } 36 | 37 | const events = Object.keys(item).filter((entry) => /^on/.test(entry)); 38 | if (_.isEmpty(events)) { return; } 39 | events.forEach((entry: any) => { 40 | const eventName = entry.slice(2, entry.length); 41 | const eventLowerCase = eventName.toLowerCase(); 42 | const content = item[entry]; 43 | 44 | // geom label event should be chart.on('label:xx') 45 | if (item.gemo && eventLowerCase.indexOf('label') >= 0) { 46 | const eventType = eventLowerCase.replace('label', ''); 47 | chart.on(`label:${eventType}`, (ev: any) => { 48 | if (content) { 49 | content(ev, chart); 50 | } 51 | }); 52 | return; 53 | } 54 | if (name) { 55 | chart.on(`${name}:${eventLowerCase}`, (ev: any) => { 56 | if (content) { 57 | content(ev, chart); 58 | } 59 | }); 60 | } else { 61 | chart.on(eventLowerCase, (ev: any) => { 62 | if (content) { 63 | content(ev, chart); 64 | } 65 | }); 66 | } 67 | }); 68 | } 69 | -------------------------------------------------------------------------------- /packages/viser/src/utils/MathUtils.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Calculate the vertor normal to the specified verctor 3 | * @param vector number[] 4 | */ 5 | export const calculateUnitNormal = (vector: number[]) => { 6 | const [a = 0, b = 0] = vector; 7 | const magnitud = Math.pow(a, 2) + Math.pow(b, 2); 8 | 9 | if (magnitud <= 0) { 10 | return [0, 0]; 11 | } 12 | 13 | if (a === 0) { return [1, 0]; } 14 | const tanTheta = b / a; 15 | const theta = Math.atan(tanTheta); 16 | const normalTheta = theta + Math.PI / 2; 17 | 18 | return [Math.cos(normalTheta), Math.sin(normalTheta)]; 19 | }; 20 | -------------------------------------------------------------------------------- /packages/viser/src/utils/PolarUtils.ts: -------------------------------------------------------------------------------- 1 | export const degreeToRadian = (angle: number): number => { 2 | return angle * Math.PI / 180; 3 | }; 4 | 5 | export const radianToDegree = (angleInRadian: number): number => { 6 | return angleInRadian * 180 / Math.PI; 7 | }; 8 | 9 | export const polarToCartesian = (cx: number, cy: number, radius: number, angle: number) => { 10 | const radian = degreeToRadian(angle); 11 | return { 12 | x: cx + Math.cos(radian) * radius, 13 | y: cy + Math.sin(radian) * radius, 14 | }; 15 | }; 16 | -------------------------------------------------------------------------------- /packages/viser/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "es2015", 4 | "outDir": "es", 5 | "noUnusedLocals": true, 6 | "strict": true, 7 | "removeComments": true, 8 | "preserveConstEnums": true, 9 | "sourceMap": true, 10 | "moduleResolution": "node", 11 | "declaration": true, 12 | "lib": [ 13 | "dom", 14 | "es2015" 15 | ] 16 | }, 17 | "include": [ 18 | "src/**/*" 19 | ], 20 | "exclude": [ 21 | "node_modules" 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /packages/viser/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "error", 3 | "extends": [ 4 | "tslint:latest" 5 | ], 6 | "jsRules": {}, 7 | "rules": { 8 | "quotemark": [true, "single"], 9 | "no-console": [true, "log", "warn"], 10 | "object-literal-sort-keys": false 11 | }, 12 | "rulesDirectory": [] 13 | } 14 | -------------------------------------------------------------------------------- /packages/viser/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpack = require('webpack'); 3 | const env = process.env.NODE_ENV; 4 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; 5 | 6 | let config = { 7 | mode: 'production', 8 | 9 | entry: './lib/index.js', 10 | 11 | output: { 12 | path: path.resolve(__dirname, 'umd'), 13 | filename: 'viser.min.js', 14 | library: 'Viser', 15 | libraryTarget: 'umd', 16 | }, 17 | 18 | resolve: { 19 | extensions: ['.js', '.json'], 20 | }, 21 | 22 | module: { 23 | rules: [{ 24 | test: /\.js?$/, 25 | exclude: /node_modules/, 26 | use: { 27 | loader: "babel-loader" 28 | } 29 | }] 30 | }, 31 | 32 | plugins: [], 33 | }; 34 | 35 | if (env === 'analyse') { 36 | config.plugins.push(new BundleAnalyzerPlugin()); 37 | } 38 | 39 | module.exports = config; 40 | -------------------------------------------------------------------------------- /scripts/publish.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | # publish viser 5 | lerna exec --scope viser -- npm run build 6 | lerna exec --scope viser-cell -- npm run build 7 | lerna exec --scope viser-graph -- npm run build 8 | lerna publish --scope viser 9 | lerna publish --scope viser-cell 10 | lerna publish --scope viser-graph 11 | 12 | # publish viser modules 13 | lerna exec --scope viser-* --ignore viser-cell* -- npm run build 14 | lerna exec --scope viser-cell-* -- npm run build 15 | lerna exec --scope viser-graph-* -- npm run build 16 | lerna publish --scope viser-* --ignore viser-cell* 17 | lerna publish --scope viser-cell-* 18 | lerna publish --scope viser-graph-* 19 | --------------------------------------------------------------------------------