zmp-vue
Version:
Build full featured iOS & Android apps using ZMP & Vue
204 lines (180 loc) • 6.35 kB
JavaScript
;
exports.__esModule = true;
exports.default = void 0;
var _vue = require("vue");
var _utils = require("../shared/utils");
var _zmp = require("../shared/zmp");
function render(_ctx, _cache) {
return (0, _vue.openBlock)(), (0, _vue.createBlock)("div", {
ref: "elRef",
class: _ctx.classes
}, [((0, _vue.openBlock)(), (0, _vue.createBlock)("svg", {
xmlns: "http://www.w3.org/2000/svg",
width: _ctx.size,
height: _ctx.size,
viewBox: "-" + _ctx.size / 3 + " -" + _ctx.size / 3 + " " + _ctx.size * 2 / 3 + " " + _ctx.size * 2 / 3,
style: {
transform: 'rotate(-90deg)'
}
}, [((0, _vue.openBlock)(true), (0, _vue.createBlock)(_vue.Fragment, null, (0, _vue.renderList)(_ctx.paths, function (path, index) {
return (0, _vue.openBlock)(), (0, _vue.createBlock)("path", {
key: path.label || index,
d: path.points,
fill: path.color,
"data-index": index,
class: _ctx.classNames({
'pie-chart-hidden': _ctx.currentIndex !== null && _ctx.currentIndex !== index
}),
onClick: function onClick($event) {
return _ctx.setCurrentIndex(index);
},
onMouseenter: function onMouseenter($event) {
return _ctx.setCurrentIndex(index);
},
onMouseleave: _cache[1] || (_cache[1] = function ($event) {
return _ctx.setCurrentIndex(null);
})
}, null, 42, ["d", "fill", "data-index", "onClick", "onMouseenter"]);
}), 128))], 12, ["width", "height", "viewBox"])), (0, _vue.renderSlot)(_ctx.$slots, "default")], 2);
}
var _default2 = {
name: 'zmp-pie-chart',
render: render,
props: {
size: {
type: Number,
default: 320
},
tooltip: Boolean,
datasets: {
type: Array,
default: function _default() {
return [];
}
},
formatTooltip: Function
},
emits: ['select'],
setup: function setup(props, _ref) {
var emit = _ref.emit;
var elRef = (0, _vue.ref)(null);
var zmpTooltip = null;
var currentIndex = (0, _vue.ref)(null);
var setCurrentIndex = function setCurrentIndex(index) {
currentIndex.value = index;
};
var summValue = (0, _vue.computed)(function () {
var summ = 0;
props.datasets.map(function (d) {
return d.value || 0;
}).forEach(function (value) {
summ += value;
});
return summ;
});
var paths = (0, _vue.computed)(function () {
var p = [];
var cumulativePercentage = 0;
function getCoordinatesForPercentage(percentage) {
var x = Math.cos(2 * Math.PI * percentage) * (props.size / 3);
var y = Math.sin(2 * Math.PI * percentage) * (props.size / 3);
return [x, y];
}
props.datasets.forEach(function (_ref2) {
var value = _ref2.value,
label = _ref2.label,
color = _ref2.color;
var percentage = value / summValue.value;
var _getCoordinatesForPer = getCoordinatesForPercentage(cumulativePercentage),
startX = _getCoordinatesForPer[0],
startY = _getCoordinatesForPer[1];
cumulativePercentage += percentage;
var _getCoordinatesForPer2 = getCoordinatesForPercentage(cumulativePercentage),
endX = _getCoordinatesForPer2[0],
endY = _getCoordinatesForPer2[1];
var largeArcFlag = percentage > 0.5 ? 1 : 0;
var points = ["M " + startX + " " + startY, // Move
"A " + props.size / 3 + " " + props.size / 3 + " 0 " + largeArcFlag + " 1 " + endX + " " + endY, // Arc
'L 0 0' // Line
].join(' ');
p.push({
points: points,
label: label,
color: color
});
});
return p;
});
var formatTooltipText = function formatTooltipText() {
if (currentIndex.value === null) return '';
var _props$datasets$curre = props.datasets[currentIndex.value],
value = _props$datasets$curre.value,
label = _props$datasets$curre.label,
color = _props$datasets$curre.color;
var percentage = value / summValue.value * 100;
var round = function round(v) {
if (parseInt(v, 10) === v) return v;
return Math.round(v * 100) / 100;
};
if (props.formatTooltip) {
return props.formatTooltip({
index: currentIndex.value,
value: value,
label: label,
color: color,
percentage: percentage
});
}
var tooltipText = "" + (label ? label + ": " : '') + round(value) + " (" + round(percentage) + "%)";
return "\n <div class=\"pie-chart-tooltip-label\">\n <span class=\"pie-chart-tooltip-color\" style=\"background-color: " + color + ";\"></span> " + tooltipText + "\n </div>\n ";
};
var setTooltip = function setTooltip() {
var index = currentIndex.value;
if (index === null && !zmpTooltip) return;
if (!props.tooltip || !elRef.value || !_zmp.zmp) return;
if (index !== null && !zmpTooltip) {
zmpTooltip = _zmp.zmp.tooltip.create({
trigger: 'manual',
containerEl: elRef.value,
targetEl: elRef.value.querySelector("path[data-index=\"" + index + "\"]"),
text: formatTooltipText(),
cssClass: 'pie-chart-tooltip'
});
zmpTooltip.show();
return;
}
if (!zmpTooltip) return;
if (index !== null) {
zmpTooltip.setText(formatTooltipText());
zmpTooltip.setTargetEl(elRef.value.querySelector("path[data-index=\"" + index + "\"]"));
zmpTooltip.show();
} else {
zmpTooltip.hide();
}
};
(0, _vue.watch)(function () {
return currentIndex.value;
}, function () {
emit('select', currentIndex.value, props.datasets[currentIndex.value]);
setTooltip();
});
(0, _vue.onBeforeUnmount)(function () {
if (zmpTooltip && zmpTooltip.destroy) {
zmpTooltip.destroy();
}
zmpTooltip = null;
});
var classes = (0, _vue.computed)(function () {
return (0, _utils.classNames)('pie-chart');
});
return {
elRef: elRef,
currentIndex: currentIndex,
classes: classes,
paths: paths,
classNames: _utils.classNames,
setCurrentIndex: setCurrentIndex
};
}
};
exports.default = _default2;