Browse Source
* 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 codepull/2/head
break60
5 years ago
committed by
qiaozhanwei
35 changed files with 1294 additions and 1647 deletions
@ -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) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -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 |
||||||
|
} |
@ -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) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -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 |
||||||
|
} |
||||||
|
} |
@ -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} <br/>{b} : {c}%' |
||||||
|
}, |
||||||
|
legend: { |
||||||
|
data: legendData |
||||||
|
}, |
||||||
|
series: _series |
||||||
|
}, true) |
||||||
|
} |
||||||
|
} |
@ -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) |
||||||
|
} |
||||||
|
} |
@ -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) |
||||||
|
} |
||||||
|
} |
@ -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) |
||||||
|
} |
||||||
|
} |
@ -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) |
||||||
|
} |
||||||
|
} |
@ -1,405 +0,0 @@ |
|||||||
|
|
||||||
# ana-charts |
|
||||||
|
|
||||||
echarts 扩展 |
|
||||||
|
|
||||||
## 安装 |
|
||||||
|
|
||||||
``` |
|
||||||
npm i @analysys/ana-charts |
|
||||||
``` |
|
||||||
|
|
||||||
## 特性 |
|
||||||
|
|
||||||
- 统一的数据结构 |
|
||||||
- 支持 ECharts 原生操作 |
|
||||||
|
|
||||||
## 快速开始 |
|
||||||
|
|
||||||
### 全量导入 |
|
||||||
|
|
||||||
```html |
|
||||||
<template> |
|
||||||
<div> |
|
||||||
<div id="chart" style="height:500px"></div> |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
|
|
||||||
<script> |
|
||||||
import Chart from '@analysys/ana-charts' |
|
||||||
|
|
||||||
export default { |
|
||||||
mounted () { |
|
||||||
Chart.line('#chart', [ |
|
||||||
{ key: 'Monday', value: 1 }, |
|
||||||
{ key: 'Tuesday', value: 2 }, |
|
||||||
{ key: 'Wednesday', value: 3 } |
|
||||||
]) |
|
||||||
} |
|
||||||
} |
|
||||||
</script> |
|
||||||
``` |
|
||||||
|
|
||||||
### 按需导入 |
|
||||||
|
|
||||||
```html |
|
||||||
<template> |
|
||||||
<div> |
|
||||||
<div id="chart" style="height:500px"></div> |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
|
|
||||||
<script> |
|
||||||
import { Line } from '@analysys/ana-charts' |
|
||||||
|
|
||||||
export default { |
|
||||||
mounted () { |
|
||||||
Line.init('#chart', [ |
|
||||||
{ key: 'Monday', value: 1 }, |
|
||||||
{ key: 'Tuesday', value: 2 }, |
|
||||||
{ key: 'Wednesday', value: 3 } |
|
||||||
]) |
|
||||||
} |
|
||||||
} |
|
||||||
</script> |
|
||||||
``` |
|
||||||
|
|
||||||
## 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) |
|
@ -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 |
|
||||||
} |
|
@ -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 |
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,87 +0,0 @@ |
|||||||
<template> |
|
||||||
<div class="app-container"> |
|
||||||
<div class="left"> |
|
||||||
<ul class="sidebar"> |
|
||||||
<li v-for="(link, i) in links" :key="i"> |
|
||||||
<router-link :to="link.url">{{link.name}}</router-link> |
|
||||||
<ul class="sub" v-if="link.subs"> |
|
||||||
<li v-for="(sub, j) in link.subs" :key="j"> |
|
||||||
<router-link :to="sub.url">{{sub.name}}</router-link> |
|
||||||
</li> |
|
||||||
</ul> |
|
||||||
</li> |
|
||||||
</ul> |
|
||||||
</div> |
|
||||||
<div class="right"> |
|
||||||
<router-view /> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
|
|
||||||
<script> |
|
||||||
import './styles/main.scss' |
|
||||||
|
|
||||||
export default { |
|
||||||
name: 'App', |
|
||||||
data () { |
|
||||||
return { |
|
||||||
links: [ |
|
||||||
{ |
|
||||||
name: '折线图', |
|
||||||
url: '/line', |
|
||||||
subs: [ |
|
||||||
{ name: '单条折线图', url: '/line#simple' }, |
|
||||||
{ name: '多条折线图', url: '/line#multiple' }, |
|
||||||
{ name: '横向折线图', url: '/line#reverse' } |
|
||||||
] |
|
||||||
}, |
|
||||||
{ |
|
||||||
name: '柱状图', |
|
||||||
url: '/bar', |
|
||||||
subs: [ |
|
||||||
{ name: '单条柱状图', url: '/bar#simple' }, |
|
||||||
{ name: '多条柱状图', url: '/bar#multiple' }, |
|
||||||
{ name: '横向柱状图', url: '/bar#reverse' }, |
|
||||||
{ name: '折柱混合图', url: '/bar#mixin' }, |
|
||||||
{ name: '堆叠柱状图', url: '/bar#stack' }, |
|
||||||
{ name: '时间轴柱状图', url: '/bar#timeline' } |
|
||||||
] |
|
||||||
}, |
|
||||||
{ |
|
||||||
name: '饼状图', |
|
||||||
url: '/pie', |
|
||||||
subs: [ |
|
||||||
{ name: '简单饼状图', url: '/pie#simple' }, |
|
||||||
{ name: '环形图', url: '/pie#ring' } |
|
||||||
] |
|
||||||
}, |
|
||||||
{ |
|
||||||
name: '雷达图', |
|
||||||
url: '/radar', |
|
||||||
subs: [ |
|
||||||
{ name: '简单雷达图', url: '/radar#simple' } |
|
||||||
] |
|
||||||
}, |
|
||||||
{ |
|
||||||
name: '漏斗图', |
|
||||||
url: '/funnel', |
|
||||||
subs: [ |
|
||||||
{ name: '简单漏斗图', url: '/funnel#simple' } |
|
||||||
] |
|
||||||
}, |
|
||||||
{ |
|
||||||
name: '气泡图', |
|
||||||
url: '/scatter', |
|
||||||
subs: [ |
|
||||||
{ name: '气泡图', url: '/scatter#simple' } |
|
||||||
] |
|
||||||
} |
|
||||||
] |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
</script> |
|
||||||
|
|
||||||
<style lang="scss"> |
|
||||||
|
|
||||||
</style> |
|
@ -1,15 +0,0 @@ |
|||||||
<!DOCTYPE html> |
|
||||||
<html lang="en"> |
|
||||||
|
|
||||||
<head> |
|
||||||
<meta charset="UTF-8"> |
|
||||||
<meta name=viewport content="width=device-width,user-scalable=no,initial-scale=1,maximum-scale=1,minimum-scale=1"> |
|
||||||
<title>demo</title> |
|
||||||
</head> |
|
||||||
|
|
||||||
<body> |
|
||||||
<div id="app"></div> |
|
||||||
<script src="./index.js"></script> |
|
||||||
</body> |
|
||||||
|
|
||||||
</html> |
|
@ -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') |
|
||||||
} |
|
||||||
} |
|
||||||
}) |
|
@ -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 = ['周一', '周二', '周三', '周四', '周五', '周六', '周日'] |
|
@ -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" |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,72 +0,0 @@ |
|||||||
<template> |
|
||||||
<div> |
|
||||||
<h1>柱状图示例</h1> |
|
||||||
<h2 id="simple">单条柱状图</h2> |
|
||||||
<div id="simpleChart" class="chart-container" ></div> |
|
||||||
<h2 id="multiple">多条柱状图</h2> |
|
||||||
<div id="multipleChart" class="chart-container" ></div> |
|
||||||
<h2 id="reverse">横向柱状图</h2> |
|
||||||
<div id="reverseChart" class="chart-container tall" ></div> |
|
||||||
<h2 id="mixin">折柱混合图</h2> |
|
||||||
<div id="mixinChart" class="chart-container tall" ></div> |
|
||||||
<h2 id="stack">堆叠柱状图</h2> |
|
||||||
<div id="stackChart" class="chart-container tall" ></div> |
|
||||||
<h2 id="timeline">时间轴柱状图</h2> |
|
||||||
<div id="timelineChart" class="chart-container tall" ></div> |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
|
|
||||||
<script> |
|
||||||
import Chart from '../../src/index' |
|
||||||
import { getSimpleList, getMultipleList, getTimelineList } from '../mock/data.js' |
|
||||||
import theme from '../mock/theme.json' |
|
||||||
|
|
||||||
export default { |
|
||||||
name: 'barCharts', |
|
||||||
mounted () { |
|
||||||
// 注册主题 |
|
||||||
Chart.config({ |
|
||||||
theme: { |
|
||||||
name: 'test', |
|
||||||
data: theme, |
|
||||||
default: true |
|
||||||
} |
|
||||||
}) |
|
||||||
Chart.bar('#simpleChart', getSimpleList()) |
|
||||||
Chart.bar('#multipleChart', getMultipleList(), { theme: 'none' }) |
|
||||||
Chart.bar('#reverseChart', getMultipleList(), { reverseAxis: true }) |
|
||||||
Chart.bar('#mixinChart', getMultipleList(), { |
|
||||||
lineTypes: ['直接访问', '搜索引擎'], |
|
||||||
title: '', |
|
||||||
yAxis: [ |
|
||||||
{ |
|
||||||
type: 'value', |
|
||||||
name: '数值' |
|
||||||
}, |
|
||||||
{ |
|
||||||
type: 'value', |
|
||||||
name: '温度', |
|
||||||
min: 0, |
|
||||||
max: 25, |
|
||||||
interval: 5, |
|
||||||
axisLabel: { |
|
||||||
formatter: '{value} °C' |
|
||||||
} |
|
||||||
} |
|
||||||
] |
|
||||||
}) |
|
||||||
Chart.bar('#stackChart', getMultipleList(), { |
|
||||||
title: '', |
|
||||||
stack: true |
|
||||||
}) |
|
||||||
Chart.bar('#timelineChart', getTimelineList(), { |
|
||||||
type: 'bar', |
|
||||||
title: '$timeline时间轴柱状图' |
|
||||||
}) |
|
||||||
} |
|
||||||
} |
|
||||||
</script> |
|
||||||
|
|
||||||
<style lang="scss"> |
|
||||||
</style> |
|
||||||
|
|
@ -1,23 +0,0 @@ |
|||||||
<template> |
|
||||||
<div> |
|
||||||
<h1>漏斗图示例</h1> |
|
||||||
<h2 id="simple">简单漏斗图</h2> |
|
||||||
<div id="simpleChart" class="chart-container tall" ></div> |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
|
|
||||||
<script> |
|
||||||
import Chart from '../../src/index' |
|
||||||
import { getSimpleList } from '../mock/data.js' |
|
||||||
|
|
||||||
export default { |
|
||||||
name: 'funnelCharts', |
|
||||||
mounted () { |
|
||||||
Chart.funnel('#simpleChart', getSimpleList()) |
|
||||||
} |
|
||||||
} |
|
||||||
</script> |
|
||||||
|
|
||||||
<style lang="scss"> |
|
||||||
</style> |
|
||||||
|
|
@ -1,29 +0,0 @@ |
|||||||
<template> |
|
||||||
<div> |
|
||||||
<h1>折线图示例</h1> |
|
||||||
<h2 id="simple">单条折线图</h2> |
|
||||||
<div id="simpleChart" class="chart-container" ></div> |
|
||||||
<h2 id="multiple">多条折线图</h2> |
|
||||||
<div id="multipleChart" class="chart-container" ></div> |
|
||||||
<h2 id="reverse">横向折线图</h2> |
|
||||||
<div id="reverseChart" class="chart-container tall" ></div> |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
|
|
||||||
<script> |
|
||||||
import { Line } from '../../src/index' |
|
||||||
import { getSimpleList, getMultipleList } from '../mock/data.js' |
|
||||||
|
|
||||||
export default { |
|
||||||
name: 'lineCharts', |
|
||||||
mounted () { |
|
||||||
Line.init('#simpleChart', getSimpleList()) |
|
||||||
Line.init('#multipleChart', getMultipleList()) |
|
||||||
Line.init('#reverseChart', getMultipleList(), { reverseAxis: true }) |
|
||||||
} |
|
||||||
} |
|
||||||
</script> |
|
||||||
|
|
||||||
<style lang="scss"> |
|
||||||
</style> |
|
||||||
|
|
@ -1,29 +0,0 @@ |
|||||||
<template> |
|
||||||
<div> |
|
||||||
<h1>饼状图示例</h1> |
|
||||||
<h2 id="simple">简单饼状图</h2> |
|
||||||
<div id="simpleChart" class="chart-container" ></div> |
|
||||||
<h2 id="ring">环形图</h2> |
|
||||||
<div id="ringChart" class="chart-container" ></div> |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
|
|
||||||
<script> |
|
||||||
import Chart from '../../src/index' |
|
||||||
import { getSimpleList } from '../mock/data.js' |
|
||||||
|
|
||||||
export default { |
|
||||||
name: 'pieCharts', |
|
||||||
mounted () { |
|
||||||
Chart.pie('#simpleChart', getSimpleList()) |
|
||||||
Chart.pie('#ringChart', getSimpleList(), { |
|
||||||
title: '环形图', |
|
||||||
ring: true |
|
||||||
}) |
|
||||||
} |
|
||||||
} |
|
||||||
</script> |
|
||||||
|
|
||||||
<style lang="scss"> |
|
||||||
</style> |
|
||||||
|
|
@ -1,23 +0,0 @@ |
|||||||
<template> |
|
||||||
<div> |
|
||||||
<h1>雷达图示例</h1> |
|
||||||
<h2 id="simple">简单雷达图</h2> |
|
||||||
<div id="simpleChart" class="chart-container tall" ></div> |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
|
|
||||||
<script> |
|
||||||
import Chart from '../../src/index' |
|
||||||
import { getMultipleList } from '../mock/data.js' |
|
||||||
|
|
||||||
export default { |
|
||||||
name: 'radarCharts', |
|
||||||
mounted () { |
|
||||||
Chart.radar('#simpleChart', getMultipleList()) |
|
||||||
} |
|
||||||
} |
|
||||||
</script> |
|
||||||
|
|
||||||
<style lang="scss"> |
|
||||||
</style> |
|
||||||
|
|
@ -1,23 +0,0 @@ |
|||||||
<template> |
|
||||||
<div> |
|
||||||
<h1>气泡图示例</h1> |
|
||||||
<h2 id="simple">气泡图</h2> |
|
||||||
<div id="simpleChart" class="chart-container tall" ></div> |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
|
|
||||||
<script> |
|
||||||
import Chart from '../../src/index' |
|
||||||
import { getMultipleList } from '../mock/data.js' |
|
||||||
|
|
||||||
export default { |
|
||||||
name: 'scatterCharts', |
|
||||||
mounted () { |
|
||||||
Chart.scatter('#simpleChart', getMultipleList(true)) |
|
||||||
} |
|
||||||
} |
|
||||||
</script> |
|
||||||
|
|
||||||
<style lang="scss"> |
|
||||||
</style> |
|
||||||
|
|
@ -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 |
|
@ -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; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -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 <liuxin@analysys.com.cn>", |
|
||||||
"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" |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
Loading…
Reference in new issue