vue-chart-component
Version:
基于echarts的图表组件库,
1,690 lines (1,592 loc) • 4.11 MB
JavaScript
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["vue-chart-component"] = factory();
else
root["vue-chart-component"] = factory();
})((typeof self !== 'undefined' ? self : this), function() {
return /******/ (function() { // webpackBootstrap
/******/ var __webpack_modules__ = ({
/***/ 1410:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
"use strict";
// ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);
// EXPORTS
__webpack_require__.d(__webpack_exports__, {
"default": function() { return /* binding */ vue_chart_base; }
});
;// CONCATENATED MODULE: ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-82.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/package/vue-chart-base/index.vue?vue&type=template&id=6e1e1270&scoped=true&
var render = function render() {
var _vm = this,
_c = _vm._self._c;
return _c('div', {
staticClass: "vChart-container"
}, [_vm.hasData ? _c('div', {
staticClass: "vChart",
attrs: {
"id": _vm.chartId
}
}) : _c('div', [_vm._v(" 暂无数据 ")])]);
};
var staticRenderFns = [];
// EXTERNAL MODULE: ./node_modules/core-js/modules/es.array.push.js
var es_array_push = __webpack_require__(7658);
// EXTERNAL MODULE: ./node_modules/echarts/index.js + 365 modules
var echarts = __webpack_require__(5289);
// EXTERNAL MODULE: ./src/package/utils.js
var utils = __webpack_require__(4941);
;// CONCATENATED MODULE: ./src/package/vue-chart-base/config.js
// 传参示例
const paramsExample = {
data: [{
type: 'line',
// 可选 图表类型 默认柱图bar
name: '折线图',
// 必传 名称
value: [10, 20, 30, 40],
// 必传 数值
showYAxis: true,
// 可选 是否显示y轴
position: 'right',
// y轴位置 默认left
yAxisName: '单位:%',
// 可选 y轴名称
stack: true,
// 可选 是否为堆叠柱图 默认false type值为bar且至少有两组柱图时有效
series: {} // 可选 自定义series配置
}, {
name: '柱图',
value: [10, 20, 30, 40]
}],
// 每个对象为一组数据 可同时绘制柱图、折线图、堆叠柱图
xAxisData: ['2023-01', '2023-02', '2023-03', '2023-04'],
// 必传 x轴数据
title: '',
// 可选 标题
option: {
title: {
text: ''
}
} // 可选 echarts 参数配置
};
let startColorList = ['25, 214, 156', '29, 184, 255', '255, 191, 70', '108, 96, 253'];
let endColorList = ['170, 255, 107', '47, 253, 248', '253, 222, 165', '191, 186, 255'];
// 图表颜色
const getColor = data => {
let startColor = startColorList;
let endColor = endColorList;
if (data.length > startColor.length || data.length > endColor.length) {
startColor = startColor.concat(startColor.slice(0, data.length - startColor.length));
endColor = endColor.concat(endColor.slice(0, data.length - endColor.length));
}
return {
startColor,
endColor
};
};
// 默认图表类型
const defaultType = 'bar';
// 折线图基础数据
const lineBaseSeries = (startColor = startColorList[0], endColor = endColorList[0]) => {
return {
type: 'line',
smooth: true,
showSymbol: false,
lineStyle: {
width: 2,
color: `rgba(${startColor}, 1)` // 线条颜色
},
itemStyle: {
color: `rgba(${startColor}, 1)`,
borderColor: '#646ace',
borderWidth: 2
},
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0,
color: `rgba(${startColor}, 1)` // 0% 处的颜色
}, {
offset: 0.2,
color: `rgba(${endColor}, 0.5)`
}, {
offset: 1,
color: `rgba(0,0,0,0)`
}],
globalCoord: false // 缺省为 false
}
}
};
};
// 柱图基础数据
const barBaseSeries = (startColor = startColorList[0], endColor = endColorList[0], stack = false) => {
return {
type: 'bar',
stack: stack,
barMaxWidth: '30',
itemStyle: {
borderColor: `rgba(${startColor}, 0.2)`,
borderWidth: '1',
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0,
color: `rgba(${startColor}, 1)` // 0% 处的颜色
}, {
offset: 0.2,
color: `rgba(${endColor}, 0.5)`
}, {
offset: 1,
color: `rgba(0,0,0,0)`
}],
globalCoord: false // 缺省为 false
}
}
};
};
const baseSeriesConfig = {
line: lineBaseSeries,
bar: barBaseSeries
};
;// CONCATENATED MODULE: ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-82.use[1]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/package/vue-chart-base/index.vue?vue&type=script&lang=js&
let idx = 1;
/* harmony default export */ var vue_chart_basevue_type_script_lang_js_ = ({
name: 'vue-chart-base',
data() {
return {
myChart: null,
chartId: '',
deepAssign: utils/* deepAssign */.n
};
},
props: {
data: {
type: Array,
default: () => []
},
xAxisData: {
type: Array,
default: () => []
},
title: {
type: String,
default: ''
},
option: {
type: Object,
default: () => ({})
}
},
computed: {
hasData() {
return this.data.length;
},
baseYAxis() {
return {
type: 'value',
nameTextStyle: {
color: 'rgba(181, 217, 255, 0.5)'
},
axisLabel: {
color: '#B5D9FF'
},
axisLine: {
show: true,
lineStyle: {
color: 'rgba(221, 238, 253, 0.2)',
width: 2
}
},
axisTick: {
show: false
},
splitLine: {
show: true,
lineStyle: {
type: 'dashed',
color: 'rgba(221, 238, 253, 0.1)'
}
}
};
}
},
watch: {
data() {
this.$nextTick(() => {
this.setChatOption();
});
}
},
created() {
this.chartId = `vChart_base_${idx++}`;
},
mounted() {
this.setChatOption();
},
methods: {
initChart() {
const dom = document.getElementById(this.chartId);
if (!dom) {
return;
}
this.myChart = echarts/* init */.S1(dom);
},
handleData() {
const {
baseYAxis,
data,
xAxisData
} = this;
const {
startColor,
endColor
} = getColor(data);
const series = [];
let yAxisList = [];
data.map((item, index) => {
if (item.showYAxis) {
const min = Math.min.apply(null, item.value);
const max = Math.max.apply(null, item.value);
yAxisList.push({
...baseYAxis,
...{
name: item.yAxisName,
position: item.position || 'left',
min: Math.floor((min - min * 0.1) / 10) * 10,
max: Math.ceil((max + max * 0.1) / 10) * 10
}
});
}
let baseType = baseSeriesConfig[defaultType];
if (item.type && baseSeriesConfig[item.type]) {
baseType = baseSeriesConfig[item.type];
}
const baseSeries = baseType(startColor[item.colorIndex || index], endColor[item.colorIndex || index], item.stack);
series.push({
name: item.name,
yAxisIndex: item.showYAxis ? yAxisList.length - 1 : 0,
...baseSeries,
data: [...item.value],
...item.series
});
});
yAxisList = yAxisList.length === 0 ? [baseYAxis] : yAxisList;
return {
xAxisData,
yAxisList,
series
};
},
setChatOption() {
if (!this.hasData) {
this.myChart && this.myChart.dispose();
this.myChart = null;
return;
}
const {
option,
title
} = this;
const {
xAxisData,
yAxisList,
series
} = this.handleData();
let opt = {
title: {
show: title,
text: title,
left: 'center',
textStyle: {
color: '#ffffff',
fontSize: 14,
lineHeight: 20
}
},
grid: {
left: '15%',
top: '15%',
right: '15%',
bottom: '20%'
},
legend: {
bottom: '5%',
textStyle: {
color: '#B5D9FF'
}
},
tooltip: {
trigger: 'axis',
backgroundColor: 'rgba(50, 50, 50, 0.7)',
borderColor: 'rgb(51, 51, 51)',
borderRadius: 5,
textStyle: {
fontSize: 12,
color: '#fff'
},
axisPointer: {
lineStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0,
color: 'rgba(255,255,255,0)' // 0% 处的颜色
}, {
offset: 0.5,
color: 'rgba(255,255,255,1)' // 100% 处的颜色
}, {
offset: 1,
color: 'rgba(195,255,250,1)' // 100% 处的颜色
}],
global: false // 缺省为 false
}
}
}
},
dataZoom: [{
type: 'inside',
start: 0,
end: 100
}],
xAxis: {
type: 'category',
axisLabel: {
//坐标轴刻度标签的相关配置
color: '#B5D9FF'
},
axisLine: {
//坐标轴轴线相关配置
show: true,
lineStyle: {
color: 'rgba(221, 238, 253, 0.2)',
width: 2
}
},
axisTick: {
show: false
},
splitLine: {
show: false
},
data: xAxisData
},
yAxis: yAxisList,
series: series
};
const opts = this.deepAssign(opt, option);
!this.myChart && this.initChart();
this.myChart && this.myChart.setOption(opts);
window.addEventListener('resize', () => {
this.myChart.resize();
});
}
}
});
;// CONCATENATED MODULE: ./src/package/vue-chart-base/index.vue?vue&type=script&lang=js&
/* harmony default export */ var package_vue_chart_basevue_type_script_lang_js_ = (vue_chart_basevue_type_script_lang_js_);
;// CONCATENATED MODULE: ./node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-64.use[0]!./node_modules/css-loader/dist/cjs.js??clonedRuleSet-64.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-64.use[2]!./node_modules/sass-loader/dist/cjs.js??clonedRuleSet-64.use[3]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/package/vue-chart-base/index.vue?vue&type=style&index=0&id=6e1e1270&prod&lang=scss&scoped=true&
// extracted by mini-css-extract-plugin
;// CONCATENATED MODULE: ./src/package/vue-chart-base/index.vue?vue&type=style&index=0&id=6e1e1270&prod&lang=scss&scoped=true&
// EXTERNAL MODULE: ./node_modules/@vue/vue-loader-v15/lib/runtime/componentNormalizer.js
var componentNormalizer = __webpack_require__(1001);
;// CONCATENATED MODULE: ./src/package/vue-chart-base/index.vue
;
/* normalize component */
var component = (0,componentNormalizer/* default */.Z)(
package_vue_chart_basevue_type_script_lang_js_,
render,
staticRenderFns,
false,
null,
"6e1e1270",
null
)
/* harmony default export */ var vue_chart_base = (component.exports);
/***/ }),
/***/ 4117:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
"use strict";
// ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);
// EXPORTS
__webpack_require__.d(__webpack_exports__, {
"default": function() { return /* binding */ vue_chart_liquidfill; }
});
;// CONCATENATED MODULE: ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-82.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/package/vue-chart-liquidfill/index.vue?vue&type=template&id=acd9ee14&scoped=true&
var render = function render() {
var _vm = this,
_c = _vm._self._c;
return _c('div', {
staticClass: "vChart-container"
}, [_vm.hasData ? _c('div', {
staticClass: "vChart-box"
}, [_c('div', {
staticClass: "vChart",
attrs: {
"id": _vm.chartId
}
}), _c('div', {
staticClass: "liquid-title",
style: {
'color': `rgb(${_vm.opt_color})`
}
}, [_c('span', {
staticClass: "liquid-num"
}, [_vm._v(_vm._s(_vm.formatNum(_vm.data.num)))]), _c('span', [_vm._v(_vm._s(_vm.data.name))])])]) : _c('div', [_vm._v(" 暂无数据 ")])]);
};
var staticRenderFns = [];
// EXTERNAL MODULE: ./node_modules/echarts/index.js + 365 modules
var echarts = __webpack_require__(5289);
// EXTERNAL MODULE: ./node_modules/echarts/lib/export/core.js + 3 modules
var core = __webpack_require__(4067);
// EXTERNAL MODULE: ./node_modules/echarts/lib/extension.js
var extension = __webpack_require__(5480);
// EXTERNAL MODULE: ./node_modules/echarts/lib/core/echarts.js + 16 modules
var core_echarts = __webpack_require__(5355);
// EXTERNAL MODULE: ./node_modules/echarts/lib/renderer/installCanvasRenderer.js + 2 modules
var installCanvasRenderer = __webpack_require__(4446);
// EXTERNAL MODULE: ./node_modules/echarts/lib/component/dataset/install.js
var install = __webpack_require__(9520);
// EXTERNAL MODULE: ./node_modules/echarts/lib/label/installLabelLayout.js + 1 modules
var installLabelLayout = __webpack_require__(7890);
;// CONCATENATED MODULE: ./node_modules/echarts/lib/echarts.js
/*
* 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.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* 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.
*/
// Default to have canvas renderer and dataset for compitatble reason.
(0,extension/* use */.D)([installCanvasRenderer/* install */.N, install/* install */.N]); // TODO: Compatitable with the following code
// import echarts from 'echarts/lib/echarts.js'
/* harmony default export */ var lib_echarts = ({
init: function () {
if (false) {} // @ts-ignore
return core_echarts/* init */.S1.apply(null, arguments);
}
}); // Import label layout by default.
// TODO remove
(0,extension/* use */.D)(installLabelLayout/* installLabelLayout */.T);
;// CONCATENATED MODULE: ./node_modules/echarts-liquidfill/src/liquidFillSeries.js
core/* extendSeriesModel */.Zr({
type: 'series.liquidFill',
optionUpdated: function () {
var option = this.option;
option.gridSize = Math.max(Math.floor(option.gridSize), 4);
},
getInitialData: function (option, ecModel) {
var dimensions = core/* helper.createDimensions */._y.createDimensions(option.data, {
coordDimensions: ['value']
});
var list = new core/* List */.aV(dimensions, this);
list.initData(option.data);
return list;
},
defaultOption: {
color: ['#294D99', '#156ACF', '#1598ED', '#45BDFF'],
center: ['50%', '50%'],
radius: '50%',
amplitude: '8%',
waveLength: '80%',
phase: 'auto',
period: 'auto',
direction: 'right',
shape: 'circle',
waveAnimation: true,
animationEasing: 'linear',
animationEasingUpdate: 'linear',
animationDuration: 2000,
animationDurationUpdate: 1000,
outline: {
show: true,
borderDistance: 8,
itemStyle: {
color: 'none',
borderColor: '#294D99',
borderWidth: 8,
shadowBlur: 20,
shadowColor: 'rgba(0, 0, 0, 0.25)'
}
},
backgroundStyle: {
color: '#E3F7FF'
},
itemStyle: {
opacity: 0.95,
shadowBlur: 50,
shadowColor: 'rgba(0, 0, 0, 0.4)'
},
label: {
show: true,
color: '#294D99',
insideColor: '#fff',
fontSize: 50,
fontWeight: 'bold',
align: 'center',
baseline: 'middle',
position: 'inside'
},
emphasis: {
itemStyle: {
opacity: 0.8
}
}
}
});
// EXTERNAL MODULE: ./node_modules/core-js/modules/es.array.push.js
var es_array_push = __webpack_require__(7658);
// EXTERNAL MODULE: ./node_modules/echarts/lib/util/number.js
var number = __webpack_require__(8662);
;// CONCATENATED MODULE: ./node_modules/echarts-liquidfill/src/liquidFillShape.js
/* harmony default export */ var liquidFillShape = (core/* graphic.extendShape */.Q.extendShape({
type: 'ec-liquid-fill',
shape: {
waveLength: 0,
radius: 0,
radiusY: 0,
cx: 0,
cy: 0,
waterLevel: 0,
amplitude: 0,
phase: 0,
inverse: false
},
buildPath: function (ctx, shape) {
if (shape.radiusY == null) {
shape.radiusY = shape.radius;
}
/**
* We define a sine wave having 4 waves, and make sure at least 8 curves
* is drawn. Otherwise, it may cause blank area for some waves when
* wave length is large enough.
*/
var curves = Math.max(Math.ceil(2 * shape.radius / shape.waveLength * 4) * 2, 8);
// map phase to [-Math.PI * 2, 0]
while (shape.phase < -Math.PI * 2) {
shape.phase += Math.PI * 2;
}
while (shape.phase > 0) {
shape.phase -= Math.PI * 2;
}
var phase = shape.phase / Math.PI / 2 * shape.waveLength;
var left = shape.cx - shape.radius + phase - shape.radius * 2;
/**
* top-left corner as start point
*
* draws this point
* |
* \|/
* ~~~~~~~~
* | |
* +------+
*/
ctx.moveTo(left, shape.waterLevel);
/**
* top wave
*
* ~~~~~~~~ <- draws this sine wave
* | |
* +------+
*/
var waveRight = 0;
for (var c = 0; c < curves; ++c) {
var stage = c % 4;
var pos = getWaterPositions(c * shape.waveLength / 4, stage, shape.waveLength, shape.amplitude);
ctx.bezierCurveTo(pos[0][0] + left, -pos[0][1] + shape.waterLevel, pos[1][0] + left, -pos[1][1] + shape.waterLevel, pos[2][0] + left, -pos[2][1] + shape.waterLevel);
if (c === curves - 1) {
waveRight = pos[2][0];
}
}
if (shape.inverse) {
/**
* top-right corner
* 2. draws this line
* |
* +------+
* 3. draws this line -> | | <- 1. draws this line
* ~~~~~~~~
*/
ctx.lineTo(waveRight + left, shape.cy - shape.radiusY);
ctx.lineTo(left, shape.cy - shape.radiusY);
ctx.lineTo(left, shape.waterLevel);
} else {
/**
* top-right corner
*
* ~~~~~~~~
* 3. draws this line -> | | <- 1. draws this line
* +------+
* ^
* |
* 2. draws this line
*/
ctx.lineTo(waveRight + left, shape.cy + shape.radiusY);
ctx.lineTo(left, shape.cy + shape.radiusY);
ctx.lineTo(left, shape.waterLevel);
}
ctx.closePath();
}
}));
/**
* Using Bezier curves to fit sine wave.
* There is 4 control points for each curve of wave,
* which is at 1/4 wave length of the sine wave.
*
* The control points for a wave from (a) to (d) are a-b-c-d:
* c *----* d
* b *
* |
* ... a * ..................
*
* whose positions are a: (0, 0), b: (0.5, 0.5), c: (1, 1), d: (PI / 2, 1)
*
* @param {number} x x position of the left-most point (a)
* @param {number} stage 0-3, stating which part of the wave it is
* @param {number} waveLength wave length of the sine wave
* @param {number} amplitude wave amplitude
*/
function getWaterPositions(x, stage, waveLength, amplitude) {
if (stage === 0) {
return [[x + 1 / 2 * waveLength / Math.PI / 2, amplitude / 2], [x + 1 / 2 * waveLength / Math.PI, amplitude], [x + waveLength / 4, amplitude]];
} else if (stage === 1) {
return [[x + 1 / 2 * waveLength / Math.PI / 2 * (Math.PI - 2), amplitude], [x + 1 / 2 * waveLength / Math.PI / 2 * (Math.PI - 1), amplitude / 2], [x + waveLength / 4, 0]];
} else if (stage === 2) {
return [[x + 1 / 2 * waveLength / Math.PI / 2, -amplitude / 2], [x + 1 / 2 * waveLength / Math.PI, -amplitude], [x + waveLength / 4, -amplitude]];
} else {
return [[x + 1 / 2 * waveLength / Math.PI / 2 * (Math.PI - 2), -amplitude], [x + 1 / 2 * waveLength / Math.PI / 2 * (Math.PI - 1), -amplitude / 2], [x + waveLength / 4, 0]];
}
}
;// CONCATENATED MODULE: ./node_modules/echarts-liquidfill/src/liquidFillView.js
var parsePercent = number/* parsePercent */.GM;
function isPathSymbol(symbol) {
return symbol && symbol.indexOf('path://') === 0;
}
core/* extendChartView */.Zy({
type: 'liquidFill',
render: function (seriesModel, ecModel, api) {
var self = this;
var group = this.group;
group.removeAll();
var data = seriesModel.getData();
var itemModel = data.getItemModel(0);
var center = itemModel.get('center');
var radius = itemModel.get('radius');
var width = api.getWidth();
var height = api.getHeight();
var size = Math.min(width, height);
// itemStyle
var outlineDistance = 0;
var outlineBorderWidth = 0;
var showOutline = seriesModel.get('outline.show');
if (showOutline) {
outlineDistance = seriesModel.get('outline.borderDistance');
outlineBorderWidth = parsePercent(seriesModel.get('outline.itemStyle.borderWidth'), size);
}
var cx = parsePercent(center[0], width);
var cy = parsePercent(center[1], height);
var outterRadius;
var innerRadius;
var paddingRadius;
var isFillContainer = false;
var symbol = seriesModel.get('shape');
if (symbol === 'container') {
// a shape that fully fills the container
isFillContainer = true;
outterRadius = [width / 2, height / 2];
innerRadius = [outterRadius[0] - outlineBorderWidth / 2, outterRadius[1] - outlineBorderWidth / 2];
paddingRadius = [parsePercent(outlineDistance, width), parsePercent(outlineDistance, height)];
radius = [Math.max(innerRadius[0] - paddingRadius[0], 0), Math.max(innerRadius[1] - paddingRadius[1], 0)];
} else {
outterRadius = parsePercent(radius, size) / 2;
innerRadius = outterRadius - outlineBorderWidth / 2;
paddingRadius = parsePercent(outlineDistance, size);
radius = Math.max(innerRadius - paddingRadius, 0);
}
if (showOutline) {
var outline = getOutline();
outline.style.lineWidth = outlineBorderWidth;
group.add(getOutline());
}
var left = isFillContainer ? 0 : cx - radius;
var top = isFillContainer ? 0 : cy - radius;
var wavePath = null;
group.add(getBackground());
// each data item for a wave
var oldData = this._data;
var waves = [];
data.diff(oldData).add(function (idx) {
var wave = getWave(idx, false);
var waterLevel = wave.shape.waterLevel;
wave.shape.waterLevel = isFillContainer ? height / 2 : radius;
core/* graphic.initProps */.Q.initProps(wave, {
shape: {
waterLevel: waterLevel
}
}, seriesModel);
wave.z2 = 2;
setWaveAnimation(idx, wave, null);
group.add(wave);
data.setItemGraphicEl(idx, wave);
waves.push(wave);
}).update(function (newIdx, oldIdx) {
var waveElement = oldData.getItemGraphicEl(oldIdx);
// new wave is used to calculate position, but not added
var newWave = getWave(newIdx, false, waveElement);
// changes with animation
var shape = {};
var shapeAttrs = ['amplitude', 'cx', 'cy', 'phase', 'radius', 'radiusY', 'waterLevel', 'waveLength'];
for (var i = 0; i < shapeAttrs.length; ++i) {
var attr = shapeAttrs[i];
if (newWave.shape.hasOwnProperty(attr)) {
shape[attr] = newWave.shape[attr];
}
}
var style = {};
var styleAttrs = ['fill', 'opacity', 'shadowBlur', 'shadowColor'];
for (var i = 0; i < styleAttrs.length; ++i) {
var attr = styleAttrs[i];
if (newWave.style.hasOwnProperty(attr)) {
style[attr] = newWave.style[attr];
}
}
if (isFillContainer) {
shape.radiusY = height / 2;
}
// changes with animation
core/* graphic.updateProps */.Q.updateProps(waveElement, {
shape: shape,
x: newWave.x,
y: newWave.y
}, seriesModel);
if (seriesModel.isUniversalTransitionEnabled && seriesModel.isUniversalTransitionEnabled()) {
core/* graphic.updateProps */.Q.updateProps(waveElement, {
style: style
}, seriesModel);
} else {
waveElement.useStyle(style);
}
// instant changes
var oldWaveClipPath = waveElement.getClipPath();
var newWaveClipPath = newWave.getClipPath();
waveElement.setClipPath(newWave.getClipPath());
waveElement.shape.inverse = newWave.inverse;
if (oldWaveClipPath && newWaveClipPath && self._shape === symbol
// TODO use zrender morphing to apply complex symbol animation.
&& !isPathSymbol(symbol)) {
// Can be animated.
core/* graphic.updateProps */.Q.updateProps(newWaveClipPath, {
shape: oldWaveClipPath.shape
}, seriesModel, {
isFrom: true
});
}
setWaveAnimation(newIdx, waveElement, waveElement);
group.add(waveElement);
data.setItemGraphicEl(newIdx, waveElement);
waves.push(waveElement);
}).remove(function (idx) {
var wave = oldData.getItemGraphicEl(idx);
group.remove(wave);
}).execute();
if (itemModel.get('label.show')) {
group.add(getText(waves));
}
this._shape = symbol;
this._data = data;
/**
* Get path for outline, background and clipping
*
* @param {number} r outter radius of shape
* @param {boolean|undefined} isForClipping if the shape is used
* for clipping
*/
function getPath(r, isForClipping) {
if (symbol) {
// customed symbol path
if (isPathSymbol(symbol)) {
var path = core/* graphic.makePath */.Q.makePath(symbol.slice(7), {});
var bouding = path.getBoundingRect();
var w = bouding.width;
var h = bouding.height;
if (w > h) {
h = r * 2 / w * h;
w = r * 2;
} else {
w = r * 2 / h * w;
h = r * 2;
}
var left = isForClipping ? 0 : cx - w / 2;
var top = isForClipping ? 0 : cy - h / 2;
path = core/* graphic.makePath */.Q.makePath(symbol.slice(7), {}, new core/* graphic.BoundingRect */.Q.BoundingRect(left, top, w, h));
if (isForClipping) {
path.x = -w / 2;
path.y = -h / 2;
}
return path;
} else if (isFillContainer) {
// fully fill the container
var x = isForClipping ? -r[0] : cx - r[0];
var y = isForClipping ? -r[1] : cy - r[1];
return core/* helper.createSymbol */._y.createSymbol('rect', x, y, r[0] * 2, r[1] * 2);
} else {
var x = isForClipping ? -r : cx - r;
var y = isForClipping ? -r : cy - r;
if (symbol === 'pin') {
y += r;
} else if (symbol === 'arrow') {
y -= r;
}
return core/* helper.createSymbol */._y.createSymbol(symbol, x, y, r * 2, r * 2);
}
}
return new core/* graphic.Circle */.Q.Circle({
shape: {
cx: isForClipping ? 0 : cx,
cy: isForClipping ? 0 : cy,
r: r
}
});
}
/**
* Create outline
*/
function getOutline() {
var outlinePath = getPath(outterRadius);
outlinePath.style.fill = null;
outlinePath.setStyle(seriesModel.getModel('outline.itemStyle').getItemStyle());
return outlinePath;
}
/**
* Create background
*/
function getBackground() {
// Seperate stroke and fill, so we can use stroke to cover the alias of clipping.
var strokePath = getPath(radius);
strokePath.setStyle(seriesModel.getModel('backgroundStyle').getItemStyle());
strokePath.style.fill = null;
// Stroke is front of wave
strokePath.z2 = 5;
var fillPath = getPath(radius);
fillPath.setStyle(seriesModel.getModel('backgroundStyle').getItemStyle());
fillPath.style.stroke = null;
var group = new core/* graphic.Group */.Q.Group();
group.add(strokePath);
group.add(fillPath);
return group;
}
/**
* wave shape
*/
function getWave(idx, isInverse, oldWave) {
var radiusX = isFillContainer ? radius[0] : radius;
var radiusY = isFillContainer ? height / 2 : radius;
var itemModel = data.getItemModel(idx);
var itemStyleModel = itemModel.getModel('itemStyle');
var phase = itemModel.get('phase');
var amplitude = parsePercent(itemModel.get('amplitude'), radiusY * 2);
var waveLength = parsePercent(itemModel.get('waveLength'), radiusX * 2);
var value = data.get('value', idx);
var waterLevel = radiusY - value * radiusY * 2;
phase = oldWave ? oldWave.shape.phase : phase === 'auto' ? idx * Math.PI / 4 : phase;
var normalStyle = itemStyleModel.getItemStyle();
if (!normalStyle.fill) {
var seriesColor = seriesModel.get('color');
var id = idx % seriesColor.length;
normalStyle.fill = seriesColor[id];
}
var x = radiusX * 2;
var wave = new liquidFillShape({
shape: {
waveLength: waveLength,
radius: radiusX,
radiusY: radiusY,
cx: x,
cy: 0,
waterLevel: waterLevel,
amplitude: amplitude,
phase: phase,
inverse: isInverse
},
style: normalStyle,
x: cx,
y: cy
});
wave.shape._waterLevel = waterLevel;
var hoverStyle = itemModel.getModel('emphasis.itemStyle').getItemStyle();
hoverStyle.lineWidth = 0;
wave.ensureState('emphasis').style = hoverStyle;
core/* helper.enableHoverEmphasis */._y.enableHoverEmphasis(wave);
// clip out the part outside the circle
var clip = getPath(radius, true);
// set fill for clipPath, otherwise it will not trigger hover event
clip.setStyle({
fill: 'white'
});
wave.setClipPath(clip);
return wave;
}
function setWaveAnimation(idx, wave, oldWave) {
var itemModel = data.getItemModel(idx);
var maxSpeed = itemModel.get('period');
var direction = itemModel.get('direction');
var value = data.get('value', idx);
var phase = itemModel.get('phase');
phase = oldWave ? oldWave.shape.phase : phase === 'auto' ? idx * Math.PI / 4 : phase;
var defaultSpeed = function (maxSpeed) {
var cnt = data.count();
return cnt === 0 ? maxSpeed : maxSpeed * (0.2 + (cnt - idx) / cnt * 0.8);
};
var speed = 0;
if (maxSpeed === 'auto') {
speed = defaultSpeed(5000);
} else {
speed = typeof maxSpeed === 'function' ? maxSpeed(value, idx) : maxSpeed;
}
// phase for moving left/right
var phaseOffset = 0;
if (direction === 'right' || direction == null) {
phaseOffset = Math.PI;
} else if (direction === 'left') {
phaseOffset = -Math.PI;
} else if (direction === 'none') {
phaseOffset = 0;
} else {
console.error('Illegal direction value for liquid fill.');
}
// wave animation of moving left/right
if (direction !== 'none' && itemModel.get('waveAnimation')) {
wave.animate('shape', true).when(0, {
phase: phase
}).when(speed / 2, {
phase: phaseOffset + phase
}).when(speed, {
phase: phaseOffset * 2 + phase
}).during(function () {
if (wavePath) {
wavePath.dirty(true);
}
}).start();
}
}
/**
* text on wave
*/
function getText(waves) {
var labelModel = itemModel.getModel('label');
function formatLabel() {
var formatted = seriesModel.getFormattedLabel(0, 'normal');
var defaultVal = data.get('value', 0) * 100;
var defaultLabel = data.getName(0) || seriesModel.name;
if (!isNaN(defaultVal)) {
defaultLabel = defaultVal.toFixed(0) + '%';
}
return formatted == null ? defaultLabel : formatted;
}
var textRectOption = {
z2: 10,
shape: {
x: left,
y: top,
width: (isFillContainer ? radius[0] : radius) * 2,
height: (isFillContainer ? radius[1] : radius) * 2
},
style: {
fill: 'transparent'
},
textConfig: {
position: labelModel.get('position') || 'inside'
},
silent: true
};
var textOption = {
style: {
text: formatLabel(),
textAlign: labelModel.get('align'),
textVerticalAlign: labelModel.get('baseline')
}
};
Object.assign(textOption.style, core/* helper.createTextStyle */._y.createTextStyle(labelModel));
var outsideTextRect = new core/* graphic.Rect */.Q.Rect(textRectOption);
var insideTextRect = new core/* graphic.Rect */.Q.Rect(textRectOption);
insideTextRect.disableLabelAnimation = true;
outsideTextRect.disableLabelAnimation = true;
var outsideText = new core/* graphic.Text */.Q.Text(textOption);
var insideText = new core/* graphic.Text */.Q.Text(textOption);
outsideTextRect.setTextContent(outsideText);
insideTextRect.setTextContent(insideText);
var insColor = labelModel.get('insideColor');
insideText.style.fill = insColor;
var group = new core/* graphic.Group */.Q.Group();
group.add(outsideTextRect);
group.add(insideTextRect);
// clip out waves for insideText
var boundingCircle = getPath(radius, true);
wavePath = new core/* graphic.CompoundPath */.Q.CompoundPath({
shape: {
paths: waves
},
x: cx,
y: cy
});
wavePath.setClipPath(boundingCircle);
insideTextRect.setClipPath(wavePath);
return group;
}
},
dispose: function () {
// dispose nothing here
}
});
;// CONCATENATED MODULE: ./node_modules/echarts-liquidfill/src/liquidFill.js
;// CONCATENATED MODULE: ./node_modules/echarts-liquidfill/index.js
;// CONCATENATED MODULE: ./src/package/vue-chart-liquidfill/config.js
// 传参示例
const paramsExample = {
data: {
value: 0.8,
// 必传 百分比数值 范围0-1
colorIndex: 1,
// 可选 使用的颜色序号 不传默认使用第一个颜色
color: '64, 158, 255',
// 可选 自定义颜色 参数值为rgb颜色 有此参数时默认颜色序号无效
name: '默认样式2',
// 可选 标题
num: 12121,
// 可选 数值
thousandFormatNum: true // 可选 数值是否千分位格式化 默认为false
},
option: {
title: {
text: ''
}
},
// 可选 echarts 参数配置
series: {} // 可选 echarts 数值配置
};
// 默认颜色
const defaultColorList = ['64, 158, 255', '103, 194, 58', '230, 162, 60'];
// 默认标题配置
const defaultTitleOpt = {
text: '',
textStyle: {
fontWeight: 'normal',
fontSize: 25,
color: 'rgb(97, 142, 205)'
}
};
// 默认参数配置
const defaultOpts = {
backgroundColor: 'transparent',
// 背景颜色
title: defaultTitleOpt
};
// EXTERNAL MODULE: ./src/package/utils.js
var utils = __webpack_require__(4941);
;// CONCATENATED MODULE: ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-82.use[1]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/package/vue-chart-liquidfill/index.vue?vue&type=script&lang=js&
let idx = 1;
/* harmony default export */ var vue_chart_liquidfillvue_type_script_lang_js_ = ({
name: 'vue-chart-liquidfill',
props: {
data: {
type: Object,
default: {}
},
option: {
type: Object,
default: () => ({})
},
series: {
type: Object,
default: () => ({})
}
},
data() {
return {
myChart: null,
chartId: '',
deepAssign: utils/* deepAssign */.n
};
},
computed: {
hasData() {
return this.data && Object.keys(this.data).length;
},
formatNum() {
return val => {
const thousandFormatNum = this.data.thousandFormatNum;
return thousandFormatNum ? (0,utils/* thousandFormat */.P)(val) : val;
};
},
// 颜色
opt_color() {
let {
color,
colorIndex
} = this.data;
colorIndex && colorIndex--;
const defaultColor = defaultColorList[colorIndex] ? defaultColorList[colorIndex] : defaultColorList[0];
return color || defaultColor;
},
// 参数配置
opts() {
return this.deepAssign(defaultOpts, this.option);
},
defaultSeries() {
const {
value
} = this.data;
const {
opt_color
} = this;
const numList = [value, value, value];
const series = {
type: 'liquidFill',
radius: '90%',
data: numList,
// 波纹颜色
color: [{
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 1,
color: 'rgba(58, 71, 212, 0)'
}, {
offset: 0.5,
color: 'rgba(31, 222, 225, .2)'
}, {
offset: 0,
color: `rgba(${opt_color}, 1)`
}],
globalCoord: false
}],
// 内部背景色
backgroundStyle: {
color: {
type: 'linear',
x: 1,
y: 0,
x2: 0.5,
y2: 1,
colorStops: [{
offset: 1,
color: 'rgba(68, 145, 253, 0)'
}, {
offset: 0.5,
color: 'rgba(68, 145, 253, .25)'
}, {
offset: 0,
color: 'rgba(68, 145, 253, 1)'
}],
globalCoord: false
}
},
// 外边框颜色 上至下
outline: {
borderDistance: 8,
// 边框与内部距离
itemStyle: {
borderWidth: 3,
borderColor: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0,
color: 'rgba(69, 73, 240, 1)'
}, {
offset: 0.7,
color: 'rgba(69, 73, 240, .25)'
}, {
offset: 1,
color: `rgba(${opt_color}, 1)`
}],
globalCoord: false
},
shadowBlur: 10,
shadowColor: '#000'
}
},
// 中间百分比数值
label: {
fontSize: 20,
color: '#06c8f9'
}
};
return series;
},
opt_series() {
return this.deepAssign(this.defaultSeries, this.series);
}
},
watch: {
data() {
this.$nextTick(() => {
this.setChatOption();
});
}
},
created() {
this.chartId = `vChart_liquidFill_${idx++}`;
},
mounted() {
this.setChatOption();
},
methods: {
initChart() {
const dom = document.getElementById(this.chartId);
if (!dom) {
return;
}
this.myChart = echarts/* init */.S1(dom);
},
setChatOption() {
if (!this.hasData) {
this.myChart && this.myChart.dispose();
this.myChart = null;
return;
}
const {
opts,
opt_series
} = this;
let option = {
series: [opt_series],
...opts
};
!this.myChart && this.initChart();
this.myChart && this.myChart.setOption(option);
window.addEventListener('resize', () => {
this.myChart.resize();
});
}
}
});
;// CONCATENATED MODULE: ./src/package/vue-chart-liquidfill/index.vue?vue&type=script&lang=js&
/* harmony default export */ var package_vue_chart_liquidfillvue_type_script_lang_js_ = (vue_chart_liquidfillvue_type_script_lang_js_);
;// CONCATENATED MODULE: ./node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-64.use[0]!./node_modules/css-loader/dist/cjs.js??clonedRuleSet-64.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-64.use[2]!./node_modules/sass-loader/dist/cjs.js??clonedRuleSet-64.use[3]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/package/vue-chart-liquidfill/index.vue?vue&type=style&index=0&id=acd9ee14&prod&lang=scss&scoped=true&
// extracted by mini-css-extract-plugin
;// CONCATENATED MODULE: ./src/package/vue-chart-liquidfill/index.vue?vue&type=style&index=0&id=acd9ee14&prod&lang=scss&scoped=true&
// EXTERNAL MODULE: ./node_modules/@vue/vue-loader-v15/lib/runtime/componentNormalizer.js
var componentNormalizer = __webpack_require__(1001);
;// CONCATENATED MODULE: ./src/package/vue-chart-liquidfill/index.vue
;
/* normalize component */
var component = (0,componentNormalizer/* default */.Z)(
package_vue_chart_liquidfillvue_type_script_lang_js_,
render,
staticRenderFns,
false,
null,
"acd9ee14",
null
)
/* harmony default export */ var vue_chart_liquidfill = (component.exports);
/***/ }),
/***/ 882:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
"use strict";
// ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);
// EXPORTS
__webpack_require__.d(__webpack_exports__, {
"default": function() { return /* binding */ vue_chart_pie; }
});
;// CONCATENATED MODULE: ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-82.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/package/vue-chart-pie/index.vue?vue&type=template&id=57e958ae&scoped=true&
var render = function render() {
var _vm = this,
_c = _vm._self._c;
return _c('div', {
staticClass: "vChart-container"
}, [_vm.hasData ? _c('div', {
staticClass: "vChart",
attrs: {
"id": _vm.chartId
}
}) : _c('div', [_vm._v(" 暂无数据 ")])]);
};
var staticRenderFns = [];
// EXTERNAL MODULE: ./node_modules/core-js/modules/es.array.push.js
var es_array_push = __webpack_require__(7658);
// EXTERNAL MODULE: ./src/package/utils.js
var utils = __webpack_require__(4941);
;// CONCATENATED MODULE: ./src/package/vue-chart-pie/config.js
// 传参示例
const paramsExample = {
data: [{
name: 'xx',
// 必传 名称
value: '1',
// 必传 数值
ratio: '20%',
// 可选 比率
thousandFormatNum: true // 可选 数值是否千分位格式化 默认为false
}],
// 数据
option: {
title: {
text: ''
}
},
// 可选 echarts 参数配置
seriesOpts: {
radius: ['50%', '60%'],
center: ['30%', '50%'],
avoidLabelOverlap: false,
label: {
show: false,
position: 'center',
color: '#B5D9FF',
formatter: ['{title|{c0}}', '{value|{b0}}'].join('\n'),
fontSize: 14,
fontWeight: 600,
rich: {
title: {
color: '#ffffff',
fontSize: 30,
fontWeight: 600,
lineHeight: 66
}
}
},
emphasis: {
label: {
show: true
}
}
} // 饼图series配置
};
// 图表颜色
const getColor = data => {
let startColor = ['28, 184, 255', '255, 191, 70', '0, 203, 141', '72, 249, 253', '255, 242, 92', '108, 96, 253'];
let endColor = ['181, 218, 252', '253, 222, 165', '124, 255, 215', '207, 254, 255', '255, 252, 222', '191, 186, 255'];
if (data.length > startColor.length || data.length > endColor.length) {
startColor = startColor.concat(startColor.slice(0, data.length - startColor.length));
endColor = endColor.concat(endColor.slice(0, data.length - endColor.length));
}
return {
startColor,
endColor
};
};
// EXTERNAL MODULE: ./node_modules/echarts/index.js + 365 modules
var echarts = __webpack_require__(5289);
;// CONCATENATED MODULE: ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-82.use[1]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/package/vue-chart-pie/index.vue?vue&type=script&lang=js&
let idx = 1;
/* harmony default export */ var vue_chart_pievue_type_script_lang_js_ = ({
name: 'vue-chart-pie',
props: {
data: {
type: Array,
default: () => []
},
option: {
type: Object,
default: () => {}
},
seriesOpts: {
type: Object,
default: () => ({})
}
},
data() {
return {
myChart: null,
chartId: '',
deepAssign: utils/* deepAssign */.n
};
},
computed: {
hasData() {
return this.data.length;
},
baseLabel() {
return {
show: false,
position: 'center',
color: '#B5D9FF',
formatter: ['{title|{c0}}', '{value|{b0}}'].join('\n'),
fontSize: 14,
fontWeight: 600,
rich: {
title: {
color: '#ffffff',
fontSize: 30,
fontWeight: 600,
lineHeight: 66
}
}
};
},
baseSeries() {
return {
type: 'pie',
radius: ['50%', '60%'],
center: ['30%', '50%'],
avoidLabelOverlap: false,
label: this.baseLabel,
emphasis: {
label: {
show: true
}
}
};
},
// 默认图例
defaultLegend() {
const legend = {
orient: 'vertical',
right: '5%',
top: '30%',
textStyle: {
color: 'rgba(181, 217, 255, 0.8)',
lineHeight: 20,
rich: {
name: {
fontSize: 14
},
value: {
color: '#F5FAFF',
fontSize: 12
}
}
},
formatter: name => {
const data = this.data.find(item => {
return item.name === name;
});
const {
value,
ratio,
thousandFormatNum
} = data;
const num = thousandFormatNum ? (0,utils/* thousandFormat */.P)(value) : value;
let content = `{name|${name}} {value|${num}}`;
if (ratio) {
content += ` {value|${ratio}}`;
}
return content;
}
};
return legend;
},
// 参数配置
opts() {
const defaultOpts = {
legend: this.defaultLegend
};
return this.deepAssign(defaultOpts, this.option);
}
},
watch: {
data() {
this.$nextTick(() => {
this.setChatOption();
});
}
},
created() {
this.chartId = `vChart_pie_${idx++}`;
},
mounted() {
this.setChatOption();
},
methods: {
initChart() {
const dom = document.getElementById(this.chartId);
if (!dom) {
return;
}
this.myChart = echarts/* init */.S1(dom);
},
handleData() {
const {
data
} = this;
const {
startColor,
endColor
} = getColor(data);
const RealData = [];
const borderData = [];
const legendData = [];
let total = 0;
data.map(item => {
// total += Number(item.value)
RealData.push(JSON.parse(JSON.stringify(item)));
borderData.push(JSON.parse(JSON.stringify(item)));
legendData.push({
name: item.name + item.value
});
});
total = (0,utils/* thousandFormat */.P)(total);
RealData.map((item, index) => {
item.itemStyle = {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0,
color: `rgba(${startColor[index]}, 1)` // 0% 处的颜色
}, {
offset: 1,
color: `rgba(${endColor[index]}, 1)` // 100% 处的颜色
}],
globalCoord: false