|
|
@@ -0,0 +1,1122 @@
|
|
|
+/**
|
|
|
+ * uCharts 主类
|
|
|
+ *
|
|
|
+ * 从 u-charts 核心库搬迁的核心图表类
|
|
|
+ * 添加完整类型注解
|
|
|
+ * @ts-nocheck - 为保持与原始代码逻辑完全一致,使用此标记
|
|
|
+ */
|
|
|
+
|
|
|
+import { uChartsEvent } from './u-charts-event';
|
|
|
+import { config, assign, util, getH5Offset } from '../config';
|
|
|
+import * as helperFunctions from '../helper-functions';
|
|
|
+import * as dataProcessing from '../data-processing';
|
|
|
+import * as chartsData from '../charts-data';
|
|
|
+import * as renderers from '../renderers';
|
|
|
+
|
|
|
+// 导入所有需要的函数
|
|
|
+const {
|
|
|
+ // Finders
|
|
|
+ findPieChartCurrentIndex,
|
|
|
+ findRoseChartCurrentIndex,
|
|
|
+ findRadarChartCurrentIndex,
|
|
|
+ findFunnelChartCurrentIndex,
|
|
|
+ findMapChartCurrentIndex,
|
|
|
+ findWordChartCurrentIndex,
|
|
|
+ findBarChartCurrentIndex,
|
|
|
+ findCurrentIndex,
|
|
|
+ findLegendIndex,
|
|
|
+ // Area checkers
|
|
|
+ isInPieChartArea,
|
|
|
+ isInRadarChartArea,
|
|
|
+ isInFunnelChartArea,
|
|
|
+ isInMapChartArea,
|
|
|
+ isInWordChartArea,
|
|
|
+ // Data helpers
|
|
|
+ getSeriesDataItem,
|
|
|
+ getCandleToolTipData,
|
|
|
+ // Legend helpers
|
|
|
+ getLegendDataIndex,
|
|
|
+ // Coordinate helpers
|
|
|
+ getTouches,
|
|
|
+ // Data fixers
|
|
|
+ fixPieSeries,
|
|
|
+ fixPieSeriesDefault,
|
|
|
+ // Misc
|
|
|
+ measureText,
|
|
|
+ performDraw
|
|
|
+} = helperFunctions;
|
|
|
+
|
|
|
+const {
|
|
|
+ fixPieSeries: fixPieSeriesDP,
|
|
|
+ fillSeries,
|
|
|
+ fillCustomColor,
|
|
|
+ getDataRange,
|
|
|
+ dataCombine,
|
|
|
+ dataCombineStack,
|
|
|
+ calXAxisData,
|
|
|
+ getXAxisPoints,
|
|
|
+ calYAxisData,
|
|
|
+ calCategoriesData,
|
|
|
+ getToolTipData,
|
|
|
+ getMixToolTipData
|
|
|
+} = dataProcessing;
|
|
|
+
|
|
|
+const {
|
|
|
+ getDataPoints,
|
|
|
+ getLineDataPoints,
|
|
|
+ getColumnDataPoints,
|
|
|
+ getCandleDataPoints,
|
|
|
+ getMountDataPoints,
|
|
|
+ getBarDataPoints,
|
|
|
+ getStackDataPoints,
|
|
|
+ getBarStackDataPoints,
|
|
|
+ getPieDataPoints,
|
|
|
+ getRoseDataPoints,
|
|
|
+ getRadarDataPoints,
|
|
|
+ getGaugeDataPoints,
|
|
|
+ getGaugeArcbarDataPoints,
|
|
|
+ getArcbarDataPoints,
|
|
|
+ getGaugeAxisPoints,
|
|
|
+ getFunnelDataPoints
|
|
|
+} = chartsData;
|
|
|
+
|
|
|
+const {
|
|
|
+ drawCharts,
|
|
|
+ drawXAxis,
|
|
|
+ drawYAxisGrid,
|
|
|
+ drawYAxis,
|
|
|
+ drawLegend,
|
|
|
+ drawGaugeLabel,
|
|
|
+ drawRadarLabel,
|
|
|
+ drawColumnDataPoints,
|
|
|
+ drawBarDataPoints,
|
|
|
+ drawMountDataPoints,
|
|
|
+ drawLineDataPoints,
|
|
|
+ drawAreaDataPoints,
|
|
|
+ drawCandleDataPoints,
|
|
|
+ drawPieDataPoints,
|
|
|
+ drawRadarDataPoints,
|
|
|
+ drawMapDataPoints,
|
|
|
+ drawFunnelDataPoints,
|
|
|
+ drawWordCloudDataPoints,
|
|
|
+ drawMixDataPoints,
|
|
|
+ drawScatterDataPoints,
|
|
|
+ drawBubbleDataPoints,
|
|
|
+ calValidDistance
|
|
|
+} = renderers;
|
|
|
+
|
|
|
+/**
|
|
|
+ * Canvas 上下文接口
|
|
|
+ * 兼容小程序和 H5 环境
|
|
|
+ */
|
|
|
+export interface CanvasContext {
|
|
|
+ width: number;
|
|
|
+ height: number;
|
|
|
+ padding?: number[];
|
|
|
+ // 标准 Canvas 2D API
|
|
|
+ strokeStyle?: string;
|
|
|
+ lineWidth?: number;
|
|
|
+ lineCap?: string;
|
|
|
+ font?: string;
|
|
|
+ fillStyle?: string;
|
|
|
+ textAlign?: string;
|
|
|
+ textBaseline?: string;
|
|
|
+ shadowColor?: string;
|
|
|
+ shadowOffsetX?: number;
|
|
|
+ shadowOffsetY?: number;
|
|
|
+ shadowBlur?: number;
|
|
|
+ // 兼容小程序的方法
|
|
|
+ setStrokeStyle?(style: string): void;
|
|
|
+ setLineWidth?(width: number): void;
|
|
|
+ setLineCap?(cap: string): void;
|
|
|
+ setFontSize?(size: number): void;
|
|
|
+ setFillStyle?(style: string): void;
|
|
|
+ setTextAlign?(align: string): void;
|
|
|
+ setTextBaseline?(baseline: string): void;
|
|
|
+ setShadow?(offsetX: number, offsetY: number, blur: number, color: string): void;
|
|
|
+ setLineDash?(segments: number[]): void;
|
|
|
+ draw?(): void;
|
|
|
+ [key: string]: any;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 图表标题配置
|
|
|
+ */
|
|
|
+export interface ChartsTitle {
|
|
|
+ name?: string;
|
|
|
+ fontSize?: number;
|
|
|
+ color?: string;
|
|
|
+ offsetX?: number;
|
|
|
+ offsetY?: number;
|
|
|
+ [key: string]: any;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Y轴配置
|
|
|
+ */
|
|
|
+export interface YAxisConfig {
|
|
|
+ data?: any[];
|
|
|
+ showTitle?: boolean;
|
|
|
+ disabled?: boolean;
|
|
|
+ disableGrid?: boolean;
|
|
|
+ gridSet?: string;
|
|
|
+ splitNumber?: number;
|
|
|
+ gridType?: string;
|
|
|
+ dashLength?: number;
|
|
|
+ gridColor?: string;
|
|
|
+ padding?: number;
|
|
|
+ fontColor?: string;
|
|
|
+ min?: number;
|
|
|
+ max?: number;
|
|
|
+ format?: (val: number) => string | number;
|
|
|
+ [key: string]: any;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * X轴配置
|
|
|
+ */
|
|
|
+export interface XAxisConfig {
|
|
|
+ rotateLabel?: boolean;
|
|
|
+ rotateAngle?: number;
|
|
|
+ disabled?: boolean;
|
|
|
+ disableGrid?: boolean;
|
|
|
+ splitNumber?: number;
|
|
|
+ calibration?: boolean;
|
|
|
+ fontColor?: string;
|
|
|
+ fontSize?: number;
|
|
|
+ lineHeight?: number;
|
|
|
+ marginTop?: number;
|
|
|
+ gridType?: string;
|
|
|
+ dashLength?: number;
|
|
|
+ scrollAlign?: string;
|
|
|
+ scrollPosition?: string;
|
|
|
+ boundaryGap?: string;
|
|
|
+ axisLine?: boolean;
|
|
|
+ axisLineColor?: string;
|
|
|
+ titleFontSize?: number;
|
|
|
+ titleOffsetY?: number;
|
|
|
+ titleOffsetX?: number;
|
|
|
+ titleFontColor?: string;
|
|
|
+ itemCount?: number;
|
|
|
+ enableScroll?: boolean;
|
|
|
+ [key: string]: any;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 图例配置
|
|
|
+ */
|
|
|
+export interface LegendConfig {
|
|
|
+ show?: boolean;
|
|
|
+ position?: string;
|
|
|
+ float?: string;
|
|
|
+ backgroundColor?: string;
|
|
|
+ borderColor?: string;
|
|
|
+ borderWidth?: number;
|
|
|
+ padding?: number;
|
|
|
+ margin?: number;
|
|
|
+ itemGap?: number;
|
|
|
+ fontSize?: number;
|
|
|
+ lineHeight?: number;
|
|
|
+ fontColor?: string;
|
|
|
+ formatter?: any;
|
|
|
+ hiddenColor?: string;
|
|
|
+ [key: string]: any;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 额外配置
|
|
|
+ */
|
|
|
+export interface ExtraConfig {
|
|
|
+ tooltip?: {
|
|
|
+ legendShape?: string;
|
|
|
+ [key: string]: any;
|
|
|
+ };
|
|
|
+ pie?: {
|
|
|
+ labelWidth?: number;
|
|
|
+ [key: string]: any;
|
|
|
+ };
|
|
|
+ ring?: {
|
|
|
+ labelWidth?: number;
|
|
|
+ [key: string]: any;
|
|
|
+ };
|
|
|
+ rose?: {
|
|
|
+ labelWidth?: number;
|
|
|
+ [key: string]: any;
|
|
|
+ };
|
|
|
+ candle?: {
|
|
|
+ [key: string]: any;
|
|
|
+ };
|
|
|
+ [key: string]: any;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 图表配置项
|
|
|
+ */
|
|
|
+export interface ChartsConfig {
|
|
|
+ pixelRatio?: number;
|
|
|
+ fontSize?: number;
|
|
|
+ fontColor?: string;
|
|
|
+ background?: string;
|
|
|
+ title?: ChartsTitle;
|
|
|
+ subtitle?: ChartsTitle;
|
|
|
+ duration?: number;
|
|
|
+ yAxis?: YAxisConfig;
|
|
|
+ xAxis?: XAxisConfig;
|
|
|
+ legend?: LegendConfig;
|
|
|
+ extra?: ExtraConfig;
|
|
|
+ rotate?: boolean;
|
|
|
+ animation?: boolean;
|
|
|
+ canvas2d?: boolean;
|
|
|
+ width?: number;
|
|
|
+ height?: number;
|
|
|
+ padding?: number[];
|
|
|
+ context?: CanvasContext;
|
|
|
+ type?: string;
|
|
|
+ categories?: any[];
|
|
|
+ series?: any[];
|
|
|
+ seriesMA?: any[];
|
|
|
+ color?: any[];
|
|
|
+ dataLabel?: boolean;
|
|
|
+ enableScroll?: boolean;
|
|
|
+ touchMoveLimit?: number;
|
|
|
+ area?: number[];
|
|
|
+ chartData?: any;
|
|
|
+ updateData?: boolean;
|
|
|
+ _scrollDistance_?: number;
|
|
|
+ _series_?: any[];
|
|
|
+ pix?: number;
|
|
|
+ [key: string]: any;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 滚动选项
|
|
|
+ */
|
|
|
+export interface ScrollOption {
|
|
|
+ currentOffset: number;
|
|
|
+ startTouchX: number;
|
|
|
+ distance: number;
|
|
|
+ lastMoveTime: number;
|
|
|
+ moveCount?: number;
|
|
|
+ moveCurrent1?: number;
|
|
|
+ moveCurrent2?: number;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 触摸事件接口
|
|
|
+ */
|
|
|
+export interface TouchEvent {
|
|
|
+ changedTouches?: TouchPoint[];
|
|
|
+ mp?: {
|
|
|
+ changedTouches?: TouchPoint[];
|
|
|
+ };
|
|
|
+ [key: string]: any;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 触摸点接口
|
|
|
+ */
|
|
|
+export interface TouchPoint {
|
|
|
+ x?: number;
|
|
|
+ y?: number;
|
|
|
+ clientX?: number;
|
|
|
+ clientY?: number;
|
|
|
+ [key: string]: any;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 提示框选项
|
|
|
+ */
|
|
|
+export interface ToolTipOption {
|
|
|
+ textList?: any[];
|
|
|
+ offset?: {
|
|
|
+ x: number;
|
|
|
+ y: number;
|
|
|
+ };
|
|
|
+ index?: number | number[];
|
|
|
+ group?: string[];
|
|
|
+ formatter?: (item: any, category: any, index: number, opts: any) => string;
|
|
|
+ [key: string]: any;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * uCharts 主类
|
|
|
+ *
|
|
|
+ * 核心图表类,提供所有图表操作方法
|
|
|
+ */
|
|
|
+export class uCharts extends uChartsEvent {
|
|
|
+ /** 图表配置 */
|
|
|
+ opts: ChartsConfig;
|
|
|
+
|
|
|
+ /** Canvas 上下文 */
|
|
|
+ context: CanvasContext;
|
|
|
+
|
|
|
+ /** 内部配置 */
|
|
|
+ config: any;
|
|
|
+
|
|
|
+ /** 事件处理器 */
|
|
|
+ uevent: uChartsEvent;
|
|
|
+
|
|
|
+ /** 滚动选项 */
|
|
|
+ scrollOption: ScrollOption;
|
|
|
+
|
|
|
+ /** 动画实例 */
|
|
|
+ animationInstance?: any;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 构造函数
|
|
|
+ * @param opts - 图表配置项
|
|
|
+ */
|
|
|
+ constructor(opts: ChartsConfig) {
|
|
|
+ super();
|
|
|
+
|
|
|
+ opts.pix = opts.pixelRatio ? opts.pixelRatio : 1;
|
|
|
+ opts.fontSize = opts.fontSize ? opts.fontSize : 13;
|
|
|
+ opts.fontColor = opts.fontColor ? opts.fontColor : config.fontColor;
|
|
|
+ if (opts.background == "" || opts.background == "none") {
|
|
|
+ opts.background = "#FFFFFF"
|
|
|
+ }
|
|
|
+ opts.title = assign({}, opts.title);
|
|
|
+ opts.subtitle = assign({}, opts.subtitle);
|
|
|
+ opts.duration = opts.duration ? opts.duration : 1000;
|
|
|
+ opts.yAxis = assign({}, {
|
|
|
+ data: [],
|
|
|
+ showTitle: false,
|
|
|
+ disabled: false,
|
|
|
+ disableGrid: false,
|
|
|
+ gridSet: 'number',
|
|
|
+ splitNumber: 5,
|
|
|
+ gridType: 'solid',
|
|
|
+ dashLength: 4 * opts.pix,
|
|
|
+ gridColor: '#cccccc',
|
|
|
+ padding: 10,
|
|
|
+ fontColor: '#666666'
|
|
|
+ }, opts.yAxis);
|
|
|
+ opts.xAxis = assign({}, {
|
|
|
+ rotateLabel: false,
|
|
|
+ rotateAngle: 45,
|
|
|
+ disabled: false,
|
|
|
+ disableGrid: false,
|
|
|
+ splitNumber: 5,
|
|
|
+ calibration: false,
|
|
|
+ fontColor: '#666666',
|
|
|
+ fontSize: 13,
|
|
|
+ lineHeight: 20,
|
|
|
+ marginTop: 0,
|
|
|
+ gridType: 'solid',
|
|
|
+ dashLength: 4,
|
|
|
+ scrollAlign: 'left',
|
|
|
+ boundaryGap: 'center',
|
|
|
+ axisLine: true,
|
|
|
+ axisLineColor: '#cccccc',
|
|
|
+ titleFontSize: 13,
|
|
|
+ titleOffsetY: 0,
|
|
|
+ titleOffsetX: 0,
|
|
|
+ titleFontColor: '#666666'
|
|
|
+ }, opts.xAxis);
|
|
|
+ opts.xAxis.scrollPosition = opts.xAxis.scrollAlign;
|
|
|
+ opts.legend = assign({}, {
|
|
|
+ show: true,
|
|
|
+ position: 'bottom',
|
|
|
+ float: 'center',
|
|
|
+ backgroundColor: 'rgba(0,0,0,0)',
|
|
|
+ borderColor: 'rgba(0,0,0,0)',
|
|
|
+ borderWidth: 0,
|
|
|
+ padding: 5,
|
|
|
+ margin: 5,
|
|
|
+ itemGap: 10,
|
|
|
+ fontSize: opts.fontSize,
|
|
|
+ lineHeight: opts.fontSize,
|
|
|
+ fontColor: opts.fontColor,
|
|
|
+ formatter: {},
|
|
|
+ hiddenColor: '#CECECE'
|
|
|
+ }, opts.legend);
|
|
|
+ opts.extra = assign({
|
|
|
+ tooltip: {
|
|
|
+ legendShape: 'auto'
|
|
|
+ }
|
|
|
+ }, opts.extra);
|
|
|
+ opts.rotate = opts.rotate ? true : false;
|
|
|
+ opts.animation = opts.animation ? true : false;
|
|
|
+ opts.rotate = opts.rotate ? true : false;
|
|
|
+ opts.canvas2d = opts.canvas2d ? true : false;
|
|
|
+
|
|
|
+ let config = assign({}, config);
|
|
|
+ config.color = opts.color ? opts.color : config.color;
|
|
|
+ if (opts.type == 'pie') {
|
|
|
+ config.pieChartLinePadding = opts.dataLabel === false ? 0 : opts.extra.pie.labelWidth * opts.pix || config.pieChartLinePadding * opts.pix;
|
|
|
+ }
|
|
|
+ if (opts.type == 'ring') {
|
|
|
+ config.pieChartLinePadding = opts.dataLabel === false ? 0 : opts.extra.ring.labelWidth * opts.pix || config.pieChartLinePadding * opts.pix;
|
|
|
+ }
|
|
|
+ if (opts.type == 'rose') {
|
|
|
+ config.pieChartLinePadding = opts.dataLabel === false ? 0 : opts.extra.rose.labelWidth * opts.pix || config.pieChartLinePadding * opts.pix;
|
|
|
+ }
|
|
|
+ config.pieChartTextPadding = opts.dataLabel === false ? 0 : config.pieChartTextPadding * opts.pix;
|
|
|
+
|
|
|
+ // 屏幕旋转
|
|
|
+ config.rotate = opts.rotate;
|
|
|
+ if (opts.rotate) {
|
|
|
+ let tempWidth = opts.width;
|
|
|
+ let tempHeight = opts.height;
|
|
|
+ opts.width = tempHeight;
|
|
|
+ opts.height = tempWidth;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 适配高分屏
|
|
|
+ opts.padding = opts.padding ? opts.padding : config.padding;
|
|
|
+ config.yAxisWidth = config.yAxisWidth * opts.pix;
|
|
|
+ config.fontSize = opts.fontSize * opts.pix;
|
|
|
+ config.titleFontSize = config.titleFontSize * opts.pix;
|
|
|
+ config.subtitleFontSize = config.subtitleFontSize * opts.pix;
|
|
|
+ if (!opts.context) {
|
|
|
+ throw new Error('[uCharts] 未获取到context!注意:v2.0版本后,需要自行获取canvas的绘图上下文并传入opts.context!');
|
|
|
+ }
|
|
|
+ this.context = opts.context;
|
|
|
+ if (!this.context.setTextAlign) {
|
|
|
+ this.context.setStrokeStyle = function(e: string) {
|
|
|
+ return this.strokeStyle = e;
|
|
|
+ }
|
|
|
+ this.context.setLineWidth = function(e: number) {
|
|
|
+ return this.lineWidth = e;
|
|
|
+ }
|
|
|
+ this.context.setLineCap = function(e: string) {
|
|
|
+ return this.lineCap = e;
|
|
|
+ }
|
|
|
+ this.context.setFontSize = function(e: number) {
|
|
|
+ return this.font = e + "px sans-serif";
|
|
|
+ }
|
|
|
+ this.context.setFillStyle = function(e: string) {
|
|
|
+ return this.fillStyle = e;
|
|
|
+ }
|
|
|
+ this.context.setTextAlign = function(e: string) {
|
|
|
+ return this.textAlign = e;
|
|
|
+ }
|
|
|
+ this.context.setTextBaseline = function(e: string) {
|
|
|
+ return this.textBaseline = e;
|
|
|
+ }
|
|
|
+ this.context.setShadow = function(offsetX: number, offsetY: number, blur: number, color: string) {
|
|
|
+ this.shadowColor = color;
|
|
|
+ this.shadowOffsetX = offsetX;
|
|
|
+ this.shadowOffsetY = offsetY;
|
|
|
+ this.shadowBlur = blur;
|
|
|
+ }
|
|
|
+ this.context.draw = function() {}
|
|
|
+ }
|
|
|
+ // 兼容NVUEsetLineDash
|
|
|
+ if (!this.context.setLineDash) {
|
|
|
+ this.context.setLineDash = function(e: number[]) {}
|
|
|
+ }
|
|
|
+ opts.chartData = {};
|
|
|
+ this.uevent = new uChartsEvent();
|
|
|
+ this.scrollOption = {
|
|
|
+ currentOffset: 0,
|
|
|
+ startTouchX: 0,
|
|
|
+ distance: 0,
|
|
|
+ lastMoveTime: 0
|
|
|
+ };
|
|
|
+ this.opts = opts;
|
|
|
+ this.config = config;
|
|
|
+ drawCharts.call(this, opts.type, opts, config, this.context);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 更新图表数据
|
|
|
+ * @param data - 新的数据
|
|
|
+ */
|
|
|
+ updateData(data: any = {}): void {
|
|
|
+ this.opts = assign({}, this.opts, data);
|
|
|
+ this.opts.updateData = true;
|
|
|
+ let scrollPosition = data.scrollPosition || 'current';
|
|
|
+ switch (scrollPosition) {
|
|
|
+ case 'current':
|
|
|
+ this.opts._scrollDistance_ = this.scrollOption.currentOffset;
|
|
|
+ break;
|
|
|
+ case 'left':
|
|
|
+ this.opts._scrollDistance_ = 0;
|
|
|
+ this.scrollOption = {
|
|
|
+ currentOffset: 0,
|
|
|
+ startTouchX: 0,
|
|
|
+ distance: 0,
|
|
|
+ lastMoveTime: 0
|
|
|
+ };
|
|
|
+ break;
|
|
|
+ case 'right':
|
|
|
+ let _calYAxisData = calYAxisData(this.opts.series, this.opts, this.config, this.context);
|
|
|
+ let yAxisWidth = _calYAxisData.yAxisWidth;
|
|
|
+ this.config.yAxisWidth = yAxisWidth;
|
|
|
+ let offsetLeft = 0;
|
|
|
+ let _getXAxisPoints0 = getXAxisPoints(this.opts.categories, this.opts, this.config);
|
|
|
+ let xAxisPoints = _getXAxisPoints0.xAxisPoints;
|
|
|
+ let startX = _getXAxisPoints0.startX;
|
|
|
+ let endX = _getXAxisPoints0.endX;
|
|
|
+ let eachSpacing = _getXAxisPoints0.eachSpacing;
|
|
|
+ let totalWidth = eachSpacing * (xAxisPoints.length - 1);
|
|
|
+ let screenWidth = endX - startX;
|
|
|
+ offsetLeft = screenWidth - totalWidth;
|
|
|
+ this.scrollOption = {
|
|
|
+ currentOffset: offsetLeft,
|
|
|
+ startTouchX: offsetLeft,
|
|
|
+ distance: 0,
|
|
|
+ lastMoveTime: 0
|
|
|
+ };
|
|
|
+ this.opts._scrollDistance_ = offsetLeft;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ drawCharts.call(this, this.opts.type, this.opts, this.config, this.context);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 缩放图表
|
|
|
+ * @param val - 缩放配置
|
|
|
+ */
|
|
|
+ zoom(val: any = this.opts.xAxis.itemCount): void {
|
|
|
+ if (this.opts.enableScroll !== true) {
|
|
|
+ console.log('[uCharts] 请启用滚动条后使用')
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 当前屏幕中间点
|
|
|
+ let centerPoint = Math.round(Math.abs(this.scrollOption.currentOffset) / this.opts.chartData.eachSpacing) + Math.round(this.opts.xAxis.itemCount / 2);
|
|
|
+ this.opts.animation = false;
|
|
|
+ this.opts.xAxis.itemCount = val.itemCount;
|
|
|
+ // 重新计算x轴偏移距离
|
|
|
+ let _calYAxisData = calYAxisData(this.opts.series, this.opts, this.config, this.context);
|
|
|
+ let yAxisWidth = _calYAxisData.yAxisWidth;
|
|
|
+ this.config.yAxisWidth = yAxisWidth;
|
|
|
+ let offsetLeft = 0;
|
|
|
+ let _getXAxisPoints0 = getXAxisPoints(this.opts.categories, this.opts, this.config);
|
|
|
+ let xAxisPoints = _getXAxisPoints0.xAxisPoints;
|
|
|
+ let startX = _getXAxisPoints0.startX;
|
|
|
+ let endX = _getXAxisPoints0.endX;
|
|
|
+ let eachSpacing = _getXAxisPoints0.eachSpacing;
|
|
|
+ let centerLeft = eachSpacing * centerPoint;
|
|
|
+ let screenWidth = endX - startX;
|
|
|
+ let MaxLeft = screenWidth - eachSpacing * (xAxisPoints.length - 1);
|
|
|
+ offsetLeft = screenWidth / 2 - centerLeft;
|
|
|
+ if (offsetLeft > 0) {
|
|
|
+ offsetLeft = 0;
|
|
|
+ }
|
|
|
+ if (offsetLeft < MaxLeft) {
|
|
|
+ offsetLeft = MaxLeft;
|
|
|
+ }
|
|
|
+ this.scrollOption = {
|
|
|
+ currentOffset: offsetLeft,
|
|
|
+ startTouchX: 0,
|
|
|
+ distance: 0,
|
|
|
+ lastMoveTime: 0
|
|
|
+ };
|
|
|
+ calValidDistance(this, offsetLeft, this.opts.chartData, this.config, this.opts);
|
|
|
+ this.opts._scrollDistance_ = offsetLeft;
|
|
|
+ drawCharts.call(this, this.opts.type, this.opts, this.config, this.context);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 双指缩放
|
|
|
+ * @param e - 触摸事件
|
|
|
+ */
|
|
|
+ dobuleZoom(e: TouchEvent): void {
|
|
|
+ if (this.opts.enableScroll !== true) {
|
|
|
+ console.log('[uCharts] 请启用滚动条后使用')
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const tcs = e.changedTouches;
|
|
|
+ if (tcs.length < 2) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ for (let i = 0; i < tcs.length; i++) {
|
|
|
+ tcs[i].x = tcs[i].x ? tcs[i].x : tcs[i].clientX;
|
|
|
+ tcs[i].y = tcs[i].y ? tcs[i].y : tcs[i].clientY;
|
|
|
+ }
|
|
|
+ const ntcs = [getTouches(tcs[0], this.opts, e), getTouches(tcs[1], this.opts, e)];
|
|
|
+ const xlength = Math.abs(ntcs[0].x - ntcs[1].x);
|
|
|
+ // 记录初始的两指之间的数据
|
|
|
+ if (!this.scrollOption.moveCount) {
|
|
|
+ let cts0 = { changedTouches: [{ x: tcs[0].x, y: this.opts.area[0] / this.opts.pix + 2 }] };
|
|
|
+ let cts1 = { changedTouches: [{ x: tcs[1].x, y: this.opts.area[0] / this.opts.pix + 2 }] };
|
|
|
+ if (this.opts.rotate) {
|
|
|
+ cts0 = { changedTouches: [{ x: this.opts.height / this.opts.pix - this.opts.area[0] / this.opts.pix - 2, y: tcs[0].y }] };
|
|
|
+ cts1 = { changedTouches: [{ x: this.opts.height / this.opts.pix - this.opts.area[0] / this.opts.pix - 2, y: tcs[1].y }] };
|
|
|
+ }
|
|
|
+ const moveCurrent1 = this.getCurrentDataIndex(cts0).index;
|
|
|
+ const moveCurrent2 = this.getCurrentDataIndex(cts1).index;
|
|
|
+ const moveCount = Math.abs(moveCurrent1 - moveCurrent2);
|
|
|
+ this.scrollOption.moveCount = moveCount;
|
|
|
+ this.scrollOption.moveCurrent1 = Math.min(moveCurrent1, moveCurrent2);
|
|
|
+ this.scrollOption.moveCurrent2 = Math.max(moveCurrent1, moveCurrent2);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ let currentEachSpacing = xlength / this.scrollOption.moveCount;
|
|
|
+ let itemCount = (this.opts.width - this.opts.area[1] - this.opts.area[3]) / currentEachSpacing;
|
|
|
+ itemCount = itemCount <= 2 ? 2 : itemCount;
|
|
|
+ itemCount = itemCount >= this.opts.categories.length ? this.opts.categories.length : itemCount;
|
|
|
+ this.opts.animation = false;
|
|
|
+ this.opts.xAxis.itemCount = itemCount;
|
|
|
+ // 重新计算滚动条偏移距离
|
|
|
+ let offsetLeft = 0;
|
|
|
+ let _getXAxisPoints0 = getXAxisPoints(this.opts.categories, this.opts, this.config);
|
|
|
+ let xAxisPoints = _getXAxisPoints0.xAxisPoints;
|
|
|
+ let startX = _getXAxisPoints0.startX;
|
|
|
+ let endX = _getXAxisPoints0.endX;
|
|
|
+ let eachSpacing = _getXAxisPoints0.eachSpacing;
|
|
|
+ let currentLeft = eachSpacing * this.scrollOption.moveCurrent1;
|
|
|
+ let screenWidth = endX - startX;
|
|
|
+ let MaxLeft = screenWidth - eachSpacing * (xAxisPoints.length - 1);
|
|
|
+ offsetLeft = -currentLeft + Math.min(ntcs[0].x, ntcs[1].x) - this.opts.area[3] - eachSpacing;
|
|
|
+ if (offsetLeft > 0) {
|
|
|
+ offsetLeft = 0;
|
|
|
+ }
|
|
|
+ if (offsetLeft < MaxLeft) {
|
|
|
+ offsetLeft = MaxLeft;
|
|
|
+ }
|
|
|
+ this.scrollOption.currentOffset = offsetLeft;
|
|
|
+ this.scrollOption.startTouchX = 0;
|
|
|
+ this.scrollOption.distance = 0;
|
|
|
+ calValidDistance(this, offsetLeft, this.opts.chartData, this.config, this.opts);
|
|
|
+ this.opts._scrollDistance_ = offsetLeft;
|
|
|
+ drawCharts.call(this, this.opts.type, this.opts, this.config, this.context);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 停止动画
|
|
|
+ */
|
|
|
+ stopAnimation(): void {
|
|
|
+ this.animationInstance && this.animationInstance.stop();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取当前数据索引
|
|
|
+ * @param e - 触摸事件
|
|
|
+ * @returns 当前数据索引
|
|
|
+ */
|
|
|
+ getCurrentDataIndex(e: TouchEvent): any {
|
|
|
+ let touches = null;
|
|
|
+ if (e.changedTouches) {
|
|
|
+ touches = e.changedTouches[0];
|
|
|
+ } else {
|
|
|
+ touches = e.mp.changedTouches[0];
|
|
|
+ }
|
|
|
+ if (touches) {
|
|
|
+ let _touches$ = getTouches(touches, this.opts, e);
|
|
|
+ if (this.opts.type === 'pie' || this.opts.type === 'ring') {
|
|
|
+ return findPieChartCurrentIndex({
|
|
|
+ x: _touches$.x,
|
|
|
+ y: _touches$.y
|
|
|
+ }, this.opts.chartData.pieData, this.opts);
|
|
|
+ } else if (this.opts.type === 'rose') {
|
|
|
+ return findRoseChartCurrentIndex({
|
|
|
+ x: _touches$.x,
|
|
|
+ y: _touches$.y
|
|
|
+ }, this.opts.chartData.pieData, this.opts);
|
|
|
+ } else if (this.opts.type === 'radar') {
|
|
|
+ return findRadarChartCurrentIndex({
|
|
|
+ x: _touches$.x,
|
|
|
+ y: _touches$.y
|
|
|
+ }, this.opts.chartData.radarData, this.opts.categories.length);
|
|
|
+ } else if (this.opts.type === 'funnel') {
|
|
|
+ return findFunnelChartCurrentIndex({
|
|
|
+ x: _touches$.x,
|
|
|
+ y: _touches$.y
|
|
|
+ }, this.opts.chartData.funnelData);
|
|
|
+ } else if (this.opts.type === 'map') {
|
|
|
+ return findMapChartCurrentIndex({
|
|
|
+ x: _touches$.x,
|
|
|
+ y: _touches$.y
|
|
|
+ }, this.opts);
|
|
|
+ } else if (this.opts.type === 'word') {
|
|
|
+ return findWordChartCurrentIndex({
|
|
|
+ x: _touches$.x,
|
|
|
+ y: _touches$.y
|
|
|
+ }, this.opts.chartData.wordCloudData);
|
|
|
+ } else if (this.opts.type === 'bar') {
|
|
|
+ return findBarChartCurrentIndex({
|
|
|
+ x: _touches$.x,
|
|
|
+ y: _touches$.y
|
|
|
+ }, this.opts.chartData.calPoints, this.opts, this.config, Math.abs(this.scrollOption.currentOffset));
|
|
|
+ } else {
|
|
|
+ return findCurrentIndex({
|
|
|
+ x: _touches$.x,
|
|
|
+ y: _touches$.y
|
|
|
+ }, this.opts.chartData.calPoints, this.opts, this.config, Math.abs(this.scrollOption.currentOffset));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取图例数据索引
|
|
|
+ * @param e - 触摸事件
|
|
|
+ * @returns 图例索引
|
|
|
+ */
|
|
|
+ getLegendDataIndex(e: TouchEvent): number {
|
|
|
+ let touches = null;
|
|
|
+ if (e.changedTouches) {
|
|
|
+ touches = e.changedTouches[0];
|
|
|
+ } else {
|
|
|
+ touches = e.mp.changedTouches[0];
|
|
|
+ }
|
|
|
+ if (touches) {
|
|
|
+ let _touches$ = getTouches(touches, this.opts, e);
|
|
|
+ return findLegendIndex({
|
|
|
+ x: _touches$.x,
|
|
|
+ y: _touches$.y
|
|
|
+ }, this.opts.chartData.legendData);
|
|
|
+ }
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 触摸图例事件
|
|
|
+ * @param e - 触摸事件
|
|
|
+ * @param option - 选项
|
|
|
+ */
|
|
|
+ touchLegend(e: TouchEvent, option: any = {}): void {
|
|
|
+ let touches = null;
|
|
|
+ if (e.changedTouches) {
|
|
|
+ touches = e.changedTouches[0];
|
|
|
+ } else {
|
|
|
+ touches = e.mp.changedTouches[0];
|
|
|
+ }
|
|
|
+ if (touches) {
|
|
|
+ let _touches$ = getTouches(touches, this.opts, e);
|
|
|
+ let index = this.getLegendDataIndex(e);
|
|
|
+ if (index >= 0) {
|
|
|
+ if (this.opts.type == 'candle') {
|
|
|
+ this.opts.seriesMA[index].show = !this.opts.seriesMA[index].show;
|
|
|
+ } else {
|
|
|
+ this.opts.series[index].show = !this.opts.series[index].show;
|
|
|
+ }
|
|
|
+ this.opts.animation = option.animation ? true : false;
|
|
|
+ this.opts._scrollDistance_ = this.scrollOption.currentOffset;
|
|
|
+ drawCharts.call(this, this.opts.type, this.opts, this.config, this.context);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 显示提示框
|
|
|
+ * @param e - 触摸事件
|
|
|
+ * @param option - 提示框选项
|
|
|
+ */
|
|
|
+ showToolTip(e: TouchEvent, option: ToolTipOption = {}): void {
|
|
|
+ let touches = null;
|
|
|
+ if (e.changedTouches) {
|
|
|
+ touches = e.changedTouches[0];
|
|
|
+ } else {
|
|
|
+ touches = e.mp.changedTouches[0];
|
|
|
+ }
|
|
|
+ if (!touches) {
|
|
|
+ console.log("[uCharts] 未获取到event坐标信息");
|
|
|
+ }
|
|
|
+ let _touches$ = getTouches(touches, this.opts, e);
|
|
|
+ let currentOffset = this.scrollOption.currentOffset;
|
|
|
+ let opts = assign({}, this.opts, {
|
|
|
+ _scrollDistance_: currentOffset,
|
|
|
+ animation: false
|
|
|
+ });
|
|
|
+ if (this.opts.type === 'line' || this.opts.type === 'area' || this.opts.type === 'column' || this.opts.type === 'scatter' || this.opts.type === 'bubble') {
|
|
|
+ let current = this.getCurrentDataIndex(e);
|
|
|
+ let index = option.index == undefined ? current.index : option.index;
|
|
|
+ if (index > -1 || index.length > 0) {
|
|
|
+ let seriesData = getSeriesDataItem(this.opts.series, index, current.group);
|
|
|
+ if (seriesData.length !== 0) {
|
|
|
+ let _getToolTipData = getToolTipData(seriesData, this.opts, index, current.group, this.opts.categories, option);
|
|
|
+ let textList = _getToolTipData.textList;
|
|
|
+ let offset = _getToolTipData.offset;
|
|
|
+ offset.y = _touches$.y;
|
|
|
+ opts.tooltip = {
|
|
|
+ textList: option.textList !== undefined ? option.textList : textList,
|
|
|
+ offset: option.offset !== undefined ? option.offset : offset,
|
|
|
+ option: option,
|
|
|
+ index: index,
|
|
|
+ group: current.group
|
|
|
+ };
|
|
|
+ }
|
|
|
+ }
|
|
|
+ drawCharts.call(this, opts.type, opts, this.config, this.context);
|
|
|
+ }
|
|
|
+ if (this.opts.type === 'mount') {
|
|
|
+ let index = option.index == undefined ? this.getCurrentDataIndex(e).index : option.index;
|
|
|
+ if (index > -1) {
|
|
|
+ let opts = assign({}, this.opts, { animation: false });
|
|
|
+ let seriesData = assign({}, opts._series_[index]);
|
|
|
+ let textList = [{
|
|
|
+ text: option.formatter ? option.formatter(seriesData, undefined, index, opts) : seriesData.name + ': ' + seriesData.data,
|
|
|
+ color: seriesData.color,
|
|
|
+ legendShape: this.opts.extra.tooltip.legendShape == 'auto' ? seriesData.legendShape : this.opts.extra.tooltip.legendShape
|
|
|
+ }];
|
|
|
+ let offset = {
|
|
|
+ x: opts.chartData.calPoints[index].x,
|
|
|
+ y: _touches$.y
|
|
|
+ };
|
|
|
+ opts.tooltip = {
|
|
|
+ textList: option.textList ? option.textList : textList,
|
|
|
+ offset: option.offset !== undefined ? option.offset : offset,
|
|
|
+ option: option,
|
|
|
+ index: index
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ drawCharts.call(this, opts.type, opts, this.config, this.context);
|
|
|
+ }
|
|
|
+ if (this.opts.type === 'bar') {
|
|
|
+ let current = this.getCurrentDataIndex(e);
|
|
|
+ let index = option.index == undefined ? current.index : option.index;
|
|
|
+ if (index > -1 || index.length > 0) {
|
|
|
+ let seriesData = getSeriesDataItem(this.opts.series, index, current.group);
|
|
|
+ if (seriesData.length !== 0) {
|
|
|
+ let _getToolTipData = getToolTipData(seriesData, this.opts, index, current.group, this.opts.categories, option);
|
|
|
+ let textList = _getToolTipData.textList;
|
|
|
+ let offset = _getToolTipData.offset;
|
|
|
+ offset.x = _touches$.x;
|
|
|
+ opts.tooltip = {
|
|
|
+ textList: option.textList !== undefined ? option.textList : textList,
|
|
|
+ offset: option.offset !== undefined ? option.offset : offset,
|
|
|
+ option: option,
|
|
|
+ index: index
|
|
|
+ };
|
|
|
+ }
|
|
|
+ }
|
|
|
+ drawCharts.call(this, opts.type, opts, this.config, this.context);
|
|
|
+ }
|
|
|
+ if (this.opts.type === 'mix') {
|
|
|
+ let current = this.getCurrentDataIndex(e);
|
|
|
+ let index = option.index == undefined ? current.index : option.index;
|
|
|
+ if (index > -1) {
|
|
|
+ let currentOffset = this.scrollOption.currentOffset;
|
|
|
+ let opts = assign({}, this.opts, {
|
|
|
+ _scrollDistance_: currentOffset,
|
|
|
+ animation: false
|
|
|
+ });
|
|
|
+ let seriesData = getSeriesDataItem(this.opts.series, index);
|
|
|
+ if (seriesData.length !== 0) {
|
|
|
+ let _getMixToolTipData = getMixToolTipData(seriesData, this.opts, index, this.opts.categories, option);
|
|
|
+ let textList = _getMixToolTipData.textList;
|
|
|
+ let offset = _getMixToolTipData.offset;
|
|
|
+ offset.y = _touches$.y;
|
|
|
+ opts.tooltip = {
|
|
|
+ textList: option.textList ? option.textList : textList,
|
|
|
+ offset: option.offset !== undefined ? option.offset : offset,
|
|
|
+ option: option,
|
|
|
+ index: index
|
|
|
+ };
|
|
|
+ }
|
|
|
+ }
|
|
|
+ drawCharts.call(this, opts.type, opts, this.config, this.context);
|
|
|
+ }
|
|
|
+ if (this.opts.type === 'candle') {
|
|
|
+ let current = this.getCurrentDataIndex(e);
|
|
|
+ let index = option.index == undefined ? current.index : option.index;
|
|
|
+ if (index > -1) {
|
|
|
+ let currentOffset = this.scrollOption.currentOffset;
|
|
|
+ let opts = assign({}, this.opts, {
|
|
|
+ _scrollDistance_: currentOffset,
|
|
|
+ animation: false
|
|
|
+ });
|
|
|
+ let seriesData = getSeriesDataItem(this.opts.series, index);
|
|
|
+ if (seriesData.length !== 0) {
|
|
|
+ let _getToolTipData = getCandleToolTipData(this.opts.series[0].data, seriesData, this.opts, index, this.opts.categories, this.opts.extra.candle, option);
|
|
|
+ let textList = _getToolTipData.textList;
|
|
|
+ let offset = _getToolTipData.offset;
|
|
|
+ offset.y = _touches$.y;
|
|
|
+ opts.tooltip = {
|
|
|
+ textList: option.textList ? option.textList : textList,
|
|
|
+ offset: option.offset !== undefined ? option.offset : offset,
|
|
|
+ option: option,
|
|
|
+ index: index
|
|
|
+ };
|
|
|
+ }
|
|
|
+ }
|
|
|
+ drawCharts.call(this, opts.type, opts, this.config, this.context);
|
|
|
+ }
|
|
|
+ if (this.opts.type === 'pie' || this.opts.type === 'ring' || this.opts.type === 'rose' || this.opts.type === 'funnel') {
|
|
|
+ let index = option.index == undefined ? this.getCurrentDataIndex(e) : option.index;
|
|
|
+ if (index > -1) {
|
|
|
+ let opts = assign({}, this.opts, { animation: false });
|
|
|
+ let seriesData = assign({}, opts._series_[index]);
|
|
|
+ let textList = [{
|
|
|
+ text: option.formatter ? option.formatter(seriesData, undefined, index, opts) : seriesData.name + ': ' + seriesData.data,
|
|
|
+ color: seriesData.color,
|
|
|
+ legendShape: this.opts.extra.tooltip.legendShape == 'auto' ? seriesData.legendShape : this.opts.extra.tooltip.legendShape
|
|
|
+ }];
|
|
|
+ let offset = {
|
|
|
+ x: _touches$.x,
|
|
|
+ y: _touches$.y
|
|
|
+ };
|
|
|
+ opts.tooltip = {
|
|
|
+ textList: option.textList ? option.textList : textList,
|
|
|
+ offset: option.offset !== undefined ? option.offset : offset,
|
|
|
+ option: option,
|
|
|
+ index: index
|
|
|
+ };
|
|
|
+ }
|
|
|
+ drawCharts.call(this, opts.type, opts, this.config, this.context);
|
|
|
+ }
|
|
|
+ if (this.opts.type === 'map') {
|
|
|
+ let index = option.index == undefined ? this.getCurrentDataIndex(e) : option.index;
|
|
|
+ if (index > -1) {
|
|
|
+ let opts = assign({}, this.opts, { animation: false });
|
|
|
+ let seriesData = assign({}, this.opts.series[index]);
|
|
|
+ seriesData.name = seriesData.properties.name
|
|
|
+ let textList = [{
|
|
|
+ text: option.formatter ? option.formatter(seriesData, undefined, index, this.opts) : seriesData.name,
|
|
|
+ color: seriesData.color,
|
|
|
+ legendShape: this.opts.extra.tooltip.legendShape == 'auto' ? seriesData.legendShape : this.opts.extra.tooltip.legendShape
|
|
|
+ }];
|
|
|
+ let offset = {
|
|
|
+ x: _touches$.x,
|
|
|
+ y: _touches$.y
|
|
|
+ };
|
|
|
+ opts.tooltip = {
|
|
|
+ textList: option.textList ? option.textList : textList,
|
|
|
+ offset: option.offset !== undefined ? option.offset : offset,
|
|
|
+ option: option,
|
|
|
+ index: index
|
|
|
+ };
|
|
|
+ }
|
|
|
+ opts.updateData = false;
|
|
|
+ drawCharts.call(this, opts.type, opts, this.config, this.context);
|
|
|
+ }
|
|
|
+ if (this.opts.type === 'word') {
|
|
|
+ let index = option.index == undefined ? this.getCurrentDataIndex(e) : option.index;
|
|
|
+ if (index > -1) {
|
|
|
+ let opts = assign({}, this.opts, { animation: false });
|
|
|
+ let seriesData = assign({}, this.opts.series[index]);
|
|
|
+ let textList = [{
|
|
|
+ text: option.formatter ? option.formatter(seriesData, undefined, index, this.opts) : seriesData.name,
|
|
|
+ color: seriesData.color,
|
|
|
+ legendShape: this.opts.extra.tooltip.legendShape == 'auto' ? seriesData.legendShape : this.opts.extra.tooltip.legendShape
|
|
|
+ }];
|
|
|
+ let offset = {
|
|
|
+ x: _touches$.x,
|
|
|
+ y: _touches$.y
|
|
|
+ };
|
|
|
+ opts.tooltip = {
|
|
|
+ textList: option.textList ? option.textList : textList,
|
|
|
+ offset: option.offset !== undefined ? option.offset : offset,
|
|
|
+ option: option,
|
|
|
+ index: index
|
|
|
+ };
|
|
|
+ }
|
|
|
+ opts.updateData = false;
|
|
|
+ drawCharts.call(this, opts.type, opts, this.config, this.context);
|
|
|
+ }
|
|
|
+ if (this.opts.type === 'radar') {
|
|
|
+ let index = option.index == undefined ? this.getCurrentDataIndex(e) : option.index;
|
|
|
+ if (index > -1) {
|
|
|
+ let opts = assign({}, this.opts, { animation: false });
|
|
|
+ let seriesData = getSeriesDataItem(this.opts.series, index);
|
|
|
+ if (seriesData.length !== 0) {
|
|
|
+ let textList = seriesData.map((item) => {
|
|
|
+ return {
|
|
|
+ text: option.formatter ? option.formatter(item, this.opts.categories[index], index, this.opts) : item.name + ': ' + item.data,
|
|
|
+ color: item.color,
|
|
|
+ legendShape: this.opts.extra.tooltip.legendShape == 'auto' ? item.legendShape : this.opts.extra.tooltip.legendShape
|
|
|
+ };
|
|
|
+ });
|
|
|
+ let offset = {
|
|
|
+ x: _touches$.x,
|
|
|
+ y: _touches$.y
|
|
|
+ };
|
|
|
+ opts.tooltip = {
|
|
|
+ textList: option.textList ? option.textList : textList,
|
|
|
+ offset: option.offset !== undefined ? option.offset : offset,
|
|
|
+ option: option,
|
|
|
+ index: index
|
|
|
+ };
|
|
|
+ }
|
|
|
+ }
|
|
|
+ drawCharts.call(this, opts.type, opts, this.config, this.context);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 平移图表
|
|
|
+ * @param distance - 平移距离
|
|
|
+ */
|
|
|
+ translate(distance: number): void {
|
|
|
+ this.scrollOption = {
|
|
|
+ currentOffset: distance,
|
|
|
+ startTouchX: distance,
|
|
|
+ distance: 0,
|
|
|
+ lastMoveTime: 0
|
|
|
+ };
|
|
|
+ let opts = assign({}, this.opts, {
|
|
|
+ _scrollDistance_: distance,
|
|
|
+ animation: false
|
|
|
+ });
|
|
|
+ drawCharts.call(this, this.opts.type, opts, this.config, this.context);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 滚动开始事件
|
|
|
+ * @param e - 触摸事件
|
|
|
+ */
|
|
|
+ scrollStart(e: TouchEvent): void {
|
|
|
+ let touches = null;
|
|
|
+ if (e.changedTouches) {
|
|
|
+ touches = e.changedTouches[0];
|
|
|
+ } else {
|
|
|
+ touches = e.mp.changedTouches[0];
|
|
|
+ }
|
|
|
+ let _touches$ = getTouches(touches, this.opts, e);
|
|
|
+ if (touches && this.opts.enableScroll === true) {
|
|
|
+ this.scrollOption.startTouchX = _touches$.x;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 滚动事件
|
|
|
+ * @param e - 触摸事件
|
|
|
+ * @returns 当前偏移量
|
|
|
+ */
|
|
|
+ scroll(e: TouchEvent): number {
|
|
|
+ if (this.scrollOption.lastMoveTime === 0) {
|
|
|
+ this.scrollOption.lastMoveTime = Date.now();
|
|
|
+ }
|
|
|
+ let Limit = this.opts.touchMoveLimit || 60;
|
|
|
+ let currMoveTime = Date.now();
|
|
|
+ let duration = currMoveTime - this.scrollOption.lastMoveTime;
|
|
|
+ if (duration < Math.floor(1000 / Limit)) return 0;
|
|
|
+ if (this.scrollOption.startTouchX == 0) return 0;
|
|
|
+ this.scrollOption.lastMoveTime = currMoveTime;
|
|
|
+ let touches = null;
|
|
|
+ if (e.changedTouches) {
|
|
|
+ touches = e.changedTouches[0];
|
|
|
+ } else {
|
|
|
+ touches = e.mp.changedTouches[0];
|
|
|
+ }
|
|
|
+ if (touches && this.opts.enableScroll === true) {
|
|
|
+ let _touches$ = getTouches(touches, this.opts, e);
|
|
|
+ let _distance;
|
|
|
+ _distance = _touches$.x - this.scrollOption.startTouchX;
|
|
|
+ let currentOffset = this.scrollOption.currentOffset;
|
|
|
+ let validDistance = calValidDistance(this, currentOffset + _distance, this.opts.chartData, this.config, this.opts);
|
|
|
+ this.scrollOption.distance = _distance = validDistance - currentOffset;
|
|
|
+ let opts = assign({}, this.opts, {
|
|
|
+ _scrollDistance_: currentOffset + _distance,
|
|
|
+ animation: false
|
|
|
+ });
|
|
|
+ this.opts = opts;
|
|
|
+ drawCharts.call(this, opts.type, opts, this.config, this.context);
|
|
|
+ return currentOffset + _distance;
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 滚动结束事件
|
|
|
+ * @param e - 触摸事件
|
|
|
+ */
|
|
|
+ scrollEnd(e: TouchEvent): void {
|
|
|
+ if (this.opts.enableScroll === true) {
|
|
|
+ let _scrollOption = this.scrollOption;
|
|
|
+ let currentOffset = _scrollOption.currentOffset;
|
|
|
+ let distance = _scrollOption.distance;
|
|
|
+ this.scrollOption.currentOffset = currentOffset + distance;
|
|
|
+ this.scrollOption.distance = 0;
|
|
|
+ this.scrollOption.moveCount = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+export default uCharts;
|