iep-ui
Version:
An enterprise-class UI design language and Vue-based implementation
446 lines (411 loc) • 17.7 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _vueTypes = require('../_util/vue-types');
var _vueTypes2 = _interopRequireDefault(_vueTypes);
var _lodash = require('lodash');
var _elementResizeDetector = require('element-resize-detector');
var _elementResizeDetector2 = _interopRequireDefault(_elementResizeDetector);
var _empty = require('../empty');
var _empty2 = _interopRequireDefault(_empty);
var _spin = require('../spin');
var _spin2 = _interopRequireDefault(_spin);
var _zrender = require('zrender');
var zrender = _interopRequireWildcard(_zrender);
var _colorUtils = require('../toolkits/colorUtils');
var _colorUtils2 = _interopRequireDefault(_colorUtils);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
exports['default'] = {
name: 'IepRingProgressBar',
props: {
start: _vueTypes2['default'].number.def(0),
end: _vueTypes2['default'].number.def(300),
target: _vueTypes2['default'].number.def(0),
real: _vueTypes2['default'].number.def(0),
radius: _vueTypes2['default'].number.def(160),
realColor: _vueTypes2['default'].string.def('#FF7E00'),
targetColor: _vueTypes2['default'].string.def('#03C98C'),
name: _vueTypes2['default'].string.def('AQI指数'),
desc: _vueTypes2['default'].string.def('表现良好,请继续保持'),
theme: _vueTypes2['default'].oneOf(['dark', 'light']).def('dark'),
icon: _vueTypes2['default'].oneOf(['fine', 'good', 'bad']).def('fine'),
loading: _vueTypes2['default'].bool.def(false),
image: _vueTypes2['default'].any,
description: _vueTypes2['default'].any,
imageStyle: _vueTypes2['default'].object
},
data: function data() {
return {
isEmpty: _lodash.isEmpty,
chart: null
};
},
created: function created() {
this.handleWindowResize = (0, _lodash.debounce)(this.handleWindowResize, 300);
},
mounted: function mounted() {
var _this = this;
window.addEventListener('resize', this.handleWindowResize);
this.addChartResizeListener();
this.watchData = this.$watch('target', function (e) {
if (e > 0) {
if (_this.chart) {
_this.chart.clear();
}
var _$refs$chartDom$getBo = _this.$refs.chartDom.getBoundingClientRect(),
width = _$refs$chartDom$getBo.width,
height = _$refs$chartDom$getBo.height;
_this.renderChartView(width, height);
}
}, {
immediate: true,
deep: true
});
},
beforeDestroy: function beforeDestroy() {
window.removeEventListener('resize', this.handleWindowResize);
this.watchData();
if (this.chart) {
this.chart.dispose();
this.chart = null;
}
},
methods: {
handleWindowResize: function handleWindowResize() {
if (!this.chart) return;
var _$refs$chartDom$getBo2 = this.$refs.chartDom.getBoundingClientRect(),
width = _$refs$chartDom$getBo2.width,
height = _$refs$chartDom$getBo2.height;
this.renderChartView(width, height);
},
addChartResizeListener: function addChartResizeListener() {
var _this2 = this;
var instance = (0, _elementResizeDetector2['default'])({
strategy: 'scroll',
callOnAdd: true
});
instance.listenTo(this.$el, function () {
if (!_this2.chart) return;
var _$refs$chartDom$getBo3 = _this2.$refs.chartDom.getBoundingClientRect(),
width = _$refs$chartDom$getBo3.width,
height = _$refs$chartDom$getBo3.height;
_this2.renderChartView(width, height);
});
},
renderChartView: function renderChartView(width, h) {
var dom = this.$refs.chartDom;
if ((0, _lodash.isEmpty)(dom) || !dom) {
return false;
}
var _$props = this.$props,
theme = _$props.theme,
start = _$props.start,
end = _$props.end,
target = _$props.target,
real = _$props.real,
name = _$props.name,
desc = _$props.desc,
radius = _$props.radius,
realColor = _$props.realColor,
targetColor = _$props.targetColor,
icon = _$props.icon;
this.chart = zrender.init(dom);
var options = {
radius: radius,
arcWidth: radius / 10,
fontWidth: 12,
leftText: start,
rightText: end,
realText: real,
realName: name,
descText: desc,
targetText: target,
targetTooltip: '\u76EE\u6807\u503C\uFF1A' + target
};
var height = h / 2 + options.radius * 2;
this.chart.clear();
this.chart.resize({
width: width,
height: height
});
var realText = 0,
targetText = 0,
tagIcon = null;
if (parseInt(options.realText) >= parseInt(options.rightText)) {
realText = parseInt(options.rightText);
} else {
realText = parseInt(options.realText);
}
if (parseInt(options.targetText) >= parseInt(options.rightText)) {
targetText = parseInt(options.rightText);
} else {
targetText = parseInt(options.targetText);
}
if (icon === 'fine') {
tagIcon = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSLliIbnu4QtMiIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiPgogIDxkZWZzPgogICAgPHN0eWxlPgogICAgICAuY2xzLTEgewogICAgICAgIGZpbGw6IG5vbmU7CiAgICAgIH0KCiAgICAgIC5jbHMtMiB7CiAgICAgICAgZmlsbDogI2ZiY2E1NzsKICAgICAgfQoKICAgICAgLmNscy0zIHsKICAgICAgICBmaWxsOiAjNWE0NDBmOwogICAgICAgIGZpbGwtcnVsZTogZXZlbm9kZDsKICAgICAgfQogICAgPC9zdHlsZT4KICA8L2RlZnM+CiAgPHJlY3QgaWQ9IuefqeW9oiIgY2xhc3M9ImNscy0xIiB3aWR0aD0iMjQiIGhlaWdodD0iMjQiPjwvcmVjdD4KICA8Y2lyY2xlIGlkPSLmpK3lnIblvaIiIGNsYXNzPSJjbHMtMiIgY3g9IjEyIiBjeT0iMTIiIHI9IjEyIj48L2NpcmNsZT4KICA8cGF0aCBpZD0i5ZCI5bm25b2i54q2IiBjbGFzcz0iY2xzLTMiIGQ9Ik04LjM3NSwxMUExLjQ0MiwxLjQ0MiwwLDAsMSw3LDkuNSwxLjQ0MiwxLjQ0MiwwLDAsMSw4LjM3NSw4LDEuNDQyLDEuNDQyLDAsMCwxLDkuNzUsOS41LDEuNDQyLDEuNDQyLDAsMCwxLDguMzc1LDExWm04LjI1LDBBMS40NDIsMS40NDIsMCwwLDEsMTUuMjUsOS41LDEuMzgsMS4zOCwwLDEsMSwxOCw5LjUsMS40NDIsMS40NDIsMCwwLDEsMTYuNjI1LDExWiI+PC9wYXRoPgogIDxwYXRoIGlkPSLot6/lvoQiIGNsYXNzPSJjbHMtMyIgZD0iTTcsMTRhNS43NjYsNS43NjYsMCwwLDAsNS41LDZBNS43NjYsNS43NjYsMCwwLDAsMTgsMTQiPjwvcGF0aD4KPC9zdmc+Cg==';
} else if (icon === 'good') {
tagIcon = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSLliIbnu4QtMiIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiPgogIDxkZWZzPgogICAgPHN0eWxlPgogICAgICAuY2xzLTEgewogICAgICAgIGZpbGw6IG5vbmU7CiAgICAgIH0KCiAgICAgIC5jbHMtMiB7CiAgICAgICAgZmlsbDogI2YxOTEyNjsKICAgICAgfQoKICAgICAgLmNscy0zIHsKICAgICAgICBmaWxsOiAjNWE0NDBmOwogICAgICAgIGZpbGwtcnVsZTogZXZlbm9kZDsKICAgICAgfQoKICAgICAgLmNscy00IHsKICAgICAgICBmaWxsOiAjNjU0ZTBjOwogICAgICB9CiAgICA8L3N0eWxlPgogIDwvZGVmcz4KICA8cmVjdCBpZD0i55+p5b2iIiBjbGFzcz0iY2xzLTEiIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCI+PC9yZWN0PgogIDxnIGlkPSLmpK3lnIblvaIiPgogICAgPGNpcmNsZSBpZD0i5qSt5ZyGXzMiIGRhdGEtbmFtZT0i5qSt5ZyGIDMiIGNsYXNzPSJjbHMtMiIgY3g9IjEyIiBjeT0iMTIiIHI9IjEyIj48L2NpcmNsZT4KICA8L2c+CiAgPHBhdGggaWQ9IuWQiOW5tuW9oueKtiIgY2xhc3M9ImNscy0zIiBkPSJNOC4zNzUsMTFBMS40NDIsMS40NDIsMCwwLDEsNyw5LjUsMS40NDIsMS40NDIsMCwwLDEsOC4zNzUsOCwxLjQ0MiwxLjQ0MiwwLDAsMSw5Ljc1LDkuNSwxLjQ0MiwxLjQ0MiwwLDAsMSw4LjM3NSwxMVptOC4yNSwwQTEuNDQyLDEuNDQyLDAsMCwxLDE1LjI1LDkuNSwxLjM4LDEuMzgsMCwxLDEsMTgsOS41LDEuNDQyLDEuNDQyLDAsMCwxLDE2LjYyNSwxMVoiPjwvcGF0aD4KICA8cGF0aCBpZD0i6Lev5b6EIiBjbGFzcz0iY2xzLTQiIGQ9Ik03LDE0SDlhMy4yODIsMy4yODIsMCwwLDAsMy41LDNBMy4yODIsMy4yODIsMCwwLDAsMTYsMTRoMmE1LjI2NSw1LjI2NSwwLDAsMS01LjUsNUE1LjI2NSw1LjI2NSwwLDAsMSw3LDE0WiI+PC9wYXRoPgo8L3N2Zz4K';
} else {
tagIcon = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSLliIbnu4QtMiIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiPgogIDxkZWZzPgogICAgPHN0eWxlPgogICAgICAuY2xzLTEgewogICAgICAgIGZpbGw6IG5vbmU7CiAgICAgIH0KCiAgICAgIC5jbHMtMiB7CiAgICAgICAgZmlsbDogI2QwZDVkOTsKICAgICAgfQoKICAgICAgLmNscy0zIHsKICAgICAgICBmaWxsOiAjOGE5N2EwOwogICAgICAgIGZpbGwtcnVsZTogZXZlbm9kZDsKICAgICAgfQogICAgPC9zdHlsZT4KICA8L2RlZnM+CiAgPHJlY3QgaWQ9IuefqeW9oiIgY2xhc3M9ImNscy0xIiB3aWR0aD0iMjQiIGhlaWdodD0iMjQiPjwvcmVjdD4KICA8Y2lyY2xlIGlkPSLmpK3lnIblvaIiIGNsYXNzPSJjbHMtMiIgY3g9IjEyIiBjeT0iMTIiIHI9IjEyIj48L2NpcmNsZT4KICA8cGF0aCBpZD0i5ZCI5bm25b2i54q2IiBjbGFzcz0iY2xzLTMiIGQ9Ik04LjM3NSwxMUExLjQ0MiwxLjQ0MiwwLDAsMSw3LDkuNSwxLjQ0MiwxLjQ0MiwwLDAsMSw4LjM3NSw4LDEuNDQyLDEuNDQyLDAsMCwxLDkuNzUsOS41LDEuNDQyLDEuNDQyLDAsMCwxLDguMzc1LDExWm04LjI1LDBBMS40NDIsMS40NDIsMCwwLDEsMTUuMjUsOS41LDEuMzgsMS4zOCwwLDEsMSwxOCw5LjUsMS40NDIsMS40NDIsMCwwLDEsMTYuNjI1LDExWk03LDE5YTUuMjY1LDUuMjY1LDAsMCwxLDUuNS01QTUuMjY1LDUuMjY1LDAsMCwxLDE4LDE5SDE2YTMuMjgyLDMuMjgyLDAsMCwwLTMuNS0zQTMuMjgyLDMuMjgyLDAsMCwwLDksMTlaIj48L3BhdGg+Cjwvc3ZnPgo=';
}
var panelTop = new zrender.Arc({
shape: {
cx: width / 2,
cy: height / 2,
r: options.radius,
startAngle: Math.PI * 1,
endAngle: 0,
clockwise: true
},
style: {
fill: 'none',
stroke: '#DEE2EC',
lineWidth: options.arcWidth
}
});
var panelBottom = new zrender.Arc({
invisible: parseInt(options.realText) <= 0,
shape: {
cx: width / 2,
cy: height / 2,
r: options.radius,
startAngle: Math.PI * (parseFloat(realText) / parseFloat(options.rightText) - 1),
endAngle: Math.PI * 1,
clockwise: false
},
style: {
fill: 'none',
stroke: realColor,
lineWidth: options.arcWidth
}
});
var panelTarget = new zrender.Arc({
invisible: parseInt(options.realText) <= 0,
shape: {
cx: width / 2,
cy: height / 2,
r: options.radius,
startAngle: Math.PI * (parseFloat(targetText) / parseFloat(options.rightText) - 1),
endAngle: Math.PI * 1,
clockwise: false
},
style: {
fill: 'none',
stroke: 'none',
lineWidth: options.arcWidth
}
});
var leftCircle = new zrender.Circle({
shape: {
cx: width / 2 - options.radius,
cy: height / 2,
r: options.arcWidth / 2
},
style: {
fill: parseInt(options.realText) <= 0 ? '#DEE2EC' : realColor,
lineWidth: options.arcWidth
}
});
var leftText = new zrender.Text({
style: {
text: options.leftText,
x: width / 2 - options.radius,
y: height / 2 + options.fontWidth,
width: options.arcWidth,
align: 'center',
fill: theme === 'dark' ? '#888' : '#999999'
}
});
var rightCircle = new zrender.Circle({
shape: {
cx: width / 2 - options.radius + options.radius * 2,
cy: height / 2,
r: options.arcWidth / 2
},
style: {
fill: parseInt(options.realText) >= parseInt(options.rightText) ? realColor : '#DEE2EC',
lineWidth: options.arcWidth
}
});
var _panelBottom$getUpdat = panelBottom.getUpdatedPathProxy(),
_x0 = _panelBottom$getUpdat._x0,
_y0 = _panelBottom$getUpdat._y0;
var rightText = new zrender.Text({
draggable: true,
style: {
text: options.rightText,
x: width / 2 - options.radius + options.radius * 2,
y: height / 2 + options.fontWidth,
fontSize: 12,
align: 'center',
fill: theme === 'dark' ? '#888' : '#999999'
}
});
this.chart.add(leftCircle);
this.chart.add(leftText);
this.chart.add(rightCircle);
this.chart.add(rightText);
this.chart.add(panelTop);
this.chart.add(panelBottom);
this.chart.add(panelTarget);
var expression = new zrender.Image({
x: _x0 - options.arcWidth * 1.4 / 2,
y: _y0 - options.arcWidth * 1.4 / 2,
z: 2,
style: {
width: options.arcWidth * 1.4,
image: tagIcon
}
});
var expressionCircle = new zrender.Circle({
shape: {
cx: _x0 - options.arcWidth * 1.4 / 2 + options.arcWidth / 1.4,
cy: _y0 - options.arcWidth * 1.4 / 2 + options.arcWidth / 1.4,
r: options.arcWidth / 1.3
},
style: {
fill: '#fff'
}
});
var descText = new zrender.Text({
style: {
text: options.descText,
x: realText > parseFloat(options.rightText) / 2 ? _x0 - options.arcWidth * 1.4 / 2 + options.descText.length * options.fontWidth / 1.3 : _x0 - options.arcWidth * 1.4 / 2 - options.descText.length * options.fontWidth / 1.6,
y: _y0 - options.arcWidth * 1.4 / 2 - options.fontWidth,
fill: realColor,
backgroundColor: _colorUtils2['default'].formatColor(realColor, 0.15),
borderColor: realColor,
align: 'center',
verticalAlign: 'middle',
padding: [6, 4, 4, 6],
borderRadius: 6,
borderWidth: 0.5
}
});
var targetRect = panelTarget.getUpdatedPathProxy();
var targetCircle = new zrender.Circle({
shape: {
cx: targetRect._x0,
cy: targetRect._y0,
r: options.arcWidth / 1.8
},
style: {
fill: targetColor,
stroke: '#fff',
lineWidth: 2
}
});
var targetCircleRect = targetCircle.getUpdatedPathProxy();
var targetTextLine = new zrender.Polyline({
shape: {
points: this.calcLine(targetCircleRect._xi, targetCircleRect._yi, targetText > parseFloat(options.rightText) / 2 ? false : true)
},
style: {
stroke: targetColor
}
});
var targetTextLineRect = targetTextLine.getUpdatedPathProxy();
var targetDesc = new zrender.Text({
style: {
text: options.targetTooltip,
x: targetText > parseFloat(options.rightText) / 2 ? targetTextLineRect._xi + options.targetTooltip.length * options.fontWidth / 2 : targetTextLineRect._xi - options.targetTooltip.length * options.fontWidth / 2,
y: targetTextLineRect._yi,
fill: theme === 'dark' ? '#888' : '#999999',
align: 'center',
verticalAlign: 'middle'
}
});
var nameNumberText = new zrender.Text({
style: {
text: options.realText,
x: width / 2,
y: height / 2 - options.radius / 2 + options.fontWidth * 1.6,
fill: realColor,
align: 'center',
verticalAlign: 'middle',
fontSize: width < 1360 ? 40 : 60,
fontWeight: 900
}
});
var nameText = new zrender.Text({
style: {
text: options.realName,
x: width / 2,
y: height / 2,
fill: theme === 'dark' ? '#888' : '#999999',
align: 'center',
verticalAlign: 'middle',
fontSize: 12,
fontWeight: 900
}
});
this.chart.add(expression);
this.chart.add(expressionCircle);
this.chart.add(descText);
this.chart.add(targetCircle);
this.chart.add(targetTextLine);
this.chart.add(targetDesc);
this.chart.add(nameNumberText);
this.chart.add(nameText);
},
calcLine: function calcLine(x, y, isLeft) {
if (!isLeft) {
return [[x, y], [x + 20, y - 20], [x + 60, y - 20]];
} else {
return [[x - 10, y], [x - 40, y - 20], [x - 80, y - 20]];
}
},
calcCirclePoint: function calcCirclePoint(x0, y0, r, angle) {
return {
x: x0 + r * Math.cos(angle * Math.PI / 180),
y: y0 + r * Math.sin(angle * Math.PI / 180)
};
},
getArcY: function getArcY(x, r, mindPoint) {
var arcMindY = Math.sqrt(Math.pow(r, 2) - Math.pow(x - mindPoint[0], 2)) + mindPoint[1];
return arcMindY - 2 * (arcMindY - mindPoint[1]);
},
getArcX: function getArcX(y, r, mindPoint) {
var arcMindX = Math.sqrt(Math.pow(r, 2) - Math.pow(y - mindPoint[1], 2)) + mindPoint[0];
return {
leftPoint: arcMindX - 2 * (arcMindX - mindPoint[0]),
rightPoint: arcMindX
};
},
getInstance: function getInstance() {
return this.chart;
}
},
render: function render() {
var h = arguments[0];
var _$props2 = this.$props,
imageStyle = _$props2.imageStyle,
image = _$props2.image,
description = _$props2.description,
loading = _$props2.loading,
target = _$props2.target;
var emptyProps = {
imageStyle: imageStyle,
image: image,
description: description
};
var chartNodes = h('div', { 'class': 'iep-chart-core', ref: 'chartDom' });
return h(
'div',
{ 'class': 'iep-chart' },
[target <= 0 ? h(
'div',
{ 'class': 'iep-chart-empty' },
[h(_empty2['default'], { props: emptyProps })]
) : loading ? h(
'div',
{ 'class': 'iep-chart-loading' },
[h(_spin2['default'], {
attrs: { spinning: loading }
})]
) : chartNodes]
);
}
};