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