UNPKG

zmp-vue

Version:

Build full featured iOS & Android apps using ZMP & Vue

414 lines (372 loc) 14 kB
"use strict"; exports.__esModule = true; exports.default = void 0; var _vue = require("vue"); var _utils = require("../shared/utils"); var _zmp = require("../shared/zmp"); var _hoisted_1 = { key: 0, class: "area-chart-axis" }; var _hoisted_2 = { key: 0 }; var _hoisted_3 = { key: 1, class: "area-chart-legend" }; function render(_ctx, _cache) { return (0, _vue.openBlock)(), (0, _vue.createBlock)("div", { ref: "elRef", class: _ctx.classes }, [((0, _vue.openBlock)(), (0, _vue.createBlock)("svg", { ref: "svgElRef", xmlns: "http://www.w3.org/2000/svg", width: _ctx.width, height: _ctx.height, viewBox: "0 0 " + _ctx.width + " " + _ctx.height, preserveAspectRatio: "none" }, [((0, _vue.openBlock)(true), (0, _vue.createBlock)(_vue.Fragment, null, (0, _vue.renderList)(_ctx.chartData, function (data, index) { return (0, _vue.openBlock)(), (0, _vue.createBlock)((0, _vue.resolveDynamicComponent)(_ctx.ChartTag), { key: _ctx.ChartTag + "-" + index, fill: _ctx.lineChart ? undefined : data.color, stroke: _ctx.lineChart ? data.color : undefined, "fill-rule": "evenodd", points: _ctx.lineChart ? undefined : data.points, d: _ctx.lineChart ? data.points : undefined }, null, 8, ["fill", "stroke", "points", "d"]); }), 128)), ((0, _vue.openBlock)(true), (0, _vue.createBlock)(_vue.Fragment, null, (0, _vue.renderList)(_ctx.verticalLines, function (line, index) { return (0, _vue.openBlock)(), (0, _vue.createBlock)("line", { key: "line-" + index, "data-index": index, fill: "#000", x1: line, y1: 0, x2: line, y2: _ctx.height, class: _ctx.classNames({ 'area-chart-current-line': _ctx.currentIndex === index }) }, null, 10, ["data-index", "x1", "x2", "y2"]); }), 128))], 8, ["width", "height", "viewBox"])), _ctx.axis ? ((0, _vue.openBlock)(), (0, _vue.createBlock)("div", _hoisted_1, [((0, _vue.openBlock)(true), (0, _vue.createBlock)(_vue.Fragment, null, (0, _vue.renderList)(_ctx.axisLabels, function (label, index) { return (0, _vue.openBlock)(), (0, _vue.createBlock)("span", { key: index }, [_ctx.visibleLegends.includes(label) ? ((0, _vue.openBlock)(), (0, _vue.createBlock)("span", _hoisted_2, (0, _vue.toDisplayString)(_ctx.formatAxisLabelMethod(label)), 1)) : (0, _vue.createCommentVNode)("", true)]); }), 128))])) : (0, _vue.createCommentVNode)("", true), _ctx.legend ? ((0, _vue.openBlock)(), (0, _vue.createBlock)("div", _hoisted_3, [((0, _vue.openBlock)(true), (0, _vue.createBlock)(_vue.Fragment, null, (0, _vue.renderList)(_ctx.datasets, function (dataset, index) { return (0, _vue.openBlock)(), (0, _vue.createBlock)((0, _vue.resolveDynamicComponent)(_ctx.LegendItemTag), { key: index, class: _ctx.classNames('area-chart-legend-item', { 'area-chart-legend-item-hidden': _ctx.hiddenDatasets.includes(index), 'area-chart-legend-button': _ctx.toggleDatasets }), type: _ctx.toggleDatasets ? 'button' : undefined, onClick: function onClick($event) { return _ctx.toggleDataset(index); } }, { default: (0, _vue.withCtx)(function () { return [(0, _vue.createVNode)("span", { style: { backgroundColor: dataset.color } }, null, 4), (0, _vue.createTextVNode)(" " + (0, _vue.toDisplayString)(_ctx.formatLegendLabelMethod(dataset.label)), 1)]; }), _: 2 }, 1032, ["class", "type", "onClick"]); }), 128))])) : (0, _vue.createCommentVNode)("", true), (0, _vue.renderSlot)(_ctx.$slots, "default")], 2); } var _default2 = { name: 'zmp-area-chart', render: render, props: { lineChart: Boolean, datasets: { type: Array, default: function _default() { return []; } }, axis: Boolean, axisLabels: { type: Array, default: function _default() { return []; } }, tooltip: Boolean, legend: Boolean, toggleDatasets: Boolean, width: { type: Number, default: 640 }, height: { type: Number, default: 320 }, maxAxisLabels: { type: Number, default: 8 }, formatAxisLabel: Function, formatLegendLabel: Function, formatTooltip: Function, formatTooltipAxisLabel: Function, formatTooltipTotal: Function, formatTooltipDataset: Function }, emits: ['select'], setup: function setup(props, _ref) { var emit = _ref.emit; var zmpTooltip = null; var currentIndex = (0, _vue.ref)(null); var hiddenDatasets = (0, _vue.ref)([]); var elRef = (0, _vue.ref)(null); var svgElRef = (0, _vue.ref)(null); var linesOffsets = (0, _vue.ref)(null); var visibleLegends = (0, _vue.computed)(function () { if (!props.maxAxisLabels || props.axisLabels.length <= props.maxAxisLabels) return props.axisLabels; var skipStep = Math.ceil(props.axisLabels.length / props.maxAxisLabels); var filtered = props.axisLabels.filter(function (label, index) { return index % skipStep === 0; }); return filtered; }); var summValues = (0, _vue.computed)(function () { var summ = []; props.datasets.filter(function (dataset, index) { return !hiddenDatasets.value.includes(index); }).forEach(function (_ref2) { var values = _ref2.values; values.forEach(function (value, valueIndex) { if (!summ[valueIndex]) summ[valueIndex] = 0; summ[valueIndex] += value; }); }); return summ; }); var chartData = (0, _vue.computed)(function () { var datasets = props.datasets, lineChart = props.lineChart, width = props.width, height = props.height; var data = []; if (!datasets.length) { return data; } var lastValues = datasets[0].values.map(function () { return 0; }); var maxValue = 0; if (lineChart) { datasets.forEach(function (_ref3) { var values = _ref3.values; var datasetMaxValue = Math.max.apply(Math, values); if (datasetMaxValue > maxValue) maxValue = datasetMaxValue; }); } else { maxValue = Math.max.apply(Math, summValues.value); } datasets.filter(function (dataset, index) { return !hiddenDatasets.value.includes(index); }).forEach(function (_ref4) { var label = _ref4.label, values = _ref4.values, color = _ref4.color; var points = values.map(function (originalValue, valueIndex) { lastValues[valueIndex] += originalValue; var value = lineChart ? originalValue : lastValues[valueIndex]; var x = valueIndex / (values.length - 1) * width; var y = height - value / maxValue * height; if (lineChart) { return "" + (valueIndex === 0 ? 'M' : 'L') + x + "," + y; } return x + " " + y; }); if (!lineChart) { points.push(width + " " + height + " 0 " + height); } data.push({ label: label, points: points.join(' '), color: color }); }); return data.reverse(); }); var verticalLines = (0, _vue.computed)(function () { var lines = []; if (!props.datasets.length) { return lines; } var values = props.datasets[0].values; values.forEach(function (value, valueIndex) { var x = valueIndex / (values.length - 1) * props.width; lines.push(x); }); return lines; }); var toggleDataset = function toggleDataset(index) { if (!props.toggleDatasets) return; if (hiddenDatasets.value.includes(index)) { hiddenDatasets.value.splice(hiddenDatasets.value.indexOf(index), 1); } else { hiddenDatasets.value.push(index); } hiddenDatasets.value = [].concat(hiddenDatasets.value); }; var formatAxisLabelMethod = function formatAxisLabelMethod(label) { if (props.formatAxisLabel) return props.formatAxisLabel(label); return label; }; var formatLegendLabelMethod = function formatLegendLabelMethod(label) { if (props.formatLegendLabel) return props.formatLegendLabel(label); return label; }; var calcLinesOffsets = function calcLinesOffsets() { var lines = svgElRef.value.querySelectorAll('line'); linesOffsets.value = []; for (var i = 0; i < lines.length; i += 1) { linesOffsets.value.push(lines[i].getBoundingClientRect().left); } }; var formatTooltip = function formatTooltip() { var index = currentIndex.value; if (index === null) return ''; var total = 0; var currentValues = props.datasets.filter(function (dataset, i) { return !hiddenDatasets.value.includes(i); }).map(function (dataset) { return { color: dataset.color, label: dataset.label, value: dataset.values[index] }; }); currentValues.forEach(function (dataset) { total += dataset.value; }); if (props.formatTooltip) { return props.formatTooltip({ index: index, total: total, datasets: currentValues }); } var labelText = props.formatTooltipAxisLabel ? props.formatTooltipAxisLabel(props.axisLabels[index]) : formatAxisLabelMethod(props.axisLabels[index]); if (!labelText) labelText = ''; var totalText = props.formatTooltipTotal ? props.formatTooltipTotal(total) : total; // prettier-ignore var datasetsText = currentValues.length > 0 ? "\n <ul class=\"area-chart-tooltip-list\">\n " + currentValues.map(function (_ref5) { var label = _ref5.label, color = _ref5.color, value = _ref5.value; var valueText = props.formatTooltipDataset ? props.formatTooltipDataset(label, value, color) : label + ": " + value; return "\n <li><span style=\"background-color: " + color + ";\"></span>" + valueText + "</li>\n "; }).join('') + "\n </ul>" : ''; // prettier-ignore return "\n <div class=\"area-chart-tooltip-label\">" + labelText + "</div>\n <div class=\"area-chart-tooltip-total\">" + totalText + "</div>\n " + datasetsText + "\n "; }; var setTooltip = function setTooltip() { var tooltip = props.tooltip, datasets = props.datasets; var index = currentIndex.value; if (!tooltip) return; var hasVisibleDataSets = datasets.filter(function (dataset, i) { return !hiddenDatasets.value.includes(i); }).length > 0; if (!hasVisibleDataSets) { if (zmpTooltip && zmpTooltip.hide) zmpTooltip.hide(); return; } if (index !== null && !zmpTooltip) { zmpTooltip = _zmp.zmp.tooltip.create({ trigger: 'manual', containerEl: elRef.value, targetEl: svgElRef.value.querySelector("line[data-index=\"" + index + "\"]"), text: formatTooltip(), cssClass: 'area-chart-tooltip' }); if (zmpTooltip && zmpTooltip.show) { zmpTooltip.show(); } return; } if (!zmpTooltip || !zmpTooltip.hide || !zmpTooltip.show) { return; } if (index !== null) { zmpTooltip.setText(formatTooltip()); zmpTooltip.setTargetEl(svgElRef.value.querySelector("line[data-index=\"" + index + "\"]")); zmpTooltip.show(); } else { zmpTooltip.hide(); } }; var onMouseEnter = function onMouseEnter() { calcLinesOffsets(); }; var onMouseMove = function onMouseMove(e) { if (!linesOffsets.value) { calcLinesOffsets(); } var currentLeft = e.pageX; if (typeof currentLeft === 'undefined') currentLeft = 0; var distances = linesOffsets.value.map(function (left) { return Math.abs(currentLeft - left); }); var minDistance = Math.min.apply(Math, distances); var closestIndex = distances.indexOf(minDistance); currentIndex.value = closestIndex; }; var onMouseLeave = function onMouseLeave() { currentIndex.value = null; }; (0, _vue.watch)(function () { return currentIndex.value; }, function () { emit('select', currentIndex.value); setTooltip(); }); (0, _vue.onMounted)(function () { if (!svgElRef.value) return; svgElRef.value.addEventListener('mouseenter', onMouseEnter); svgElRef.value.addEventListener('mousemove', onMouseMove); svgElRef.value.addEventListener('mouseleave', onMouseLeave); }); (0, _vue.onBeforeUnmount)(function () { if (zmpTooltip && zmpTooltip.destroy) { zmpTooltip.destroy(); } zmpTooltip = null; if (!svgElRef.value) return; svgElRef.value.removeEventListener('mouseenter', onMouseEnter); svgElRef.value.removeEventListener('mousemove', onMouseMove); svgElRef.value.removeEventListener('mouseleave', onMouseLeave); }); var classes = (0, _vue.computed)(function () { return (0, _utils.classNames)('area-chart'); }); var LegendItemTag = (0, _vue.computed)(function () { return props.toggleDatasets ? 'button' : 'span'; }); var ChartTag = (0, _vue.computed)(function () { return props.lineChart ? 'path' : 'polygon'; }); return { currentIndex: currentIndex, hiddenDatasets: hiddenDatasets, visibleLegends: visibleLegends, chartData: chartData, verticalLines: verticalLines, elRef: elRef, svgElRef: svgElRef, classes: classes, toggleDataset: toggleDataset, formatAxisLabelMethod: formatAxisLabelMethod, formatLegendLabelMethod: formatLegendLabelMethod, LegendItemTag: LegendItemTag, ChartTag: ChartTag, classNames: _utils.classNames }; } }; exports.default = _default2;