From d0636bbf030cb3bba454ed456f773a43a2716ce4 Mon Sep 17 00:00:00 2001 From: break60 <790061044@qq.com> Date: Fri, 1 Nov 2019 18:48:40 +0800 Subject: [PATCH] Replace ans charts with source code (#1144) * Dependency workflow add dependency correction value * Download workflow instance map width adjustment and change "desc" field to "description" * The third-party library that builds the dependency is recommended to be placed in 'devDependencies' * Tree chart and Gantt chart style modification * The workflow instance can be deleted only when its status is success, failure, stop and pause. * change desc to description * Maximum width of tooltip is set to 500px, note the copyright number of login page * Delete copyright number * No tenant in the list of selected tenants the default is default, and the status not shown in the repair page * repair * Repair security center module prompt * Remove blank character during verification * Remove blank character during verification * Non admin users cannot create users, tenants, alarm groups, queues and worker groups * Remove CI windows detection * The value of loadaverage should be two decimal places * Add license * delete docs * update package.json * delete LICENSE * Display icon when there is no data in process definition * Worker group add IP format verification * Modify MySQL page of monitoring center * DB page rename and background color modification * IO build replace with source code * Replace ans charts with source code --- dolphinscheduler-ui/src/js/conf/home/index.js | 2 +- .../pages/index/_source/commandStateCount.vue | 2 +- .../pages/index/_source/defineUserCount.vue | 2 +- .../pages/index/_source/processStateCount.vue | 2 +- .../pages/index/_source/queueCount.vue | 2 +- .../pages/index/_source/taskCtatusCount.vue | 2 +- .../src/js/module/ana-charts/common.js | 61 +++ .../src/js/module/ana-charts/index.js | 78 +++ .../module/ana-charts/packages/bar/index.js | 326 ++++++++++++ .../src/js/module/ana-charts/packages/base.js | 76 +++ .../ana-charts/packages/funnel/index.js | 144 +++++ .../module/ana-charts/packages/line/index.js | 204 ++++++++ .../module/ana-charts/packages/pie/index.js | 121 +++++ .../module/ana-charts/packages/radar/index.js | 129 +++++ .../ana-charts/packages/scatter/index.js | 149 ++++++ .../src/lib/@analysys/ana-charts/README.md | 405 -------------- .../lib/@analysys/ana-charts/build/config.js | 60 --- .../ana-charts/build/webpack.config.prod.js | 104 ---- .../lib/@analysys/ana-charts/dist/index.js | 2 - .../@analysys/ana-charts/dist/index.js.map | 1 - .../lib/@analysys/ana-charts/example/app.vue | 87 --- .../@analysys/ana-charts/example/index.html | 15 - .../lib/@analysys/ana-charts/example/index.js | 14 - .../@analysys/ana-charts/example/mock/data.js | 58 -- .../ana-charts/example/mock/theme.json | 494 ------------------ .../ana-charts/example/packages/bar.vue | 72 --- .../ana-charts/example/packages/funnel.vue | 23 - .../ana-charts/example/packages/line.vue | 29 - .../ana-charts/example/packages/pie.vue | 29 - .../ana-charts/example/packages/radar.vue | 23 - .../ana-charts/example/packages/scatter.vue | 23 - .../ana-charts/example/router/index.js | 53 -- .../ana-charts/example/styles/main.scss | 77 --- .../src/lib/@analysys/ana-charts/package.json | 65 --- .../@analysys/ana-charts/postcss.config.js | 7 - 35 files changed, 1294 insertions(+), 1647 deletions(-) create mode 100755 dolphinscheduler-ui/src/js/module/ana-charts/common.js create mode 100755 dolphinscheduler-ui/src/js/module/ana-charts/index.js create mode 100755 dolphinscheduler-ui/src/js/module/ana-charts/packages/bar/index.js create mode 100755 dolphinscheduler-ui/src/js/module/ana-charts/packages/base.js create mode 100755 dolphinscheduler-ui/src/js/module/ana-charts/packages/funnel/index.js create mode 100755 dolphinscheduler-ui/src/js/module/ana-charts/packages/line/index.js create mode 100755 dolphinscheduler-ui/src/js/module/ana-charts/packages/pie/index.js create mode 100755 dolphinscheduler-ui/src/js/module/ana-charts/packages/radar/index.js create mode 100755 dolphinscheduler-ui/src/js/module/ana-charts/packages/scatter/index.js delete mode 100644 dolphinscheduler-ui/src/lib/@analysys/ana-charts/README.md delete mode 100644 dolphinscheduler-ui/src/lib/@analysys/ana-charts/build/config.js delete mode 100644 dolphinscheduler-ui/src/lib/@analysys/ana-charts/build/webpack.config.prod.js delete mode 100644 dolphinscheduler-ui/src/lib/@analysys/ana-charts/dist/index.js delete mode 100644 dolphinscheduler-ui/src/lib/@analysys/ana-charts/dist/index.js.map delete mode 100644 dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/app.vue delete mode 100644 dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/index.html delete mode 100644 dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/index.js delete mode 100644 dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/mock/data.js delete mode 100644 dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/mock/theme.json delete mode 100644 dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/packages/bar.vue delete mode 100644 dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/packages/funnel.vue delete mode 100644 dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/packages/line.vue delete mode 100644 dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/packages/pie.vue delete mode 100644 dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/packages/radar.vue delete mode 100644 dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/packages/scatter.vue delete mode 100644 dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/router/index.js delete mode 100644 dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/styles/main.scss delete mode 100644 dolphinscheduler-ui/src/lib/@analysys/ana-charts/package.json delete mode 100644 dolphinscheduler-ui/src/lib/@analysys/ana-charts/postcss.config.js diff --git a/dolphinscheduler-ui/src/js/conf/home/index.js b/dolphinscheduler-ui/src/js/conf/home/index.js index 6099fb58af..cb134492ec 100644 --- a/dolphinscheduler-ui/src/js/conf/home/index.js +++ b/dolphinscheduler-ui/src/js/conf/home/index.js @@ -24,7 +24,7 @@ import router from './router' import store from './store' import i18n from '@/module/i18n' import { sync } from 'vuex-router-sync' -import Chart from '~/@analysys/ana-charts' +import Chart from '@/module/ana-charts' import '@/module/filter/formatDate' import themeData from '@/module/echarts/themeData.json' import Permissions from '@/module/permissions' diff --git a/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/index/_source/commandStateCount.vue b/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/index/_source/commandStateCount.vue index 657a9d9c31..f640a1e3c4 100644 --- a/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/index/_source/commandStateCount.vue +++ b/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/index/_source/commandStateCount.vue @@ -30,7 +30,7 @@ import _ from 'lodash' import { mapActions } from 'vuex' import { simple } from './chartConfig' - import Chart from '~/@analysys/ana-charts' + import Chart from '@/module/ana-charts' import mNoData from '@/module/components/noData/noData' export default { diff --git a/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/index/_source/defineUserCount.vue b/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/index/_source/defineUserCount.vue index b825f5025f..078d747327 100644 --- a/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/index/_source/defineUserCount.vue +++ b/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/index/_source/defineUserCount.vue @@ -30,7 +30,7 @@ import _ from 'lodash' import { mapActions } from 'vuex' import { bar } from './chartConfig' - import Chart from '~/@analysys/ana-charts' + import Chart from '@/module/ana-charts' import mNoData from '@/module/components/noData/noData' export default { name: 'define-user-count', diff --git a/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/index/_source/processStateCount.vue b/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/index/_source/processStateCount.vue index 746bcfb12b..c21579a434 100644 --- a/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/index/_source/processStateCount.vue +++ b/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/index/_source/processStateCount.vue @@ -48,7 +48,7 @@ import _ from 'lodash' import { mapActions } from 'vuex' import { pie } from './chartConfig' - import Chart from '~/@analysys/ana-charts' + import Chart from '@/module/ana-charts' import mNoData from '@/module/components/noData/noData' import { stateType } from '@/conf/home/pages/projects/pages/_source/instanceConditions/common' export default { diff --git a/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/index/_source/queueCount.vue b/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/index/_source/queueCount.vue index ea93e077e9..00eef39ea2 100644 --- a/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/index/_source/queueCount.vue +++ b/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/index/_source/queueCount.vue @@ -48,7 +48,7 @@ import _ from 'lodash' import { mapActions } from 'vuex' import { pie } from './chartConfig' - import Chart from '~/@analysys/ana-charts' + import Chart from '@/module/ana-charts' import mNoData from '@/module/components/noData/noData' export default { name: 'queue-count', diff --git a/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/index/_source/taskCtatusCount.vue b/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/index/_source/taskCtatusCount.vue index a630295548..928852d44f 100644 --- a/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/index/_source/taskCtatusCount.vue +++ b/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/index/_source/taskCtatusCount.vue @@ -52,7 +52,7 @@ import _ from 'lodash' import { mapActions } from 'vuex' import { pie } from './chartConfig' - import Chart from '~/@analysys/ana-charts' + import Chart from '@/module/ana-charts' import mNoData from '@/module/components/noData/noData' import { stateType } from '@/conf/home/pages/projects/pages/_source/instanceConditions/common' diff --git a/dolphinscheduler-ui/src/js/module/ana-charts/common.js b/dolphinscheduler-ui/src/js/module/ana-charts/common.js new file mode 100755 index 0000000000..87f25c32ca --- /dev/null +++ b/dolphinscheduler-ui/src/js/module/ana-charts/common.js @@ -0,0 +1,61 @@ +/** + * 根据参数找到容器并初始化图表,然后返回一个或者一组图表实例 + * @param {*} Target 图表组件类 + * @param {*} el 选择器或者 DOM 对象 + * @param {*} data 数据源 + * @param {*} options 可选项 + */ +export const init = (Target, el, data, options) => { + const list = getChartContainers(el) + const settings = Object.assign({}, { data }, options) + const charts = list.map(element => { + return new Target(element, settings) + }) + return charts.length === 1 ? charts[0] : charts +} + +/** + * 统一图表容器为 DOM 元素数组 + * @param {*} el 选择器或者 DOM 对象 + */ +function getChartContainers (el) { + // 未传参数,直接返回 + if (!el) { + return + } + if (typeof el === 'string') { + if (el.startsWith('#')) { + el = document.getElementById(el.slice(1)) + } else if (el.startsWith('.')) { + el = document.getElementsByClassName(el.slice(1)) + } else { + return + } + } + if (!el) { + throw new Error('找不到对应的dom对象!') + } + let list + if (HTMLElement.prototype.isPrototypeOf(el)) { + list = new Array(el) + } else { + list = Array.from(el) + } + if (!list) { + throw new Error('未找到对应的dom对象!') + } + return list +} + +/** + * 检测在指定对象中是否存在指定的属性名 + * @param {Object} model 待检测模型 + * @param {...any} params 待检测属性名 + */ +export const checkKeyInModel = (model, ...params) => { + for (const key of params) { + if (!model.hasOwnProperty(key)) { + throw new Error('数据格式错误!未找到指定属性:' + key) + } + } +} diff --git a/dolphinscheduler-ui/src/js/module/ana-charts/index.js b/dolphinscheduler-ui/src/js/module/ana-charts/index.js new file mode 100755 index 0000000000..437c431058 --- /dev/null +++ b/dolphinscheduler-ui/src/js/module/ana-charts/index.js @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import echarts from 'echarts' + +import Line from './packages/line' +import Bar from './packages/bar' +import Pie from './packages/pie' +import Radar from './packages/radar' +import Funnel from './packages/funnel' +import Scatter from './packages/scatter' +import { checkKeyInModel, init } from './common' + +const components = { + Line, + Bar, + Pie, + Radar, + Funnel, + Scatter +} + +const Chart = { + // 默认配置 + settings: {}, + /** + * 配置全局属性 + * @param {Object} options 全局配置项 + */ + config (options) { + const { theme } = options + // 注册主题 + if (theme) { + checkKeyInModel(theme, 'name', 'data') + echarts.registerTheme(theme.name, theme.data) + if (theme.default) { + Chart.settings.defaultTheme = theme.name + } + } + } +} + +// 注入不同组件对应方法 +for (const key in components) { + if (components.hasOwnProperty(key)) { + Chart[key.toLowerCase()] = (el, data, options) => { + return init(components[key], el, data, options) + } + } +} + +export { + Line, + Bar, + Pie, + Radar, + Funnel, + Scatter +} + +export default Chart + +if (typeof window !== 'undefined') { + window.Chart = Chart +} diff --git a/dolphinscheduler-ui/src/js/module/ana-charts/packages/bar/index.js b/dolphinscheduler-ui/src/js/module/ana-charts/packages/bar/index.js new file mode 100755 index 0000000000..4f31c0031e --- /dev/null +++ b/dolphinscheduler-ui/src/js/module/ana-charts/packages/bar/index.js @@ -0,0 +1,326 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Base from '../base' +import { checkKeyInModel, init } from '../../common' + +const TYPE = 'bar' + +/** + * 柱状图 + */ +export default class Bar extends Base { + /** + * 单独导出时调用的初始化方法 + * @param {*} el 选择器或者 DOM 对象 + * @param {*} data 数据源 + * @param {*} options 可选项 + */ + static init (el, data, options) { + return init(Bar, el, data, options) + } + + /** + * 将用户配置转换为符合 ECharts API 格式的配置格式 + */ + transform () { + const { data = [] } = this.settings + + if (data.length === 0) { + throw new Error('数据源为空!') + } + + if (Object.keys(data[0]).length > 2) { + return this.setMultipleBars() + } else { + this.simple = true + return this.setSingleBar() + } + } + + /** + * 单条柱 + */ + setSingleBar () { + const { + // 数据 + data = [], + // 属性字典 + keyMap = { + xAxisKey: 'key', + dataKey: 'value' + }, + // 图表标题 + title = '单条柱状图' + } = this.settings + + // x 轴对应属性名,数据值对应的属性名 + const { xAxisKey, dataKey } = keyMap + checkKeyInModel(data[0], xAxisKey, dataKey) + + const series = [{ + type: TYPE, + data: [] + }] + const xAxis = { + type: 'category', + data: [] + } + + for (let i = 0; i < data.length; i++) { + xAxis.data.push(data[i][xAxisKey]) + series[0].data.push(data[i][dataKey]) + } + + return { title, xAxis, series } + } + + /** + * 多条柱 + */ + setMultipleBars () { + const { + // 数据 + data = [], + // 属性字典 + keyMap = { + xAxisKey: 'key', + legendKey: 'typeName', + dataKey: 'value' + }, + // 图表标题 + title = '多条柱状图', + // 折柱混合时,指定的折线数据索引 + lineTypes + } = this.settings + + // x 轴对应属性名,图例对应的属性名,数据值对应的属性名 + const { xAxisKey, legendKey, dataKey } = keyMap + // 是否使用时间轴数据 + const timeline = Object.keys(data[0]).length === 4 + const timelineKey = keyMap.timelineKey || 'timeline' + if (timeline) { + checkKeyInModel(data[0], xAxisKey, legendKey, dataKey, timelineKey) + } else { + checkKeyInModel(data[0], xAxisKey, legendKey, dataKey) + } + + // 规范折柱混合索引 + let lineTypeList = [] + if (lineTypes) { + if (!Array.isArray(lineTypes)) { + lineTypeList = [lineTypes] + } else { + lineTypeList = lineTypes + } + } + + // 时间轴默认配置 + const timelineOptions = { + timeline: { + axisType: 'category', + autoPlay: true, + playInterval: 1000, + data: [] + }, + options: [] + } + + // 初始值 + const legendData = [] + const series = [] + const xAxis = { + type: 'category', + data: [] + } + for (let i = 0; i < data.length; i++) { + const legendItem = data[i][legendKey] + const xAxisItem = data[i][xAxisKey] + const dataItem = data[i][dataKey] + + // 图例 + if (!legendData.includes(legendItem)) { + legendData.push(legendItem) + } + + // x 轴 + if (!xAxis.data.includes(xAxisItem)) { + xAxis.data.push(xAxisItem) + } + + // 时间轴 + if (timeline) { + const timelineItem = data[i][timelineKey] + // 设置时间轴 label + if (!timelineOptions.timeline.data.includes(timelineItem)) { + timelineOptions.timeline.data.push(timelineItem) + } + // 通用的系列配置 + if (!series.some(s => s.name === legendItem)) { + let seriesType = TYPE + if (lineTypeList.length !== 0 && lineTypeList.includes(legendItem)) { + seriesType = 'line' + } + series.push({ + name: legendItem, + type: seriesType + }) + } + // 系列数据 + let targetOptions = timelineOptions.options.find(o => o._helpName === timelineItem) + if (!targetOptions) { + // 初始化 option + targetOptions = { + _helpName: timelineItem, + title: { text: title.replace('$timeline', timelineItem) }, + series: [] + } + timelineOptions.options.push(targetOptions) + } + let targetSeries = targetOptions.series.find(d => d._helpName === legendItem) + if (!targetSeries) { + // 初始化系列数据 + targetSeries = { + _helpName: legendItem, + data: [] + } + targetOptions.series.push(targetSeries) + } + targetSeries.data.push(dataItem) + } else { + // 非时间轴数据处理 + let targetSeries = series.find(s => s.name === legendItem) + if (!targetSeries) { + let seriesType = TYPE + if (lineTypeList.length !== 0 && lineTypeList.includes(legendItem)) { + seriesType = 'line' + } + targetSeries = { + name: legendItem, + type: seriesType, + data: [] + } + series.push(targetSeries) + } + targetSeries.data.push(dataItem) + } + } + + if (timeline) { + return { title, xAxis, series, legendData, timelineOptions } + } + return { title, xAxis, series, legendData } + } + + /** + * 绘制图表 + */ + apply () { + const { title, xAxis, series, legendData, timelineOptions } = this.options + const { + // 是否为横向图 + reverseAxis = false, + // 自定义 y 轴 + yAxis, + // 是否为堆叠图 + stack = false, + // 注入配置到 series + insertSeries + } = this.settings + const valueAxis = { type: 'value' } + let yAxisModel = reverseAxis ? xAxis : valueAxis + let xAxisModel = reverseAxis ? valueAxis : xAxis + // 使用自定义 y 轴覆盖 + if (yAxis) { + yAxisModel = yAxis + } + // 设置堆叠图 + if (stack) { + series.forEach(set => { + set.stack = '总量' + set.label = { + normal: { + show: true, + position: reverseAxis ? 'insideRight' : 'insideTop' + } + } + }) + } + + let _series = series + if (insertSeries && insertSeries.length && series.length) { + _series = this.injectDataIntoSeries(insertSeries, _series) + } + + // 时间轴 + if (timelineOptions) { + let opts = { + baseOption: { + timeline: timelineOptions.timeline, + tooltip: { + trigger: 'axis' + }, + grid: { + top: 80, + bottom: 100, + containLabel: true + }, + legend: { + x: 'right', + data: legendData + }, + xAxis: xAxisModel, + yAxis: yAxisModel, + series: _series + }, + options: timelineOptions.options + } + + this.echart.setOption(opts, true) + this.echart.clear() + this.echart.setOption(opts, true) + } else { + // 简单图表标题为空时,图表垂直居中 + const top = !title && this.simple ? '3%' : 60 + + let opts = { + title: { + text: title + }, + tooltip: { + trigger: 'axis' + }, + grid: { + left: '3%', + right: '4%', + bottom: '3%', + top, + containLabel: true + }, + legend: { + data: legendData + }, + xAxis: xAxisModel, + yAxis: yAxisModel, + series: _series + } + + this.echart.setOption(opts, true) + this.echart.clear() + this.echart.setOption(opts, true) + } + } +} diff --git a/dolphinscheduler-ui/src/js/module/ana-charts/packages/base.js b/dolphinscheduler-ui/src/js/module/ana-charts/packages/base.js new file mode 100755 index 0000000000..0725dc8ea8 --- /dev/null +++ b/dolphinscheduler-ui/src/js/module/ana-charts/packages/base.js @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import echarts from 'echarts' +import Chart from '../index' + +export default class Base { + constructor (element, settings) { + this.settings = settings + const options = this.transform() + if (options) { + this.options = options + if (settings.theme) { + // 使用已经注册的自定义主题 + this.echart = echarts.init(element, settings.theme) + } else if (Chart.settings.defaultTheme) { + // 使用全局配置的主题 + this.echart = echarts.init(element, Chart.settings.defaultTheme) + } else { + this.echart = echarts.init(element) + } + // 响应窗口 resize 事件 + window.addEventListener('resize', () => this.echart.resize()) + this.apply() + } + } + + /** + * 刷新数据 + * @param {*} data 图表数据 + */ + setData (data) { + if (data && data.length !== 0) { + this.settings.data = data + this.options = this.transform() + this.apply() + } + } + + injectDataIntoSeries (data, series) { + data.forEach(o => { + if (o.index === 'all') { + delete o.index + series = series.map(item => { + return Object.assign({}, item, o) + }) + } else if (o.index === 'start') { + delete o.index + series[0] = Object.assign({}, series[0], o) + } else if (o.index === 'end') { + delete o.index + series[series.length - 1] = Object.assign({}, series[series.length - 1], o) + } else if (Array.isArray(o.index)) { + for (const i of o.index) { + if (series[i]) { + series[i] = Object.assign({}, series[i], o) + } + } + } + }) + return series + } +} diff --git a/dolphinscheduler-ui/src/js/module/ana-charts/packages/funnel/index.js b/dolphinscheduler-ui/src/js/module/ana-charts/packages/funnel/index.js new file mode 100755 index 0000000000..9204064d54 --- /dev/null +++ b/dolphinscheduler-ui/src/js/module/ana-charts/packages/funnel/index.js @@ -0,0 +1,144 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Base from '../base' +import { checkKeyInModel, init } from '../../common' + +const TYPE = 'funnel' + +/** + * 漏斗图 + */ +export default class Funnel extends Base { + /** + * 单独导出时调用的初始化方法 + * @param {*} el 选择器或者 DOM 对象 + * @param {*} data 数据源 + * @param {*} options 可选项 + */ + static init (el, data, options) { + return init(Funnel, el, data, options) + } + + /** + * 将用户配置转换为符合 ECharts API 格式的配置格式 + */ + transform () { + const { + // 数据 + data = [], + // 标题 + title = '漏斗图', + // 属性字典 + keyMap = { + textKey: 'key', + dataKey: 'value' + } + } = this.settings + + if (data.length === 0) { + throw new Error('数据源为空!') + } + + // 文本对应属性名,数据值对应的属性名 + const { textKey, dataKey } = keyMap + checkKeyInModel(data[0], textKey, dataKey) + + const legendData = [] + const series = [{ + type: TYPE, + left: '10%', + top: 60, + bottom: 60, + width: '80%', + min: 0, + max: 100, + minSize: '0%', + maxSize: '100%', + sort: 'descending', + gap: 2, + label: { + normal: { + show: true, + position: 'inside' + }, + emphasis: { + textStyle: { + fontSize: 20 + } + } + }, + labelLine: { + normal: { + length: 10, + lineStyle: { + width: 1, + type: 'solid' + } + } + }, + itemStyle: { + normal: { + borderColor: '#fff', + borderWidth: 1 + } + }, + data: [] + }] + + // 填充数据 + for (let i = 0; i < data.length; i++) { + const element = data[i] + const { [dataKey]: value, [textKey]: name, ...other } = element + const item = { + value, + name, + ...other, + _raw: element + } + series[0].data.push(item) + } + return { title, series, legendData } + } + + /** + * 绘制图表 + */ + apply () { + let { title, series, legendData } = this.options + + // 注入配置到series + let { insertSeries } = this.settings + let _series = series + if (insertSeries && insertSeries.length && series.length) { + _series = this.injectDataIntoSeries(insertSeries, _series) + } + + this.echart.setOption({ + title: { + text: title + }, + tooltip: { + trigger: 'item', + formatter: '{a}
{b} : {c}%' + }, + legend: { + data: legendData + }, + series: _series + }, true) + } +} diff --git a/dolphinscheduler-ui/src/js/module/ana-charts/packages/line/index.js b/dolphinscheduler-ui/src/js/module/ana-charts/packages/line/index.js new file mode 100755 index 0000000000..c2508b5d8e --- /dev/null +++ b/dolphinscheduler-ui/src/js/module/ana-charts/packages/line/index.js @@ -0,0 +1,204 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Base from '../base' +import { checkKeyInModel, init } from '../../common' + +const TYPE = 'line' + +/** + * 折线图 + */ +export default class Line extends Base { + /** + * 单独导出时调用的初始化方法 + * @param {*} el 选择器或者 DOM 对象 + * @param {*} data 数据源 + * @param {*} options 可选项 + */ + static init (el, data, options) { + return init(Line, el, data, options) + } + + /** + * 将用户配置转换为符合 ECharts API 格式的配置格式 + */ + transform () { + const { data = [] } = this.settings + + if (data.length === 0) { + throw new Error('数据源为空!') + } + + if (Object.keys(data[0]).length > 2) { + return this.setMultipleLines() + } else { + this.simple = true + return this.setSingleLine() + } + } + + /** + * 单条折线 + */ + setSingleLine () { + const { + // 数据 + data = [], + // 属性字典 + keyMap = { + xAxisKey: 'key', + dataKey: 'value' + }, + // 图表标题 + title = '单条折线图' + } = this.settings + + // x 轴对应属性名,数据值对应的属性名 + const { xAxisKey, dataKey } = keyMap + checkKeyInModel(data[0], xAxisKey, dataKey) + + const series = [{ + type: TYPE, + data: [] + }] + const xAxis = { + type: 'category', + data: [] + } + + for (let i = 0; i < data.length; i++) { + xAxis.data.push(data[i][xAxisKey]) + series[0].data.push(data[i][dataKey]) + } + + return { title, xAxis, series } + } + + /** + * 多条折线 + */ + setMultipleLines () { + const { + // 数据 + data = [], + // 属性字典 + keyMap = { + xAxisKey: 'key', + legendKey: 'typeName', + dataKey: 'value' + }, + // 图表标题 + title = '多条折线图' + } = this.settings + + // x 轴对应属性名,图例对应的属性名,数据值对应的属性名 + const { xAxisKey, legendKey, dataKey } = keyMap + checkKeyInModel(data[0], xAxisKey, legendKey, dataKey) + + const legendData = [] + const series = [] + const xAxis = { + type: 'category', + data: [] + } + + for (let i = 0; i < data.length; i++) { + const legendItem = data[i][legendKey] + const xAxisItem = data[i][xAxisKey] + const dataItem = data[i][dataKey] + + // 图例 + if (!legendData.includes(legendItem)) { + legendData.push(legendItem) + } + + // x 轴 + if (!xAxis.data.includes(xAxisItem)) { + xAxis.data.push(xAxisItem) + } + + // 系列 + let targetSeries = series.find(s => s.name === legendItem) + if (!targetSeries) { + targetSeries = { + name: legendItem, + type: TYPE, + data: [] + } + series.push(targetSeries) + } + targetSeries.data.push(dataItem) + } + + return { title, xAxis, series, legendData } + } + + /** + * 绘制图表 + */ + apply () { + const { title, xAxis, series, legendData = [] } = this.options + const { + // 是否为横向图 + reverseAxis = false, + // 自定义 y 轴 + yAxis, + // 注入配置到 series + insertSeries + } = this.settings + const valueAxis = { type: 'value' } + let yAxisModel = reverseAxis ? xAxis : valueAxis + let xAxisModel = reverseAxis ? valueAxis : xAxis + // 使用自定义 y 轴覆盖 + if (yAxis) { + yAxisModel = yAxis + } + // 简单图表标题为空时,图表垂直居中 + const top = !title && this.simple ? '3%' : 60 + + let _series = series + if (insertSeries && insertSeries.length && series.length) { + _series = this.injectDataIntoSeries(insertSeries, _series) + } + + let opts = { + title: { + text: title + }, + tooltip: { + trigger: 'axis' + }, + grid: { + left: '3%', + right: '4%', + bottom: '3%', + top, + containLabel: true + }, + legend: { + data: legendData + }, + xAxis: xAxisModel, + yAxis: yAxisModel, + series: _series + } + + this.echart.setOption(opts, true) + this.echart.clear() + this.echart.setOption(opts, true) + } +} diff --git a/dolphinscheduler-ui/src/js/module/ana-charts/packages/pie/index.js b/dolphinscheduler-ui/src/js/module/ana-charts/packages/pie/index.js new file mode 100755 index 0000000000..f77f5fd9bc --- /dev/null +++ b/dolphinscheduler-ui/src/js/module/ana-charts/packages/pie/index.js @@ -0,0 +1,121 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Base from '../base' +import { checkKeyInModel, init } from '../../common' + +const TYPE = 'pie' + +/** + * 饼图 + */ +export default class Pie extends Base { + /** + * 单独导出时调用的初始化方法 + * @param {*} el 选择器或者 DOM 对象 + * @param {*} data 数据源 + * @param {*} options 可选项 + */ + static init (el, data, options) { + return init(Pie, el, data, options) + } + + /** + * 将用户配置转换为符合 ECharts API 格式的配置格式 + */ + transform () { + const { + // 数据 + data = [], + // 标题 + title = '饼图', + // 是否环形图 + ring = false, + // 属性字典 + keyMap = { + textKey: 'key', + dataKey: 'value' + } + } = this.settings + + if (data.length === 0) { + throw new Error('数据源为空!') + } + + // 文本对应属性名,数据值对应的属性名 + const { textKey, dataKey } = keyMap + checkKeyInModel(data[0], textKey, dataKey) + + const legendData = [] + let radius = ring ? ['50%', '70%'] : '60%' + let center = title ? ['50%', '60%'] : ['50%', '50%'] + const series = [{ + radius: radius, + center: center, + type: TYPE, + data: [] + }] + + // 填充数据 + for (let i = 0; i < data.length; i++) { + const element = data[i] + const { [dataKey]: value, [textKey]: name, ...other } = element + const item = { + value, + name, + ...other, + _raw: element + } + series[0].data.push(item) + } + return { title, series, legendData } + } + + /** + * 绘制图表 + */ + apply () { + let { title, series, legendData } = this.options + + // 注入配置到series + let { insertSeries } = this.settings + let _series = series + if (insertSeries && insertSeries.length && series.length) { + _series = this.injectDataIntoSeries(insertSeries, _series) + } + + let opts = { + title: { + text: title, + x: 'center' + }, + tooltip: { + trigger: 'item', + formatter: '{b} : {c} ({d}%)' + }, + legend: { + orient: 'vertical', + left: 'left', + data: legendData + }, + series: _series + } + + this.echart.setOption(opts, true) + this.echart.clear() + this.echart.setOption(opts, true) + } +} diff --git a/dolphinscheduler-ui/src/js/module/ana-charts/packages/radar/index.js b/dolphinscheduler-ui/src/js/module/ana-charts/packages/radar/index.js new file mode 100755 index 0000000000..42802c623b --- /dev/null +++ b/dolphinscheduler-ui/src/js/module/ana-charts/packages/radar/index.js @@ -0,0 +1,129 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Base from '../base' +import { checkKeyInModel, init } from '../../common' + +const TYPE = 'radar' + +/** + * 雷达图 + */ +export default class Radar extends Base { + /** + * 单独导出时调用的初始化方法 + * @param {*} el 选择器或者 DOM 对象 + * @param {*} data 数据源 + * @param {*} options 可选项 + */ + static init (el, data, options) { + return init(Radar, el, data, options) + } + + /** + * 将用户配置转换为符合 ECharts API 格式的配置格式 + */ + transform () { + const { + // 数据 + data = [], + // 图表标题 + title = '雷达图', + // 属性字典 + keyMap = { + textKey: 'key', + legendKey: 'typeName', + dataKey: 'value' + } + } = this.settings + + if (data.length === 0) { + throw new Error('数据源为空!') + } + + // 文本对应属性名,图例对应的属性名,数据值对应的属性名 + const { textKey, legendKey, dataKey } = keyMap + checkKeyInModel(data[0], textKey, legendKey, dataKey) + + const legendData = [] + const seriesData = [] + const indicator = [] + + // 设置图例并初始化数据系列 + for (let i = 0; i < data.length; i++) { + const legendItem = data[i][legendKey] + const textItem = data[i][textKey] + const dataItem = data[i][dataKey] + + // 图例 + if (!legendData.includes(legendItem)) { + legendData.push(legendItem) + } + + // 系列 + let targetSeries = seriesData.find(s => s.name === legendItem) + if (!targetSeries) { + targetSeries = { + name: legendItem, + value: [], + _raw: [] + } + seriesData.push(targetSeries) + } + targetSeries.value.push(dataItem) + targetSeries._raw.push(data[i]) + + // 指标 + let targetIndicator = indicator.find(i => i.name === textItem) + if (!targetIndicator) { + indicator.push({ name: textItem }) + } + } + + return { title, seriesData, legendData, indicator } + } + + /** + * 绘制图表 + */ + apply () { + const { title, seriesData, legendData = [], indicator } = this.options + this.echart.setOption({ + title: { + text: title + }, + tooltip: {}, + legend: { + data: legendData + }, + radar: { + name: { + textStyle: { + color: '#fff', + backgroundColor: '#999', + borderRadius: 3, + padding: [3, 5] + } + }, + indicator + }, + series: [{ + type: TYPE, + data: seriesData + }] + }, true) + } +} diff --git a/dolphinscheduler-ui/src/js/module/ana-charts/packages/scatter/index.js b/dolphinscheduler-ui/src/js/module/ana-charts/packages/scatter/index.js new file mode 100755 index 0000000000..7c8baea472 --- /dev/null +++ b/dolphinscheduler-ui/src/js/module/ana-charts/packages/scatter/index.js @@ -0,0 +1,149 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import Base from '../base' +import { checkKeyInModel, init } from '../../common' + +const TYPE = 'scatter' + +/** + * 气泡图 + */ +export default class Scatter extends Base { + /** + * 单独导出时调用的初始化方法 + * @param {*} el 选择器或者 DOM 对象 + * @param {*} data 数据源 + * @param {*} options 可选项 + */ + static init (el, data, options) { + return init(Scatter, el, data, options) + } + + /** + * 将用户配置转换为符合 ECharts API 格式的配置格式 + */ + transform () { + const { + // 数据 + data = [], + // 图表标题 + title = '气泡图', + // 属性字典 + keyMap = { + xKey: 'x', + yKey: 'y', + sizeKey: 'size', + textKey: 'text', + legendKey: 'typeName' + } + } = this.settings + + if (data.length === 0) { + throw new Error('数据源为空!') + } + + const legendData = [] + const series = [] + + const { xKey, yKey, sizeKey, textKey, legendKey } = keyMap + checkKeyInModel(data[0], xKey, yKey, sizeKey, textKey, legendKey) + + for (let i = 0; i < data.length; i++) { + const { + [legendKey]: legendItem, + [xKey]: xValue, + [yKey]: yValue, + [sizeKey]: sizeValue, + [textKey]: textValue, + ...other + } = data[i] + + // 图例 + if (!legendData.includes(legendItem)) { + legendData.push(legendItem) + } + + // 系列 + let targetSeries = series.find(s => s.name === legendItem) + if (!targetSeries) { + targetSeries = { + type: TYPE, + name: legendItem, + data: [], + symbolSize: function (data) { + return Math.sqrt(data[2]) + }, + label: { + emphasis: { + show: true, + formatter: function (param) { + return param.data[3] + }, + position: 'top' + } + } + } + series.push(targetSeries) + } + targetSeries.data.push({ + value: [ + xValue, + yValue, + sizeValue, + textValue + ], + ...other, + _raw: data[i] + }) + } + + return { title, series, legendData } + } + + /** + * 绘制图表 + */ + apply () { + const { title, series, legendData = [] } = this.options + + let { + // 自定义 x 轴 + xAxis, + // 自定义 y 轴 + yAxis, + // 注入配置到 series + insertSeries + } = this.settings + let _series = series + if (insertSeries && insertSeries.length && series.length) { + _series = this.injectDataIntoSeries(insertSeries, _series) + } + + this.echart.setOption({ + title: { + text: title + }, + legend: { + right: 10, + data: legendData + }, + xAxis: xAxis || {}, + yAxis: yAxis || {}, + series: _series + }, true) + } +} diff --git a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/README.md b/dolphinscheduler-ui/src/lib/@analysys/ana-charts/README.md deleted file mode 100644 index d18db5aba9..0000000000 --- a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/README.md +++ /dev/null @@ -1,405 +0,0 @@ - -# ana-charts - -echarts 扩展 - -## 安装 - -``` -npm i @analysys/ana-charts -``` - -## 特性 - -- 统一的数据结构 -- 支持 ECharts 原生操作 - -## 快速开始 - -### 全量导入 - -```html - - - -``` - -### 按需导入 - -```html - - - -``` - -## APIs - -### 一般用法 - -``` js -const myChart = Chart.line(el, data, options) -// const myChart = Chart.bar(el, data, options) -// const myChart = Chart.pie(el, data, options) -// const myChart = Chart.radar(el, data, options) -// const myChart = Chart.funnel(el, data, options) -// const myChart = Chart.scatter(el, data, options) - -// 刷新数据 -myChart.setData(data) -``` - -### 注入属性 - -``` js -// 以 line 折线图为例,bar、funnel、pie、scatter 均可使用 -Chart.line(el, data, { - insertSeries: [ - { - // index 可选 `all`,`start`,`end`,也可指定需要被注入的索引数组,如 [0, 2, 4] - index: 'all', - // 以下属性会被注入到指定的序列中 - areaStyle: {} - } - ] -}) -``` - -### ECharts 对象 - -> 初始化图表后返回的对象上保存了 ECharts 对象的引用,可以通过该属性来设置图表配置和监听事件 - -``` js -const myChart = Chart.line(el, data, options) -// 设置可配置项 -myChart.echart.setOption({ - // 与 ECharts 参考文档用法一致 -}) -``` - -### 折线图 - -#### 基本用法 - -``` js -Chart.line('#chart', [ - { key: 'Monday', value: 1 }, - { key: 'Tuesday', value: 2 }, - { key: 'Wednesday', value: 3 }, - ... -]) -``` - -#### 多条折线图 - -``` js -Chart.line('#chart', [ - { typeName: 'apple', key: 'Monday', value: 1 }, - { typeName: 'apple', key: 'Tuesday', value: 2 }, - { typeName: 'apple', key: 'Wednesday', value: 3 }, - { typeName: 'pear', key: 'Monday', value: 11 }, - { typeName: 'pear', key: 'Tuesday', value: 21 }, - { typeName: 'pear', key: 'Wednesday', value: 31 }, - { typeName: 'banana', key: 'Monday', value: 31 }, - { typeName: 'banana', key: 'Tuesday', value: 32 }, - { typeName: 'banana', key: 'Wednesday', value: 33 }, - ... -]) -``` - -#### options 可配置参数 - -| 属性 | 说明 | required | 类型 | 默认值 | -| :----| :------| :--------| :---:| :------| -| title | 图表标题 | - | String | '单条折线图' 或 '多条折线图' | -| keyMap | 数据列表的属性字典 | - | Object | 详见后续属性 | -| keyMap.xAxisKey | x 轴对应的属性名称 | - | String | 'key' | -| keyMap.dataKey | 数据值对应的属性名称 | - | String | 'value' | -| keyMap.legendKey | 图例对应的属性名称 | - | String | 'typeName' | -| reverseAxis | 是否为横向图 | - | Boolean | false | - -### 柱状图 - -#### 基本用法 - -``` js -Chart.bar('#chart', [ - { key: 'Monday', value: 1 }, - { key: 'Tuesday', value: 2 }, - { key: 'Wednesday', value: 3 }, - ... -]) -``` - -#### 多条柱状图 - -``` js -Chart.bar('#chart', [ - { typeName: 'apple', key: 'Monday', value: 1 }, - { typeName: 'apple', key: 'Tuesday', value: 2 }, - { typeName: 'apple', key: 'Wednesday', value: 3 }, - { typeName: 'pear', key: 'Monday', value: 11 }, - { typeName: 'pear', key: 'Tuesday', value: 21 }, - { typeName: 'pear', key: 'Wednesday', value: 31 }, - { typeName: 'banana', key: 'Monday', value: 31 }, - { typeName: 'banana', key: 'Tuesday', value: 32 }, - { typeName: 'banana', key: 'Wednesday', value: 33 }, - ... -]) -``` - -#### 折柱混合图 - -``` js -Chart.bar('#chart', [ - { typeName: 'apple', key: 'Monday', value: 1 }, - { typeName: 'apple', key: 'Tuesday', value: 2 }, - { typeName: 'apple', key: 'Wednesday', value: 3 }, - { typeName: 'pear', key: 'Monday', value: 11 }, - { typeName: 'pear', key: 'Tuesday', value: 21 }, - { typeName: 'pear', key: 'Wednesday', value: 31 }, - { typeName: 'banana', key: 'Monday', value: 31 }, - { typeName: 'banana', key: 'Tuesday', value: 32 }, - { typeName: 'banana', key: 'Wednesday', value: 33 }, - ... -], { - lineTypes: ['banana'] -}) -``` - -#### 时间轴柱状图 - -``` js -Chart.bar('#chart', [ - { timeline: 2015, typeName: 'apple', key: 'Monday', value: 1 }, - { timeline: 2015, typeName: 'apple', key: 'Tuesday', value: 2 }, - { timeline: 2015, typeName: 'apple', key: 'Wednesday', value: 3 }, - { timeline: 2015, typeName: 'pear', key: 'Monday', value: 11 }, - { timeline: 2015, typeName: 'pear', key: 'Tuesday', value: 21 }, - { timeline: 2015, typeName: 'pear', key: 'Wednesday', value: 31 }, - { timeline: 2015, typeName: 'banana', key: 'Monday', value: 31 }, - { timeline: 2015, typeName: 'banana', key: 'Tuesday', value: 32 }, - { timeline: 2015, typeName: 'banana', key: 'Wednesday', value: 33 }, - { timeline: 2016, typeName: 'apple', key: 'Monday', value: 1 }, - { timeline: 2016, typeName: 'apple', key: 'Tuesday', value: 2 }, - { timeline: 2016, typeName: 'apple', key: 'Wednesday', value: 3 }, - { timeline: 2016, typeName: 'pear', key: 'Monday', value: 11 }, - { timeline: 2016, typeName: 'pear', key: 'Tuesday', value: 21 }, - { timeline: 2016, typeName: 'pear', key: 'Wednesday', value: 31 }, - { timeline: 2016, typeName: 'banana', key: 'Monday', value: 31 }, - { timeline: 2016, typeName: 'banana', key: 'Tuesday', value: 32 }, - { timeline: 2016, typeName: 'banana', key: 'Wednesday', value: 33 }, - ... -], { - // 可以使用 $timeline 进行占位,该字符串将替换为 timeline 属性的值 - title: '$timeline时间轴柱状图' -}) -``` - -#### options 可配置参数 - -| 属性 | 说明 | required | 类型 | 默认值 | -| :----| :------| :--------| :---:| :------| -| title | 图表标题 | - | String | '单条柱状图' 或 '多条柱状图' | -| keyMap | 数据列表的属性字典 | - | Object | 详见后续属性 | -| keyMap.xAxisKey | x 轴对应的属性名称 | - | String | 'key' | -| keyMap.dataKey | 数据值对应的属性名称 | - | String | 'value' | -| keyMap.legendKey | 图例对应的属性名称 | - | String | 'typeName' | -| keyMap.timelineKey | 时间轴对应的属性名称 | - | String | 'timeline' | -| reverseAxis | 是否为横向图 | - | Boolean | false | -| stack | 是否为堆叠图 | - | Boolean | false | -| lineTypes | 折柱混合图中折线数据对应的图例名称数组 | - | Array | - | -| yAxis | 自定义的 y 轴,请参考 echarts 配置 | - | Object | - | - -### 饼状图 - -#### 基本用法 - -``` js -Chart.pie('#chart', [ - { key: 'Monday', value: 1 }, - { key: 'Tuesday', value: 2 }, - { key: 'Wednesday', value: 3 }, - ... -]) -``` - -#### 环形图 - -``` js -Chart.pie('#chart', [ - { key: 'Monday', value: 1 }, - { key: 'Tuesday', value: 2 }, - { key: 'Wednesday', value: 3 }, - ... -], { - ring: true -}) -``` - -#### options 可配置参数 - -| 属性 | 说明 | required | 类型 | 默认值 | -| :----| :------| :--------| :---:| :------| -| title | 图表标题 | - | String | '饼图' | -| keyMap | 数据列表的属性字典 | - | Object | 详见后续属性 | -| keyMap.textKey | 文本对应的属性名称 | - | String | 'key' | -| keyMap.dataKey | 数据值对应的属性名称 | - | String | 'value' | -| ring | 是否环形图 | - | Boolean | false | - -### 雷达图 - -#### 基本用法 - -``` js -Chart.radar('#chart', [ - { typeName: 'apple', key: 'Monday', value: 1 }, - { typeName: 'apple', key: 'Tuesday', value: 2 }, - { typeName: 'apple', key: 'Wednesday', value: 3 }, - { typeName: 'pear', key: 'Monday', value: 11 }, - { typeName: 'pear', key: 'Tuesday', value: 21 }, - { typeName: 'pear', key: 'Wednesday', value: 31 }, - { typeName: 'banana', key: 'Monday', value: 31 }, - { typeName: 'banana', key: 'Tuesday', value: 32 }, - { typeName: 'banana', key: 'Wednesday', value: 33 }, - ... -]) -``` - -#### options 可配置参数 - -| 属性 | 说明 | required | 类型 | 默认值 | -| :----| :------| :--------| :---:| :------| -| title | 图表标题 | - | String | '雷达图' | -| keyMap | 数据列表的属性字典 | - | Object | 详见后续属性 | -| keyMap.textKey | 指标对应的属性名称 | - | String | 'key' | -| keyMap.dataKey | 数据值对应的属性名称 | - | String | 'value' | -| keyMap.legendKey | 图例对应的属性名称 | - | String | 'typeName' | - -### 漏斗图 - -#### 基本用法 - -``` js -Chart.funnel('#chart', [ - { key: 'Monday', value: 1 }, - { key: 'Tuesday', value: 2 }, - { key: 'Wednesday', value: 3 }, - ... -]) -``` - -#### options 可配置参数 - -| 属性 | 说明 | required | 类型 | 默认值 | -| :----| :------| :--------| :---:| :------| -| title | 图表标题 | - | String | '漏斗图' | -| keyMap | 数据列表的属性字典 | - | Object | 详见后续属性 | -| keyMap.textKey | 文本对应的属性名称 | - | String | 'key' | -| keyMap.dataKey | 数据值对应的属性名称 | - | String | 'value' | - -### 气泡图 - -#### 基本用法 - -``` js -Chart.scatter('#chart', [ - { typeName: 'apple', text: 'Monday', x: 1, y: 1, size: 1 }, - { typeName: 'apple', text: 'Tuesday', x: 2, y: 2, size: 2 }, - { typeName: 'apple', text: 'Wednesday', x: 3, y: 3, size: 3 }, - { typeName: 'pear', text: 'Monday', x: 11, y: 11, size: 11 }, - { typeName: 'pear', text: 'Tuesday', x: 21, y: 21, size: 21 }, - { typeName: 'pear', text: 'Wednesday', x: 31, y: 31, size: 31 }, - { typeName: 'banana', text: 'Monday', x: 31, y: 31, size: 31 }, - { typeName: 'banana', text: 'Tuesday', x: 32, y: 32, size: 32 }, - { typeName: 'banana', text: 'Wednesday', x: 33, y: 33, size: 33 }, - ... -]) -``` - -#### options 可配置参数 - -| 属性 | 说明 | required | 类型 | 默认值 | -| :----| :------| :--------| :---:| :------| -| title | 图表标题 | - | String | '气泡图' | -| keyMap | 数据列表的属性字典 | - | Object | 详见后续属性 | -| keyMap.xKey | x 坐标对应的属性名称 | - | String | 'x' | -| keyMap.yKey | y 坐标对应的属性名称 | - | String | 'y' | -| keyMap.sizeKey | 气泡大小对应的属性名称 | - | String | 'size' | -| keyMap.textKey | 气泡文本对应的属性名称 | - | String | 'text' | -| keyMap.legendKey | 图例对应的属性名称 | - | String | 'typeName' | - -### 全局配置 - -#### 主题 - -注册并按需使用 -``` js -import themeData from './theme.json' - -// 注册主题 -Chart.config({ - theme: { - name: 'themeName', - data: themeData - } -}) - -// 使用主题 -Chart.line('#chart', data, { theme: 'themeName' }) -``` - -注册并全局使用 -``` js -import themeData from './theme.json' - -// 注册为默认主题后,所有的图表均使用该主题,不需要特别指定 -Chart.config({ - theme: { - name: 'themeName', - data: themeData, - default: true - } -}) -``` - -### 实例 API - -| 方法 | 说明 | 参数 | 参数类型 | 返回值 | -| :----| :------| :--------| :---:| :------| -| setData | 重新设置数据 | data | Array | - | - -## License - -[MIT](http://opensource.org/licenses/MIT) diff --git a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/build/config.js b/dolphinscheduler-ui/src/lib/@analysys/ana-charts/build/config.js deleted file mode 100644 index 006e4b0147..0000000000 --- a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/build/config.js +++ /dev/null @@ -1,60 +0,0 @@ -/** - * webpack config - * - * author: liuxin(liuxin@analysys.com.cn) - */ - -const path = require('path') -const glob = require('globby') - -const isProduction = process.env.NODE_ENV !== 'development' -const resolve = dir => path.join(__dirname, '..', dir) -const assetsDir = resolve('src') -const distDir = resolve('dist') - -const baseConfig = { - entry: { - 'index': glob.sync(['index.js'], { cwd: assetsDir }) - }, - output: { - path: distDir - }, - module: { - rules: [ - { - test: /\.js$/, - exclude: file => ( - /node_modules/.test(file) && - !/\.vue\.js/.test(file) - ), - use: [ - { - loader: 'babel-loader', - options: { - cacheDirectory: true, - cacheIdentifier: true - } - } - ] - } - ] - }, - resolve: { - modules: [ - resolve('node_modules'), - resolve('src') - ], - extensions: ['.js', '.json', '.vue', '.scss'] - }, - externals: { - 'vue': 'Vue', - 'echarts': 'echarts' - } -} - -module.exports = { - isProduction, - assetsDir, - distDir, - baseConfig -} diff --git a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/build/webpack.config.prod.js b/dolphinscheduler-ui/src/lib/@analysys/ana-charts/build/webpack.config.prod.js deleted file mode 100644 index b7b97ff9b9..0000000000 --- a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/build/webpack.config.prod.js +++ /dev/null @@ -1,104 +0,0 @@ -/** - * webpack config for production - * - * author: liuxin(liuxin@analysys.com.cn) - */ - -const webpack = require('webpack') -const merge = require('webpack-merge') -const { baseConfig } = require('./config') -const ExtractTextPlugin = require('extract-text-webpack-plugin') -const UglifyJSPlugin = require('uglifyjs-webpack-plugin') -const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin') -const VueLoaderPlugin = require('vue-loader/lib/plugin') - -const config = merge.smart(baseConfig, { - devtool: 'source-map', - output: { - filename: '[name].js', - libraryTarget: 'umd', - umdNamedDefine: false - }, - module: { - rules: [ - { - test: /\.vue$/, - loader: 'vue-loader', - options: { - hotReload: false - } - }, - { - test: /\.css$/, - loader: ExtractTextPlugin.extract({ - use: [ - 'css-loader', - { - loader: 'postcss-loader', - options: { - plugins: (loader) => [ - require('autoprefixer')({ - 'browsers': ['ie > 8', 'last 2 version', 'safari >= 9'] - }), - require('cssnano') - ] - } - } - ], - fallback: ['vue-style-loader'] - }) - }, - { - test: /\.scss$/, - loader: ExtractTextPlugin.extract({ - use: [ - 'css-loader', - 'sass-loader', - { - loader: 'postcss-loader', - options: { - plugins: (loader) => [ - require('autoprefixer')({ - 'browsers': ['ie > 8', 'last 2 version', 'safari >= 9'] - }), - require('cssnano') - ] - } - } - ], - fallback: ['vue-style-loader'] - }) - } - ] - }, - plugins: [ - new VueLoaderPlugin(), - new ExtractTextPlugin({ filename: '[name].css', allChunks: true }), - new webpack.optimize.OccurrenceOrderPlugin(), - new OptimizeCssAssetsPlugin({ - assetNameRegExp: /\.css$/g, - cssProcessor: require('cssnano'), - cssProcessorOptions: { discardComments: { removeAll: true } }, - canPrint: true - }), - new UglifyJSPlugin({ - parallel: true, - sourceMap: true, - uglifyOptions: { - compress: { - drop_console: true, - drop_debugger: true - }, - comments: function (n, c) { - /*! IMPORTANT: Please preserve 3rd-party library license info, inspired from @allex/amd-build-worker/config/util.js */ - var text = c.value, type = c.type - if (type === 'comment2') { - return /^!|@preserve|@license|@cc_on|MIT/i.test(text) - } - } - } - }) - ] -}) - -module.exports = config diff --git a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/dist/index.js b/dolphinscheduler-ui/src/lib/@analysys/ana-charts/dist/index.js deleted file mode 100644 index f1ec7d4b10..0000000000 --- a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/dist/index.js +++ /dev/null @@ -1,2 +0,0 @@ -!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t(require("echarts"));else if("function"==typeof define&&define.amd)define(["echarts"],t);else{var n="object"==typeof exports?t(require("echarts")):t(e.echarts);for(var i in n)("object"==typeof exports?exports:e)[i]=n[i]}}("undefined"!=typeof self?self:this,function(e){return function(e){var t={};function n(i){if(t[i])return t[i].exports;var r=t[i]={i:i,l:!1,exports:{}};return e[i].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:i})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=4)}([function(e,t,n){"use strict";t.__esModule=!0;t.init=function(e,t,n,i){var r=function(e){if(!e)return;if("string"==typeof e)if(e.startsWith("#"))e=document.getElementById(e.slice(1));else{if(!e.startsWith("."))return;e=document.getElementsByClassName(e.slice(1))}if(!e)throw new Error("找不到对应的dom对象!");var t=void 0;t=HTMLElement.prototype.isPrototypeOf(e)?new Array(e):Array.from(e);if(!t)throw new Error("未找到对应的dom对象!");return t}(t),a=Object.assign({},{data:n},i),o=r.map(function(t){return new e(t,a)});return 1===o.length?o[0]:o};t.checkKeyInModel=function(e){for(var t=arguments.length,n=Array(t>1?t-1:0),i=1;i=r.length)break;s=r[o++]}else{if((o=r.next()).done)break;s=o.value}var l=s;if(!e.hasOwnProperty(l))throw new Error("数据格式错误!未找到指定属性:"+l)}}},function(e,t,n){"use strict";t.__esModule=!0;var i=a(n(3)),r=a(n(2));function a(e){return e&&e.__esModule?e:{default:e}}var o=function(){function e(t,n){var a=this;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.settings=n;var o=this.transform();o&&(this.options=o,n.theme?this.echart=i.default.init(t,n.theme):r.default.settings.defaultTheme?this.echart=i.default.init(t,r.default.settings.defaultTheme):this.echart=i.default.init(t),window.addEventListener("resize",function(){return a.echart.resize()}),this.apply())}return e.prototype.setData=function(e){e&&0!==e.length&&(this.settings.data=e,this.options=this.transform(),this.apply())},e.prototype.injectDataIntoSeries=function(e,t){return e.forEach(function(e){if("all"===e.index)delete e.index,t=t.map(function(t){return Object.assign({},t,e)});else if("start"===e.index)delete e.index,t[0]=Object.assign({},t[0],e);else if("end"===e.index)delete e.index,t[t.length-1]=Object.assign({},t[t.length-1],e);else if(Array.isArray(e.index)){var n=e.index,i=Array.isArray(n),r=0;for(n=i?n:n[Symbol.iterator]();;){var a;if(i){if(r>=n.length)break;a=n[r++]}else{if((r=n.next()).done)break;a=r.value}var o=a;t[o]&&(t[o]=Object.assign({},t[o],e))}}}),t},e}();t.default=o},function(e,t,n){"use strict";t.__esModule=!0,t.Scatter=t.Funnel=t.Radar=t.Pie=t.Bar=t.Line=void 0;var i=c(n(3)),r=c(n(5)),a=c(n(6)),o=c(n(7)),s=c(n(8)),l=c(n(9)),u=c(n(10)),f=n(0);function c(e){return e&&e.__esModule?e:{default:e}}var p={Line:r.default,Bar:a.default,Pie:o.default,Radar:s.default,Funnel:l.default,Scatter:u.default},d={settings:{},config:function(e){var t=e.theme;t&&((0,f.checkKeyInModel)(t,"name","data"),i.default.registerTheme(t.name,t.data),t.default&&(d.settings.defaultTheme=t.name))}},h=function(e){p.hasOwnProperty(e)&&(d[e.toLowerCase()]=function(t,n,i){return(0,f.init)(p[e],t,n,i)})};for(var y in p)h(y);t.Line=r.default,t.Bar=a.default,t.Pie=o.default,t.Radar=s.default,t.Funnel=l.default,t.Scatter=u.default,t.default=d,"undefined"!=typeof window&&(window.Chart=d)},function(t,n){t.exports=e},function(e,t,n){e.exports=n(2)},function(e,t,n){"use strict";t.__esModule=!0;var i,r=n(1),a=(i=r)&&i.__esModule?i:{default:i},o=n(0);var s=function(e){function t(){return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t),function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,e.apply(this,arguments))}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),t.init=function(e,n,i){return(0,o.init)(t,e,n,i)},t.prototype.transform=function(){var e=this.settings.data,t=void 0===e?[]:e;if(0===t.length)throw new Error("数据源为空!");return Object.keys(t[0]).length>2?this.setMultipleLines():(this.simple=!0,this.setSingleLine())},t.prototype.setSingleLine=function(){var e=this.settings,t=e.data,n=void 0===t?[]:t,i=e.keyMap,r=void 0===i?{xAxisKey:"key",dataKey:"value"}:i,a=e.title,s=void 0===a?"单条折线图":a,l=r.xAxisKey,u=r.dataKey;(0,o.checkKeyInModel)(n[0],l,u);for(var f=[{type:"line",data:[]}],c={type:"category",data:[]},p=0;p2?this.setMultipleBars():(this.simple=!0,this.setSingleBar())},t.prototype.setSingleBar=function(){var e=this.settings,t=e.data,n=void 0===t?[]:t,i=e.keyMap,r=void 0===i?{xAxisKey:"key",dataKey:"value"}:i,a=e.title,s=void 0===a?"单条柱状图":a,l=r.xAxisKey,u=r.dataKey;(0,o.checkKeyInModel)(n[0],l,u);for(var f=[{type:"bar",data:[]}],c={type:"category",data:[]},p=0;p=0||Object.prototype.hasOwnProperty.call(e,i)&&(n[i]=e[i]);return n}var l=function(e){function t(){return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t),function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,e.apply(this,arguments))}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),t.init=function(e,n,i){return(0,o.init)(t,e,n,i)},t.prototype.transform=function(){var e=this.settings,t=e.data,n=void 0===t?[]:t,i=e.title,r=void 0===i?"饼图":i,a=e.ring,l=void 0!==a&&a,u=e.keyMap,f=void 0===u?{textKey:"key",dataKey:"value"}:u;if(0===n.length)throw new Error("数据源为空!");var c=f.textKey,p=f.dataKey;(0,o.checkKeyInModel)(n[0],c,p);for(var d=[{radius:l?["50%","70%"]:"60%",center:r?["50%","60%"]:["50%","50%"],type:"pie",data:[]}],h=0;h=0||Object.prototype.hasOwnProperty.call(e,i)&&(n[i]=e[i]);return n}var l=function(e){function t(){return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t),function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,e.apply(this,arguments))}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),t.init=function(e,n,i){return(0,o.init)(t,e,n,i)},t.prototype.transform=function(){var e=this.settings,t=e.data,n=void 0===t?[]:t,i=e.title,r=void 0===i?"漏斗图":i,a=e.keyMap,l=void 0===a?{textKey:"key",dataKey:"value"}:a;if(0===n.length)throw new Error("数据源为空!");var u=l.textKey,f=l.dataKey;(0,o.checkKeyInModel)(n[0],u,f);for(var c=[{type:"funnel",left:"10%",top:60,bottom:60,width:"80%",min:0,max:100,minSize:"0%",maxSize:"100%",sort:"descending",gap:2,label:{normal:{show:!0,position:"inside"},emphasis:{textStyle:{fontSize:20}}},labelLine:{normal:{length:10,lineStyle:{width:1,type:"solid"}}},itemStyle:{normal:{borderColor:"#fff",borderWidth:1}},data:[]}],p=0;p{b} : {c}%"},legend:{data:i},series:a},!0)},t}(a.default);t.default=l},function(e,t,n){"use strict";t.__esModule=!0;var i,r=n(1),a=(i=r)&&i.__esModule?i:{default:i},o=n(0);var s=function(e){function t(){return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t),function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,e.apply(this,arguments))}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),t.init=function(e,n,i){return(0,o.init)(t,e,n,i)},t.prototype.transform=function(){var e=this.settings,t=e.data,n=void 0===t?[]:t,i=e.title,r=void 0===i?"气泡图":i,a=e.keyMap,s=void 0===a?{xKey:"x",yKey:"y",sizeKey:"size",textKey:"text",legendKey:"typeName"}:a;if(0===n.length)throw new Error("数据源为空!");var l=[],u=[],f=s.xKey,c=s.yKey,p=s.sizeKey,d=s.textKey,h=s.legendKey;(0,o.checkKeyInModel)(n[0],f,c,p,d,h);for(var y=function(e){var t=n[e],i=t[h],r=t[f],a=t[c],o=t[p],s=t[d],y=function(e,t){var n={};for(var i in e)t.indexOf(i)>=0||Object.prototype.hasOwnProperty.call(e,i)&&(n[i]=e[i]);return n}(t,[h,f,c,p,d]);l.includes(i)||l.push(i);var v=u.find(function(e){return e.name===i});v||(v={type:"scatter",name:i,data:[],symbolSize:function(e){return Math.sqrt(e[2])},label:{emphasis:{show:!0,formatter:function(e){return e.data[3]},position:"top"}}},u.push(v)),v.data.push(Object.assign({value:[r,a,o,s]},y,{_raw:n[e]}))},v=0;v {\n const list = getChartContainers(el)\n const settings = Object.assign({}, { data }, options)\n const charts = list.map(element => {\n return new Target(element, settings)\n })\n return charts.length === 1 ? charts[0] : charts\n}\n\n/**\n * 统一图表容器为 DOM 元素数组\n * @param {*} el 选择器或者 DOM 对象\n */\nfunction getChartContainers (el) {\n // 未传参数,直接返回\n if (!el) {\n return\n }\n if (typeof el === 'string') {\n if (el.startsWith('#')) {\n el = document.getElementById(el.slice(1))\n } else if (el.startsWith('.')) {\n el = document.getElementsByClassName(el.slice(1))\n } else {\n return\n }\n }\n if (!el) {\n throw new Error('找不到对应的dom对象!')\n }\n let list\n if (HTMLElement.prototype.isPrototypeOf(el)) {\n list = new Array(el)\n } else {\n list = Array.from(el)\n }\n if (!list) {\n throw new Error('未找到对应的dom对象!')\n }\n return list\n}\n\n/**\n * 检测在指定对象中是否存在指定的属性名\n * @param {Object} model 待检测模型\n * @param {...any} params 待检测属性名\n */\nexport const checkKeyInModel = (model, ...params) => {\n for (const key of params) {\n if (!model.hasOwnProperty(key)) {\n throw new Error('数据格式错误!未找到指定属性:' + key)\n }\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/common.js","import echarts from 'echarts'\nimport Chart from '../index'\n\nexport default class Base {\n constructor (element, settings) {\n this.settings = settings\n const options = this.transform()\n if (options) {\n this.options = options\n if (settings.theme) {\n // 使用已经注册的自定义主题\n this.echart = echarts.init(element, settings.theme)\n } else if (Chart.settings.defaultTheme) {\n // 使用全局配置的主题\n this.echart = echarts.init(element, Chart.settings.defaultTheme)\n } else {\n this.echart = echarts.init(element)\n }\n // 响应窗口 resize 事件\n window.addEventListener('resize', () => this.echart.resize())\n this.apply()\n }\n }\n\n /**\n * 刷新数据\n * @param {*} data 图表数据\n */\n setData (data) {\n if (data && data.length !== 0) {\n this.settings.data = data\n this.options = this.transform()\n this.apply()\n }\n }\n\n injectDataIntoSeries (data, series) {\n data.forEach(o => {\n if (o.index === 'all') {\n delete o.index\n series = series.map(item => {\n return Object.assign({}, item, o)\n })\n } else if (o.index === 'start') {\n delete o.index\n series[0] = Object.assign({}, series[0], o)\n } else if (o.index === 'end') {\n delete o.index\n series[series.length - 1] = Object.assign({}, series[series.length - 1], o)\n } else if (Array.isArray(o.index)) {\n for (const i of o.index) {\n if (series[i]) {\n series[i] = Object.assign({}, series[i], o)\n }\n }\n }\n })\n return series\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/packages/base.js","import echarts from 'echarts'\n\nimport Line from './packages/line'\nimport Bar from './packages/bar'\nimport Pie from './packages/pie'\nimport Radar from './packages/radar'\nimport Funnel from './packages/funnel'\nimport Scatter from './packages/scatter'\nimport { checkKeyInModel, init } from './common'\n\nconst components = {\n Line,\n Bar,\n Pie,\n Radar,\n Funnel,\n Scatter\n}\n\nconst Chart = {\n // 默认配置\n settings: {},\n /**\n * 配置全局属性\n * @param {Object} options 全局配置项\n */\n config (options) {\n const { theme } = options\n // 注册主题\n if (theme) {\n checkKeyInModel(theme, 'name', 'data')\n echarts.registerTheme(theme.name, theme.data)\n if (theme.default) {\n Chart.settings.defaultTheme = theme.name\n }\n }\n }\n}\n\n// 注入不同组件对应方法\nfor (const key in components) {\n if (components.hasOwnProperty(key)) {\n Chart[key.toLowerCase()] = (el, data, options) => {\n return init(components[key], el, data, options)\n }\n }\n}\n\nexport {\n Line,\n Bar,\n Pie,\n Radar,\n Funnel,\n Scatter\n}\n\nexport default Chart\n\nif (typeof window !== 'undefined') {\n window.Chart = Chart\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/index.js","module.exports = __WEBPACK_EXTERNAL_MODULE_3__;\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"echarts\"\n// module id = 3\n// module chunks = 0","import Base from '../base'\nimport { checkKeyInModel, init } from '../../common'\n\nconst TYPE = 'line'\n\n/**\n * 折线图\n */\nexport default class Line extends Base {\n /**\n * 单独导出时调用的初始化方法\n * @param {*} el 选择器或者 DOM 对象\n * @param {*} data 数据源\n * @param {*} options 可选项\n */\n static init (el, data, options) {\n return init(Line, el, data, options)\n }\n\n /**\n * 将用户配置转换为符合 ECharts API 格式的配置格式\n */\n transform () {\n const { data = [] } = this.settings\n\n if (data.length === 0) {\n throw new Error('数据源为空!')\n }\n\n if (Object.keys(data[0]).length > 2) {\n return this.setMultipleLines()\n } else {\n this.simple = true\n return this.setSingleLine()\n }\n }\n\n /**\n * 单条折线\n */\n setSingleLine () {\n const {\n // 数据\n data = [],\n // 属性字典\n keyMap = {\n xAxisKey: 'key',\n dataKey: 'value'\n },\n // 图表标题\n title = '单条折线图'\n } = this.settings\n\n // x 轴对应属性名,数据值对应的属性名\n const { xAxisKey, dataKey } = keyMap\n checkKeyInModel(data[0], xAxisKey, dataKey)\n\n const series = [{\n type: TYPE,\n data: []\n }]\n const xAxis = {\n type: 'category',\n data: []\n }\n\n for (let i = 0; i < data.length; i++) {\n xAxis.data.push(data[i][xAxisKey])\n series[0].data.push(data[i][dataKey])\n }\n\n return { title, xAxis, series }\n }\n\n /**\n * 多条折线\n */\n setMultipleLines () {\n const {\n // 数据\n data = [],\n // 属性字典\n keyMap = {\n xAxisKey: 'key',\n legendKey: 'typeName',\n dataKey: 'value'\n },\n // 图表标题\n title = '多条折线图'\n } = this.settings\n\n // x 轴对应属性名,图例对应的属性名,数据值对应的属性名\n const { xAxisKey, legendKey, dataKey } = keyMap\n checkKeyInModel(data[0], xAxisKey, legendKey, dataKey)\n\n const legendData = []\n const series = []\n const xAxis = {\n type: 'category',\n data: []\n }\n\n for (let i = 0; i < data.length; i++) {\n const legendItem = data[i][legendKey]\n const xAxisItem = data[i][xAxisKey]\n const dataItem = data[i][dataKey]\n\n // 图例\n if (!legendData.includes(legendItem)) {\n legendData.push(legendItem)\n }\n\n // x 轴\n if (!xAxis.data.includes(xAxisItem)) {\n xAxis.data.push(xAxisItem)\n }\n\n // 系列\n let targetSeries = series.find(s => s.name === legendItem)\n if (!targetSeries) {\n targetSeries = {\n name: legendItem,\n type: TYPE,\n data: []\n }\n series.push(targetSeries)\n }\n targetSeries.data.push(dataItem)\n }\n\n return { title, xAxis, series, legendData }\n }\n\n /**\n * 绘制图表\n */\n apply () {\n const { title, xAxis, series, legendData = [] } = this.options\n const {\n // 是否为横向图\n reverseAxis = false\n } = this.settings\n const valueAxis = { type: 'value' }\n let yAxisModel = reverseAxis ? xAxis : valueAxis\n let xAxisModel = reverseAxis ? valueAxis : xAxis\n // 简单图表标题为空时,图表垂直居中\n const top = !title && this.simple ? '3%' : 60\n\n // 注入配置到series\n let { insertSeries } = this.settings\n let _series = series\n if (insertSeries && insertSeries.length && series.length) {\n _series = this.injectDataIntoSeries(insertSeries, _series)\n }\n\n this.echart.setOption({\n title: {\n text: title\n },\n tooltip: {\n trigger: 'axis'\n },\n grid: {\n left: '3%',\n right: '4%',\n bottom: '3%',\n top,\n containLabel: true\n },\n legend: {\n data: legendData\n },\n xAxis: xAxisModel,\n yAxis: yAxisModel,\n series: _series\n }, true)\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/packages/line/index.js","import Base from '../base'\nimport { checkKeyInModel, init } from '../../common'\n\nconst TYPE = 'bar'\n\n/**\n * 柱状图\n */\nexport default class Bar extends Base {\n /**\n * 单独导出时调用的初始化方法\n * @param {*} el 选择器或者 DOM 对象\n * @param {*} data 数据源\n * @param {*} options 可选项\n */\n static init (el, data, options) {\n return init(Bar, el, data, options)\n }\n\n /**\n * 将用户配置转换为符合 ECharts API 格式的配置格式\n */\n transform () {\n const { data = [] } = this.settings\n\n if (data.length === 0) {\n throw new Error('数据源为空!')\n }\n\n if (Object.keys(data[0]).length > 2) {\n return this.setMultipleBars()\n } else {\n this.simple = true\n return this.setSingleBar()\n }\n }\n\n /**\n * 单条柱\n */\n setSingleBar () {\n const {\n // 数据\n data = [],\n // 属性字典\n keyMap = {\n xAxisKey: 'key',\n dataKey: 'value'\n },\n // 图表标题\n title = '单条柱状图'\n } = this.settings\n\n // x 轴对应属性名,数据值对应的属性名\n const { xAxisKey, dataKey } = keyMap\n checkKeyInModel(data[0], xAxisKey, dataKey)\n\n const series = [{\n type: TYPE,\n data: []\n }]\n const xAxis = {\n type: 'category',\n data: []\n }\n\n for (let i = 0; i < data.length; i++) {\n xAxis.data.push(data[i][xAxisKey])\n series[0].data.push(data[i][dataKey])\n }\n\n return { title, xAxis, series }\n }\n\n /**\n * 多条柱\n */\n setMultipleBars () {\n const {\n // 数据\n data = [],\n // 属性字典\n keyMap = {\n xAxisKey: 'key',\n legendKey: 'typeName',\n dataKey: 'value'\n },\n // 图表标题\n title = '多条柱状图',\n // 折柱混合时,指定的折线数据索引\n lineTypes\n } = this.settings\n\n // x 轴对应属性名,图例对应的属性名,数据值对应的属性名\n const { xAxisKey, legendKey, dataKey } = keyMap\n // 是否使用时间轴数据\n const timeline = Object.keys(data[0]).length === 4\n const timelineKey = keyMap.timelineKey || 'timeline'\n if (timeline) {\n checkKeyInModel(data[0], xAxisKey, legendKey, dataKey, timelineKey)\n } else {\n checkKeyInModel(data[0], xAxisKey, legendKey, dataKey)\n }\n\n // 规范折柱混合索引\n let lineTypeList = []\n if (lineTypes) {\n if (!Array.isArray(lineTypes)) {\n lineTypeList = [lineTypes]\n } else {\n lineTypeList = lineTypes\n }\n }\n\n // 时间轴默认配置\n const timelineOptions = {\n timeline: {\n axisType: 'category',\n autoPlay: true,\n playInterval: 1000,\n data: []\n },\n options: []\n }\n\n // 初始值\n const legendData = []\n const series = []\n const xAxis = {\n type: 'category',\n data: []\n }\n for (let i = 0; i < data.length; i++) {\n const legendItem = data[i][legendKey]\n const xAxisItem = data[i][xAxisKey]\n const dataItem = data[i][dataKey]\n\n // 图例\n if (!legendData.includes(legendItem)) {\n legendData.push(legendItem)\n }\n\n // x 轴\n if (!xAxis.data.includes(xAxisItem)) {\n xAxis.data.push(xAxisItem)\n }\n\n // 时间轴\n if (timeline) {\n const timelineItem = data[i][timelineKey]\n // 设置时间轴 label\n if (!timelineOptions.timeline.data.includes(timelineItem)) {\n timelineOptions.timeline.data.push(timelineItem)\n }\n // 通用的系列配置\n if (!series.some(s => s.name === legendItem)) {\n let seriesType = TYPE\n if (lineTypeList.length !== 0 && lineTypeList.includes(legendItem)) {\n seriesType = 'line'\n }\n series.push({\n name: legendItem,\n type: seriesType\n })\n }\n // 系列数据\n let targetOptions = timelineOptions.options.find(o => o._helpName === timelineItem)\n if (!targetOptions) {\n // 初始化 option\n targetOptions = {\n _helpName: timelineItem,\n title: { text: title.replace('$timeline', timelineItem) },\n series: []\n }\n timelineOptions.options.push(targetOptions)\n }\n let targetSeries = targetOptions.series.find(d => d._helpName === legendItem)\n if (!targetSeries) {\n // 初始化系列数据\n targetSeries = {\n _helpName: legendItem,\n data: []\n }\n targetOptions.series.push(targetSeries)\n }\n targetSeries.data.push(dataItem)\n } else {\n // 非时间轴数据处理\n let targetSeries = series.find(s => s.name === legendItem)\n if (!targetSeries) {\n let seriesType = TYPE\n if (lineTypeList.length !== 0 && lineTypeList.includes(legendItem)) {\n seriesType = 'line'\n }\n targetSeries = {\n name: legendItem,\n type: seriesType,\n data: []\n }\n series.push(targetSeries)\n }\n targetSeries.data.push(dataItem)\n }\n }\n\n if (timeline) {\n return { title, xAxis, series, legendData, timelineOptions }\n }\n return { title, xAxis, series, legendData }\n }\n\n /**\n * 绘制图表\n */\n apply () {\n const { title, xAxis, series, legendData, timelineOptions } = this.options\n const {\n // 是否为横向图\n reverseAxis = false,\n // 自定义 y 轴\n yAxis,\n // 是否为堆叠图\n stack = false\n } = this.settings\n const valueAxis = { type: 'value' }\n let yAxisModel = reverseAxis ? xAxis : valueAxis\n let xAxisModel = reverseAxis ? valueAxis : xAxis\n // 使用自定义 y 轴覆盖\n if (yAxis) {\n yAxisModel = yAxis\n }\n // 设置堆叠图\n if (stack) {\n series.forEach(set => {\n set.stack = '总量'\n set.label = {\n normal: {\n show: true,\n position: reverseAxis ? 'insideRight' : 'insideTop'\n }\n }\n })\n }\n\n // 注入配置到series\n let { insertSeries } = this.settings\n let _series = series\n if (insertSeries && insertSeries.length && series.length) {\n _series = this.injectDataIntoSeries(insertSeries, _series)\n }\n\n // 时间轴\n if (timelineOptions) {\n this.echart.setOption({\n baseOption: {\n timeline: timelineOptions.timeline,\n tooltip: {\n trigger: 'axis'\n },\n grid: {\n top: 80,\n bottom: 100,\n containLabel: true\n },\n legend: {\n x: 'right',\n data: legendData\n },\n xAxis: xAxisModel,\n yAxis: yAxisModel,\n series: _series\n },\n options: timelineOptions.options\n }, true)\n } else {\n // 简单图表标题为空时,图表垂直居中\n const top = !title && this.simple ? '3%' : 60\n this.echart.setOption({\n title: {\n text: title\n },\n tooltip: {\n trigger: 'axis'\n },\n grid: {\n left: '3%',\n right: '4%',\n bottom: '3%',\n top,\n containLabel: true\n },\n legend: {\n data: legendData\n },\n xAxis: xAxisModel,\n yAxis: yAxisModel,\n series: _series\n }, true)\n }\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/packages/bar/index.js","import Base from '../base'\nimport { checkKeyInModel, init } from '../../common'\n\nconst TYPE = 'pie'\n\n/**\n * 饼图\n */\nexport default class Pie extends Base {\n /**\n * 单独导出时调用的初始化方法\n * @param {*} el 选择器或者 DOM 对象\n * @param {*} data 数据源\n * @param {*} options 可选项\n */\n static init (el, data, options) {\n return init(Pie, el, data, options)\n }\n\n /**\n * 将用户配置转换为符合 ECharts API 格式的配置格式\n */\n transform () {\n const {\n // 数据\n data = [],\n // 标题\n title = '饼图',\n // 是否环形图\n ring = false,\n // 属性字典\n keyMap = {\n textKey: 'key',\n dataKey: 'value'\n }\n } = this.settings\n\n if (data.length === 0) {\n throw new Error('数据源为空!')\n }\n\n // 文本对应属性名,数据值对应的属性名\n const { textKey, dataKey } = keyMap\n checkKeyInModel(data[0], textKey, dataKey)\n\n const legendData = []\n let radius = ring ? ['50%', '70%'] : '60%'\n let center = title ? ['50%', '60%'] : ['50%', '50%']\n const series = [{\n radius: radius,\n center: center,\n type: TYPE,\n data: []\n }]\n\n // 填充数据\n for (let i = 0; i < data.length; i++) {\n const element = data[i]\n const { [dataKey]: value, [textKey]: name, ...other } = element\n const item = {\n value,\n name,\n ...other,\n _raw: element\n }\n series[0].data.push(item)\n }\n return { title, series, legendData }\n }\n\n /**\n * 绘制图表\n */\n apply () {\n let { title, series, legendData } = this.options\n\n // 注入配置到series\n let { insertSeries } = this.settings\n let _series = series\n if (insertSeries && insertSeries.length && series.length) {\n _series = this.injectDataIntoSeries(insertSeries, _series)\n }\n\n this.echart.setOption({\n title: {\n text: title,\n x: 'center'\n },\n tooltip: {\n trigger: 'item',\n formatter: '{b} : {c} ({d}%)'\n },\n legend: {\n orient: 'vertical',\n left: 'left',\n data: legendData\n },\n series: _series\n }, true)\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/packages/pie/index.js","import Base from '../base'\nimport { checkKeyInModel, init } from '../../common'\n\nconst TYPE = 'radar'\n\n/**\n * 雷达图\n */\nexport default class Radar extends Base {\n /**\n * 单独导出时调用的初始化方法\n * @param {*} el 选择器或者 DOM 对象\n * @param {*} data 数据源\n * @param {*} options 可选项\n */\n static init (el, data, options) {\n return init(Radar, el, data, options)\n }\n\n /**\n * 将用户配置转换为符合 ECharts API 格式的配置格式\n */\n transform () {\n const {\n // 数据\n data = [],\n // 图表标题\n title = '雷达图',\n // 属性字典\n keyMap = {\n textKey: 'key',\n legendKey: 'typeName',\n dataKey: 'value'\n }\n } = this.settings\n\n if (data.length === 0) {\n throw new Error('数据源为空!')\n }\n\n // 文本对应属性名,图例对应的属性名,数据值对应的属性名\n const { textKey, legendKey, dataKey } = keyMap\n checkKeyInModel(data[0], textKey, legendKey, dataKey)\n\n const legendData = []\n const seriesData = []\n const indicator = []\n\n // 设置图例并初始化数据系列\n for (let i = 0; i < data.length; i++) {\n const legendItem = data[i][legendKey]\n const textItem = data[i][textKey]\n const dataItem = data[i][dataKey]\n\n // 图例\n if (!legendData.includes(legendItem)) {\n legendData.push(legendItem)\n }\n\n // 系列\n let targetSeries = seriesData.find(s => s.name === legendItem)\n if (!targetSeries) {\n targetSeries = {\n name: legendItem,\n value: [],\n _raw: []\n }\n seriesData.push(targetSeries)\n }\n targetSeries.value.push(dataItem)\n targetSeries._raw.push(data[i])\n\n // 指标\n let targetIndicator = indicator.find(i => i.name === textItem)\n if (!targetIndicator) {\n indicator.push({ name: textItem })\n }\n }\n\n return { title, seriesData, legendData, indicator }\n }\n\n /**\n * 绘制图表\n */\n apply () {\n const { title, seriesData, legendData = [], indicator } = this.options\n this.echart.setOption({\n title: {\n text: title\n },\n tooltip: {},\n legend: {\n data: legendData\n },\n radar: {\n name: {\n textStyle: {\n color: '#fff',\n backgroundColor: '#999',\n borderRadius: 3,\n padding: [3, 5]\n }\n },\n indicator\n },\n series: [{\n type: TYPE,\n data: seriesData\n }]\n }, true)\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/packages/radar/index.js","import Base from '../base'\nimport { checkKeyInModel, init } from '../../common'\n\nconst TYPE = 'funnel'\n\n/**\n * 漏斗图\n */\nexport default class Funnel extends Base {\n /**\n * 单独导出时调用的初始化方法\n * @param {*} el 选择器或者 DOM 对象\n * @param {*} data 数据源\n * @param {*} options 可选项\n */\n static init (el, data, options) {\n return init(Funnel, el, data, options)\n }\n\n /**\n * 将用户配置转换为符合 ECharts API 格式的配置格式\n */\n transform () {\n const {\n // 数据\n data = [],\n // 标题\n title = '漏斗图',\n // 属性字典\n keyMap = {\n textKey: 'key',\n dataKey: 'value'\n }\n } = this.settings\n\n if (data.length === 0) {\n throw new Error('数据源为空!')\n }\n\n // 文本对应属性名,数据值对应的属性名\n const { textKey, dataKey } = keyMap\n checkKeyInModel(data[0], textKey, dataKey)\n\n const legendData = []\n const series = [{\n type: TYPE,\n left: '10%',\n top: 60,\n bottom: 60,\n width: '80%',\n min: 0,\n max: 100,\n minSize: '0%',\n maxSize: '100%',\n sort: 'descending',\n gap: 2,\n label: {\n normal: {\n show: true,\n position: 'inside'\n },\n emphasis: {\n textStyle: {\n fontSize: 20\n }\n }\n },\n labelLine: {\n normal: {\n length: 10,\n lineStyle: {\n width: 1,\n type: 'solid'\n }\n }\n },\n itemStyle: {\n normal: {\n borderColor: '#fff',\n borderWidth: 1\n }\n },\n data: []\n }]\n\n // 填充数据\n for (let i = 0; i < data.length; i++) {\n const element = data[i]\n const { [dataKey]: value, [textKey]: name, ...other } = element\n const item = {\n value,\n name,\n ...other,\n _raw: element\n }\n series[0].data.push(item)\n }\n return { title, series, legendData }\n }\n\n /**\n * 绘制图表\n */\n apply () {\n let { title, series, legendData } = this.options\n\n // 注入配置到series\n let { insertSeries } = this.settings\n let _series = series\n if (insertSeries && insertSeries.length && series.length) {\n _series = this.injectDataIntoSeries(insertSeries, _series)\n }\n\n this.echart.setOption({\n title: {\n text: title\n },\n tooltip: {\n trigger: 'item',\n formatter: '{a}
{b} : {c}%'\n },\n legend: {\n data: legendData\n },\n series: _series\n }, true)\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/packages/funnel/index.js","import Base from '../base'\nimport { checkKeyInModel, init } from '../../common'\n\nconst TYPE = 'scatter'\n\n/**\n * 气泡图\n */\nexport default class Scatter extends Base {\n /**\n * 单独导出时调用的初始化方法\n * @param {*} el 选择器或者 DOM 对象\n * @param {*} data 数据源\n * @param {*} options 可选项\n */\n static init (el, data, options) {\n return init(Scatter, el, data, options)\n }\n\n /**\n * 将用户配置转换为符合 ECharts API 格式的配置格式\n */\n transform () {\n const {\n // 数据\n data = [],\n // 图表标题\n title = '气泡图',\n // 属性字典\n keyMap = {\n xKey: 'x',\n yKey: 'y',\n sizeKey: 'size',\n textKey: 'text',\n legendKey: 'typeName'\n }\n } = this.settings\n\n if (data.length === 0) {\n throw new Error('数据源为空!')\n }\n\n const legendData = []\n const series = []\n\n const { xKey, yKey, sizeKey, textKey, legendKey } = keyMap\n checkKeyInModel(data[0], xKey, yKey, sizeKey, textKey, legendKey)\n\n for (let i = 0; i < data.length; i++) {\n const {\n [legendKey]: legendItem,\n [xKey]: xValue,\n [yKey]: yValue,\n [sizeKey]: sizeValue,\n [textKey]: textValue,\n ...other\n } = data[i]\n\n // 图例\n if (!legendData.includes(legendItem)) {\n legendData.push(legendItem)\n }\n\n // 系列\n let targetSeries = series.find(s => s.name === legendItem)\n if (!targetSeries) {\n targetSeries = {\n type: TYPE,\n name: legendItem,\n data: [],\n symbolSize: function (data) {\n return Math.sqrt(data[2])\n },\n label: {\n emphasis: {\n show: true,\n formatter: function (param) {\n return param.data[3]\n },\n position: 'top'\n }\n }\n }\n series.push(targetSeries)\n }\n targetSeries.data.push({\n value: [\n xValue,\n yValue,\n sizeValue,\n textValue\n ],\n ...other,\n _raw: data[i]\n })\n }\n\n return { title, series, legendData }\n }\n\n /**\n * 绘制图表\n */\n apply () {\n const { title, series, legendData = [] } = this.options\n\n // 注入配置到series\n let { insertSeries } = this.settings\n let _series = series\n if (insertSeries && insertSeries.length && series.length) {\n _series = this.injectDataIntoSeries(insertSeries, _series)\n }\n\n this.echart.setOption({\n title: {\n text: title\n },\n legend: {\n right: 10,\n data: legendData\n },\n xAxis: {},\n yAxis: {},\n series: _series\n }, true)\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/packages/scatter/index.js"],"sourceRoot":""} \ No newline at end of file diff --git a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/app.vue b/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/app.vue deleted file mode 100644 index 30ba1185f9..0000000000 --- a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/app.vue +++ /dev/null @@ -1,87 +0,0 @@ - - - - - diff --git a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/index.html b/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/index.html deleted file mode 100644 index 23e63a0bb7..0000000000 --- a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - demo - - - -
- - - - diff --git a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/index.js b/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/index.js deleted file mode 100644 index e8cc09e56a..0000000000 --- a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/index.js +++ /dev/null @@ -1,14 +0,0 @@ -import Vue from 'vue' -import router from './router' -import App from './app.vue' - -new Vue({ - el: '#app', - router, - render: h => h(App), - mounted () { - if (this.$route.path === '/') { - this.$router.push('/line') - } - } -}) diff --git a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/mock/data.js b/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/mock/data.js deleted file mode 100644 index 8b77b8ce11..0000000000 --- a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/mock/data.js +++ /dev/null @@ -1,58 +0,0 @@ -export const getTimelineList = () => { - const list = [] - for (let i = 2008; i < 2018; i++) { - let index = 0 - for (const key of keys) { - for (const day of days) { - list.push({ - timeline: i, - typeName: key, - key: day, - value: Math.floor(Math.random() * 100 + (index + 1) * 100) - }) - index++ - } - } - } - return list -} - -export const getSimpleList = () => { - const list = [] - for (const key of keys) { - list.push({ - key: key, - value: Math.floor(Math.random() * 100) - }) - } - return list -} - -export const getMultipleList = (scatter = false) => { - const list = [] - let index = 0 - for (const key of keys) { - for (const day of days) { - if (scatter) { - list.push({ - typeName: key, - text: day, - x: Math.floor(Math.random() * 100 + (index + 1) * 100), - y: Math.floor(Math.random() * 100 + (index + 1) * 100), - size: Math.floor(Math.random() * 1000) - }) - } else { - list.push({ - typeName: key, - key: day, - value: Math.floor(Math.random() * 100 + (index + 1) * 100) - }) - } - } - index++ - } - return list -} - -const keys = ['邮件营销', '联盟广告', '视频广告', '直接访问', '搜索引擎'] -const days = ['周一', '周二', '周三', '周四', '周五', '周六', '周日'] diff --git a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/mock/theme.json b/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/mock/theme.json deleted file mode 100644 index 0811274596..0000000000 --- a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/mock/theme.json +++ /dev/null @@ -1,494 +0,0 @@ - -{ - "color": [ - "#fc97af", - "#87f7cf", - "#f7f494", - "#72ccff", - "#f7c5a0", - "#d4a4eb", - "#d2f5a6", - "#76f2f2" - ], - "backgroundColor": "rgba(41,52,65,1)", - "textStyle": {}, - "title": { - "textStyle": { - "color": "#ffffff" - }, - "subtextStyle": { - "color": "#dddddd" - } - }, - "line": { - "itemStyle": { - "normal": { - "borderWidth": "4" - } - }, - "lineStyle": { - "normal": { - "width": "3" - } - }, - "symbolSize": "0", - "symbol": "circle", - "smooth": true - }, - "radar": { - "itemStyle": { - "normal": { - "borderWidth": "4" - } - }, - "lineStyle": { - "normal": { - "width": "3" - } - }, - "symbolSize": "0", - "symbol": "circle", - "smooth": true - }, - "bar": { - "itemStyle": { - "normal": { - "barBorderWidth": 0, - "barBorderColor": "#ccc" - }, - "emphasis": { - "barBorderWidth": 0, - "barBorderColor": "#ccc" - } - } - }, - "pie": { - "itemStyle": { - "normal": { - "borderWidth": 0, - "borderColor": "#ccc" - }, - "emphasis": { - "borderWidth": 0, - "borderColor": "#ccc" - } - } - }, - "scatter": { - "itemStyle": { - "normal": { - "borderWidth": 0, - "borderColor": "#ccc" - }, - "emphasis": { - "borderWidth": 0, - "borderColor": "#ccc" - } - } - }, - "boxplot": { - "itemStyle": { - "normal": { - "borderWidth": 0, - "borderColor": "#ccc" - }, - "emphasis": { - "borderWidth": 0, - "borderColor": "#ccc" - } - } - }, - "parallel": { - "itemStyle": { - "normal": { - "borderWidth": 0, - "borderColor": "#ccc" - }, - "emphasis": { - "borderWidth": 0, - "borderColor": "#ccc" - } - } - }, - "sankey": { - "itemStyle": { - "normal": { - "borderWidth": 0, - "borderColor": "#ccc" - }, - "emphasis": { - "borderWidth": 0, - "borderColor": "#ccc" - } - } - }, - "funnel": { - "itemStyle": { - "normal": { - "borderWidth": 0, - "borderColor": "#ccc" - }, - "emphasis": { - "borderWidth": 0, - "borderColor": "#ccc" - } - } - }, - "gauge": { - "itemStyle": { - "normal": { - "borderWidth": 0, - "borderColor": "#ccc" - }, - "emphasis": { - "borderWidth": 0, - "borderColor": "#ccc" - } - } - }, - "candlestick": { - "itemStyle": { - "normal": { - "color": "#fc97af", - "color0": "transparent", - "borderColor": "#fc97af", - "borderColor0": "#87f7cf", - "borderWidth": "2" - } - } - }, - "graph": { - "itemStyle": { - "normal": { - "borderWidth": 0, - "borderColor": "#ccc" - } - }, - "lineStyle": { - "normal": { - "width": "1", - "color": "#ffffff" - } - }, - "symbolSize": "0", - "symbol": "circle", - "smooth": true, - "color": [ - "#fc97af", - "#87f7cf", - "#f7f494", - "#72ccff", - "#f7c5a0", - "#d4a4eb", - "#d2f5a6", - "#76f2f2" - ], - "label": { - "normal": { - "textStyle": { - "color": "#293441" - } - } - } - }, - "map": { - "itemStyle": { - "normal": { - "areaColor": "#f3f3f3", - "borderColor": "#999999", - "borderWidth": 0.5 - }, - "emphasis": { - "areaColor": "rgba(255,178,72,1)", - "borderColor": "#eb8146", - "borderWidth": 1 - } - }, - "label": { - "normal": { - "textStyle": { - "color": "#893448" - } - }, - "emphasis": { - "textStyle": { - "color": "rgb(137,52,72)" - } - } - } - }, - "geo": { - "itemStyle": { - "normal": { - "areaColor": "#f3f3f3", - "borderColor": "#999999", - "borderWidth": 0.5 - }, - "emphasis": { - "areaColor": "rgba(255,178,72,1)", - "borderColor": "#eb8146", - "borderWidth": 1 - } - }, - "label": { - "normal": { - "textStyle": { - "color": "#893448" - } - }, - "emphasis": { - "textStyle": { - "color": "rgb(137,52,72)" - } - } - } - }, - "categoryAxis": { - "axisLine": { - "show": true, - "lineStyle": { - "color": "#666666" - } - }, - "axisTick": { - "show": false, - "lineStyle": { - "color": "#333" - } - }, - "axisLabel": { - "show": true, - "textStyle": { - "color": "#aaaaaa" - } - }, - "splitLine": { - "show": false, - "lineStyle": { - "color": [ - "#e6e6e6" - ] - } - }, - "splitArea": { - "show": false, - "areaStyle": { - "color": [ - "rgba(250,250,250,0.05)", - "rgba(200,200,200,0.02)" - ] - } - } - }, - "valueAxis": { - "axisLine": { - "show": true, - "lineStyle": { - "color": "#666666" - } - }, - "axisTick": { - "show": false, - "lineStyle": { - "color": "#333" - } - }, - "axisLabel": { - "show": true, - "textStyle": { - "color": "#aaaaaa" - } - }, - "splitLine": { - "show": false, - "lineStyle": { - "color": [ - "#e6e6e6" - ] - } - }, - "splitArea": { - "show": false, - "areaStyle": { - "color": [ - "rgba(250,250,250,0.05)", - "rgba(200,200,200,0.02)" - ] - } - } - }, - "logAxis": { - "axisLine": { - "show": true, - "lineStyle": { - "color": "#666666" - } - }, - "axisTick": { - "show": false, - "lineStyle": { - "color": "#333" - } - }, - "axisLabel": { - "show": true, - "textStyle": { - "color": "#aaaaaa" - } - }, - "splitLine": { - "show": false, - "lineStyle": { - "color": [ - "#e6e6e6" - ] - } - }, - "splitArea": { - "show": false, - "areaStyle": { - "color": [ - "rgba(250,250,250,0.05)", - "rgba(200,200,200,0.02)" - ] - } - } - }, - "timeAxis": { - "axisLine": { - "show": true, - "lineStyle": { - "color": "#666666" - } - }, - "axisTick": { - "show": false, - "lineStyle": { - "color": "#333" - } - }, - "axisLabel": { - "show": true, - "textStyle": { - "color": "#aaaaaa" - } - }, - "splitLine": { - "show": false, - "lineStyle": { - "color": [ - "#e6e6e6" - ] - } - }, - "splitArea": { - "show": false, - "areaStyle": { - "color": [ - "rgba(250,250,250,0.05)", - "rgba(200,200,200,0.02)" - ] - } - } - }, - "toolbox": { - "iconStyle": { - "normal": { - "borderColor": "#999999" - }, - "emphasis": { - "borderColor": "#666666" - } - } - }, - "legend": { - "textStyle": { - "color": "#999999" - } - }, - "tooltip": { - "axisPointer": { - "lineStyle": { - "color": "#cccccc", - "width": 1 - }, - "crossStyle": { - "color": "#cccccc", - "width": 1 - } - } - }, - "timeline": { - "lineStyle": { - "color": "#87f7cf", - "width": 1 - }, - "itemStyle": { - "normal": { - "color": "#87f7cf", - "borderWidth": 1 - }, - "emphasis": { - "color": "#f7f494" - } - }, - "controlStyle": { - "normal": { - "color": "#87f7cf", - "borderColor": "#87f7cf", - "borderWidth": 0.5 - }, - "emphasis": { - "color": "#87f7cf", - "borderColor": "#87f7cf", - "borderWidth": 0.5 - } - }, - "checkpointStyle": { - "color": "#fc97af", - "borderColor": "rgba(252,151,175,0.3)" - }, - "label": { - "normal": { - "textStyle": { - "color": "#87f7cf" - } - }, - "emphasis": { - "textStyle": { - "color": "#87f7cf" - } - } - } - }, - "visualMap": { - "color": [ - "#fc97af", - "#87f7cf" - ] - }, - "dataZoom": { - "backgroundColor": "rgba(255,255,255,0)", - "dataBackgroundColor": "rgba(114,204,255,1)", - "fillerColor": "rgba(114,204,255,0.2)", - "handleColor": "#72ccff", - "handleSize": "100%", - "textStyle": { - "color": "#333333" - } - }, - "markPoint": { - "label": { - "normal": { - "textStyle": { - "color": "#293441" - } - }, - "emphasis": { - "textStyle": { - "color": "#293441" - } - } - } - } -} diff --git a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/packages/bar.vue b/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/packages/bar.vue deleted file mode 100644 index 60e7be99e1..0000000000 --- a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/packages/bar.vue +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - diff --git a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/packages/funnel.vue b/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/packages/funnel.vue deleted file mode 100644 index acada0313b..0000000000 --- a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/packages/funnel.vue +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - diff --git a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/packages/line.vue b/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/packages/line.vue deleted file mode 100644 index dafb9bab8f..0000000000 --- a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/packages/line.vue +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - diff --git a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/packages/pie.vue b/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/packages/pie.vue deleted file mode 100644 index 28bc315587..0000000000 --- a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/packages/pie.vue +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - diff --git a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/packages/radar.vue b/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/packages/radar.vue deleted file mode 100644 index 24ff64f09d..0000000000 --- a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/packages/radar.vue +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - diff --git a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/packages/scatter.vue b/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/packages/scatter.vue deleted file mode 100644 index 591e1d222c..0000000000 --- a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/packages/scatter.vue +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - diff --git a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/router/index.js b/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/router/index.js deleted file mode 100644 index acba1ed503..0000000000 --- a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/router/index.js +++ /dev/null @@ -1,53 +0,0 @@ -import Vue from 'vue' -import Router from 'vue-router' -import Line from '../packages/line' -import Bar from '../packages/bar' -import Pie from '../packages/pie' -import Radar from '../packages/radar' -import Funnel from '../packages/funnel' -import Scatter from '../packages/scatter' - -Vue.use(Router) - -const router = new Router({ - mode: 'history', - routes: [ - { - path: '/line', - component: Line - }, - { - path: '/bar', - component: Bar - }, - { - path: '/pie', - component: Pie - }, - { - path: '/radar', - component: Radar - }, - { - path: '/funnel', - component: Funnel - }, - { - path: '/scatter', - component: Scatter - } - ] -}) - -router.afterEach((to, from) => { - if (to.hash) { - const target = document.querySelector(to.hash) - if (target) { - window.scrollTo(0, target.offsetTop) - } - } else { - window.scrollTo(0, 0) - } -}) - -export default router diff --git a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/styles/main.scss b/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/styles/main.scss deleted file mode 100644 index 09a2b018d9..0000000000 --- a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/example/styles/main.scss +++ /dev/null @@ -1,77 +0,0 @@ -$leftWidth: 200px; -$leftPaddingX: 30px; - -body { - margin: 0; - padding: 0; -} - -.app-container { - .left { - position: fixed; - left: 0; - top: 0; - display: flex; - flex-direction: column; - width: $leftWidth; - min-height: 500px; - padding: 20px $leftPaddingX; - .sidebar { - padding: 0; - list-style-type: none; - a { - display: block; - text-decoration: none; - color: #35495e; - padding: 5px 10px; - border-radius: 4px; - letter-spacing: .25px; - } - .router-link-active { - color: #fff; - background-color: #41b883; - } - .router-link-active + .sub { - display: block; - } - li { - font-size: 16px; - .sub { - display: none; - padding-left: 20px; - list-style-type: none; - li { - font-size: 14px; - } - .router-link-active { - color: #41b883; - background: #fff; - } - } - } - } - } - .right { - margin-left: $leftWidth + $leftPaddingX * 2; - border-left: 1px solid #c6c6c6; - h1 { - margin: 0; - padding: 30px; - text-align: center; - } - h2 { - margin: 0; - padding: 20px; - text-align: center; - } - .chart-container { - width: 80%; - height: 300px; - margin: auto; - padding-bottom: 50px; - } - .tall { - height: 600px; - } - } -} diff --git a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/package.json b/dolphinscheduler-ui/src/lib/@analysys/ana-charts/package.json deleted file mode 100644 index 73b98e735f..0000000000 --- a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/package.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "name": "@analysys/ana-charts", - "version": "1.0.4", - "main": "dist/index.js", - "repository": "git@git.analysys.cn:fss-modules/echarts-tooltip.git", - "author": "liuxin ", - "license": "MIT", - "scripts": { - "dev": "npm run clean && parcel ./example/index.html -p 3000", - "build": "npm run clean && cross-env NODE_ENV=production webpack --config ./build/webpack.config.prod.js", - "lint": "standard \"**/*.{js,vue}\"", - "lint:fix": "standard \"**/*.{js,vue}\" --fix", - "prepublishOnly": "npm run build", - "clean": "rimraf dist", - "start": "npm run dev", - "test": "npm run lint" - }, - "dependencies": { - "echarts": "^4.1.0" - }, - "devDependencies": { - "@fedor/standard": "^1.0.3", - "@vue/component-compiler-utils": "^2.2.0", - "autoprefixer": "^9.1.3", - "babel-core": "^6.26.3", - "babel-eslint": "^8.2.6", - "babel-loader": "^7.1.1", - "babel-plugin-transform-object-rest-spread": "^6.26.0", - "babel-preset-env": "^1.7.0", - "cross-env": "^5.2.0", - "css-loader": "^0.28.8", - "cssnano": "^4.1.0", - "extract-text-webpack-plugin": "^3.0.2", - "ghooks": "^2.0.4", - "node-sass": "^4.9.3", - "optimize-css-assets-webpack-plugin": "3.2.0", - "postcss-loader": "^3.0.0", - "rimraf": "^2.6.2", - "sass-loader": "^7.1.0", - "uglifyjs-webpack-plugin": "^1.2.7", - "vue": "^2.5.17", - "vue-hot-reload-api": "^2.3.0", - "vue-loader": "^15.4.1", - "vue-router": "^3.0.1", - "vue-style-loader": "^4.1.1", - "vue-template-compiler": "^2.5.17", - "webpack": "^3.12.0", - "webpack-merge": "^4.1.4" - }, - "standard": { - "parser": "babel-eslint", - "ignore": [ - "src/font/*", - "dist/**", - "test/coverage/**", - "karma.conf.js", - "postcss.config.js" - ] - }, - "config": { - "ghooks": { - "pre-commit": "npm run lint" - } - } -} diff --git a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/postcss.config.js b/dolphinscheduler-ui/src/lib/@analysys/ana-charts/postcss.config.js deleted file mode 100644 index 1b3026aecd..0000000000 --- a/dolphinscheduler-ui/src/lib/@analysys/ana-charts/postcss.config.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - plugins: [ - require('autoprefixer')({ - browsers: ["ie > 8", "last 2 version", "safari >= 9"] - }) - ] -}