| | |
| | | /* |
| | | * uCharts® |
| | | * 高性能跨平台图表库,支持H5、APP、小程序(微信/支付宝/百度/头条/QQ/360)、Vue、Taro等支持canvas的框架平台 |
| | | * Copyright (c) 2021 QIUN®秋云 https://www.ucharts.cn All rights reserved. |
| | | * uCharts (R) |
| | | * 高性能跨平台图表库,支持H5、APP、小程序(微信/支付宝/百度/头条/QQ/360/快手)、Vue、Taro等支持canvas的框架平台 |
| | | * Copyright (C) 2018-2022 QIUN (R) 秋云 https://www.ucharts.cn All rights reserved. |
| | | * Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) |
| | | * 复制使用请保留本段注释,感谢支持开源! |
| | | * |
| | | * uCharts®官方网站 |
| | | * uCharts (R) 官方网站 |
| | | * https://www.uCharts.cn |
| | | * |
| | | * 开源地址: |
| | |
| | | 'use strict'; |
| | | |
| | | var config = { |
| | | version: 'v2.3.7-20220122', |
| | | version: 'v2.4.4-20221102', |
| | | yAxisWidth: 15, |
| | | yAxisSplit: 5, |
| | | xAxisHeight: 22, |
| | | xAxisLineHeight: 22, |
| | | legendHeight: 15, |
| | | yAxisTitleWidth: 15, |
| | | xAxisTextPadding: 3, |
| | | padding: [10, 10, 10, 10], |
| | | pixelRatio: 1, |
| | | rotate: false, |
| | | columePadding: 3, |
| | | fontSize: 13, |
| | | fontColor: '#666666', |
| | | dataPointShape: ['circle', 'circle', 'circle', 'circle'], |
| | |
| | | linearColor: ['#0EE2F8', '#2BDCA8', '#FA7D8D', '#EB88E2', '#2AE3A0', '#0EE2F8', '#EB88E2', '#6773E3', '#F78A85'], |
| | | pieChartLinePadding: 15, |
| | | pieChartTextPadding: 5, |
| | | xAxisTextPadding: 3, |
| | | titleColor: '#333333', |
| | | titleFontSize: 20, |
| | | subtitleColor: '#999999', |
| | | subtitleFontSize: 15, |
| | | toolTipPadding: 3, |
| | | toolTipBackground: '#000000', |
| | | toolTipOpacity: 0.7, |
| | | toolTipLineHeight: 20, |
| | | radarLabelTextMargin: 13, |
| | | gaugeLabelTextMargin: 13 |
| | | }; |
| | | |
| | | var assign = function(target, ...varArgs) { |
| | |
| | | return e; |
| | | } |
| | | |
| | | // 经纬度转墨卡托 |
| | | function lonlat2mercator(longitude, latitude) { |
| | | var mercator = Array(2); |
| | | var x = longitude * 20037508.34 / 180; |
| | | var y = Math.log(Math.tan((90 + latitude) * Math.PI / 360)) / (Math.PI / 180); |
| | | y = y * 20037508.34 / 180; |
| | | mercator[0] = x; |
| | | mercator[1] = y; |
| | | return mercator; |
| | | } |
| | | |
| | | // 墨卡托转经纬度 |
| | | function mercator2lonlat(longitude, latitude) { |
| | | var lonlat = Array(2) |
| | | var x = longitude / 20037508.34 * 180; |
| | | var y = latitude / 20037508.34 * 180; |
| | | y = 180 / Math.PI * (2 * Math.atan(Math.exp(y * Math.PI / 180)) - Math.PI / 2); |
| | | lonlat[0] = x; |
| | | lonlat[1] = y; |
| | | return lonlat; |
| | | } |
| | | |
| | | // hex 转 rgba |
| | | function hexToRgb(hexValue, opc) { |
| | | var rgx = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; |
| | |
| | | } |
| | | while (num % limit !== 0) { |
| | | if (type === 'upper') { |
| | | if (num == num + 1) { //修复数据值过大num++无效的bug by 向日葵 @xrk_jy |
| | | break; |
| | | } |
| | | num++; |
| | | } else { |
| | | num--; |
| | |
| | | function calValidDistance(self, distance, chartData, config, opts) { |
| | | var dataChartAreaWidth = opts.width - opts.area[1] - opts.area[3]; |
| | | var dataChartWidth = chartData.eachSpacing * (opts.chartData.xAxisData.xAxisPoints.length - 1); |
| | | if(opts.type == 'mount' && opts.extra && opts.extra.mount && opts.extra.mount.widthRatio && opts.extra.mount.widthRatio > 1){ |
| | | if(opts.extra.mount.widthRatio>2) opts.extra.mount.widthRatio = 2 |
| | | dataChartWidth += (opts.extra.mount.widthRatio - 1)*chartData.eachSpacing; |
| | | } |
| | | var validDistance = distance; |
| | | if (distance >= 0) { |
| | | validDistance = 0; |
| | |
| | | } |
| | | } |
| | | return angle >= startAngle && angle <= endAngle; |
| | | } |
| | | |
| | | function calRotateTranslate(x, y, h) { |
| | | var xv = x; |
| | | var yv = h - y; |
| | | var transX = xv + (h - yv - xv) / Math.sqrt(2); |
| | | transX *= -1; |
| | | var transY = (h - yv) * (Math.sqrt(2) - 1) - (h - yv - xv) / Math.sqrt(2); |
| | | return { |
| | | transX: transX, |
| | | transY: transY |
| | | }; |
| | | } |
| | | |
| | | function createCurveControlPoints(points, i) { |
| | |
| | | }; |
| | | } |
| | | |
| | | |
| | | function convertCoordinateOrigin(x, y, center) { |
| | | return { |
| | | x: center.x + x, |
| | |
| | | item.legendShape = "line"; |
| | | break; |
| | | case 'column': |
| | | case 'bar': |
| | | item.legendShape = "rect"; |
| | | break; |
| | | case 'area': |
| | | case 'mount': |
| | | item.legendShape = "triangle"; |
| | | break; |
| | | case 'bar': |
| | | item.legendShape = "rect"; |
| | | break; |
| | | default: |
| | | item.legendShape = "circle"; |
| | |
| | | } |
| | | return newcolor; |
| | | } |
| | | |
| | | |
| | | function getDataRange(minData, maxData) { |
| | | var limit = 0; |
| | | var range = maxData - minData; |
| | |
| | | } |
| | | points = filterPoints[0][index[0]]; |
| | | }else{ |
| | | points = calPoints[0][index]; |
| | | for (let i = 0; i < calPoints.length; i++) { |
| | | if(calPoints[i][index]){ |
| | | points = calPoints[i][index]; |
| | | break; |
| | | } |
| | | } |
| | | }; |
| | | var textList = seriesData.map(function(item) { |
| | | let titleText = null; |
| | |
| | | return Math.pow(currentPoints.x - center.x, 2) + Math.pow(currentPoints.y - center.y, 2) <= Math.pow(radius, 2); |
| | | } |
| | | |
| | | |
| | | function splitPoints(points,eachSeries) { |
| | | var newPoints = []; |
| | | var items = []; |
| | |
| | | } |
| | | return newPoints; |
| | | } |
| | | |
| | | |
| | | function calLegendData(series, opts, config, chartData, context) { |
| | | let legendData = { |
| | |
| | | let currentRow = []; |
| | | for (let i = 0; i < series.length; i++) { |
| | | let item = series[i]; |
| | | let itemWidth = shapeWidth + shapeRight + measureText(item.name || 'undefined', fontSize, context) + opts.legend.itemGap * opts.pix; |
| | | const legendText = item.legendText ? item.legendText : item.name; |
| | | let itemWidth = shapeWidth + shapeRight + measureText(legendText || 'undefined', fontSize, context) + opts.legend.itemGap * opts.pix; |
| | | if (widthCount + itemWidth > opts.width - opts.area[1] - opts.area[3]) { |
| | | legendList.push(currentRow); |
| | | widthCountArr.push(widthCount - opts.legend.itemGap * opts.pix); |
| | |
| | | angle: 0, |
| | | xAxisHeight: config.xAxisHeight |
| | | }; |
| | | var categoriesTextLenth = categories.map(function(item) { |
| | | return measureText(item, opts.xAxis.fontSize * opts.pix || config.fontSize, context); |
| | | var fontSize = opts.xAxis.fontSize * opts.pix || config.fontSize; |
| | | var categoriesTextLenth = categories.map(function(item,index) { |
| | | var xitem = opts.xAxis.formatter ? opts.xAxis.formatter(item,index,opts) : item; |
| | | return measureText(String(xitem), fontSize, context); |
| | | }); |
| | | |
| | | var maxTextLength = Math.max.apply(this, categoriesTextLenth); |
| | | |
| | | if (opts.xAxis.rotateLabel == true && maxTextLength + 2 * config.xAxisTextPadding > eachSpacing) { |
| | | result.angle = 45 * Math.PI / 180; |
| | | result.xAxisHeight = 2 * config.xAxisTextPadding + maxTextLength * Math.sin(result.angle); |
| | | if (opts.xAxis.rotateLabel == true) { |
| | | result.angle = opts.xAxis.rotateAngle * Math.PI / 180; |
| | | let tempHeight = 2 * config.xAxisTextPadding + Math.abs(maxTextLength * Math.sin(result.angle)) |
| | | tempHeight = tempHeight < fontSize + 2 * config.xAxisTextPadding ? tempHeight + 2 * config.xAxisTextPadding : tempHeight; |
| | | if(opts.enableScroll == true && opts.xAxis.scrollShow == true){ |
| | | tempHeight += 12 * opts.pix; |
| | | } |
| | | result.xAxisHeight = tempHeight; |
| | | } |
| | | if (opts.xAxis.disabled){ |
| | | result.xAxisHeight = 0; |
| | | } |
| | | return result; |
| | | } |
| | |
| | | return series; |
| | | } |
| | | |
| | | function getFunnelDataPoints(series, radius, type, eachSpacing) { |
| | | function getFunnelDataPoints(series, radius, option, eachSpacing) { |
| | | var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1; |
| | | series = series.sort(function(a, b) { |
| | | return parseInt(b.data) - parseInt(a.data); |
| | | }); |
| | | for (let i = 0; i < series.length; i++) { |
| | | if(type == 'funnel'){ |
| | | if(option.type == 'funnel'){ |
| | | series[i].radius = series[i].data / series[0].data * radius * process; |
| | | }else{ |
| | | series[i].radius = (eachSpacing * (series.length - i)) / (eachSpacing * series.length) * radius * process; |
| | | } |
| | | series[i]._proportion_ = series[i].data / series[0].data; |
| | | } |
| | | if(type !== 'pyramid'){ |
| | | series.reverse(); |
| | | } |
| | | // if(option.type !== 'pyramid'){ |
| | | // series.reverse(); |
| | | // } |
| | | return series; |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | function getArcbarDataPoints(series, arcbarOption) { |
| | | var process = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1; |
| | | if (process == 1) { |
| | | process = 0.999999; |
| | | } |
| | | for (let i = 0; i < series.length; i++) { |
| | | let item = series[i]; |
| | | item.data = item.data === null ? 0 : item.data; |
| | | let totalAngle; |
| | | if (arcbarOption.type == 'circle') { |
| | | totalAngle = 2; |
| | | } else { |
| | | if(arcbarOption.direction == 'ccw'){ |
| | | if (arcbarOption.startAngle < arcbarOption.endAngle) { |
| | | totalAngle = 2 + arcbarOption.startAngle - arcbarOption.endAngle; |
| | | } else { |
| | | totalAngle = arcbarOption.startAngle - arcbarOption.endAngle; |
| | | } |
| | | }else{ |
| | | if (arcbarOption.endAngle < arcbarOption.startAngle) { |
| | | totalAngle = 2 + arcbarOption.endAngle - arcbarOption.startAngle; |
| | | } else { |
| | | totalAngle = arcbarOption.startAngle - arcbarOption.endAngle; |
| | | } |
| | | } |
| | | } |
| | | item._proportion_ = totalAngle * item.data * process + arcbarOption.startAngle; |
| | | if(arcbarOption.direction == 'ccw'){ |
| | | item._proportion_ = arcbarOption.startAngle - totalAngle * item.data * process ; |
| | | } |
| | | if (item._proportion_ >= 2) { |
| | | item._proportion_ = item._proportion_ % 2; |
| | | } |
| | | } |
| | | return series; |
| | | } |
| | | |
| | | function getGaugeArcbarDataPoints(series, arcbarOption) { |
| | | var process = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1; |
| | | if (process == 1) { |
| | | process = 0.999999; |
| | |
| | | if (item === null) { |
| | | return null; |
| | | } |
| | | item.width = Math.ceil(eachSpacing - 2 * categoryGap); |
| | | item.width = eachSpacing - 2 * categoryGap; |
| | | if (opts.extra.column && opts.extra.column.width && +opts.extra.column.width > 0) { |
| | | item.width = Math.min(item.width, +opts.extra.column.width * opts.pix); |
| | | } |
| | | if (index > 0) { |
| | | item.width -= 2 * border; |
| | | item.width -= border; |
| | | } |
| | | return item; |
| | | }); |
| | |
| | | if ((opts.type == 'line' || opts.type == 'area' || opts.type == 'scatter' || opts.type == 'bubble' || opts.type == 'bar') && dataCount > 1 && opts.xAxis.boundaryGap == 'justify') { |
| | | dataCount -= 1; |
| | | } |
| | | var widthRatio = 0; |
| | | if(opts.type == 'mount' && opts.extra && opts.extra.mount && opts.extra.mount.widthRatio && opts.extra.mount.widthRatio > 1){ |
| | | if(opts.extra.mount.widthRatio>2) opts.extra.mount.widthRatio = 2 |
| | | widthRatio = opts.extra.mount.widthRatio - 1; |
| | | dataCount += widthRatio; |
| | | } |
| | | var eachSpacing = spacingValid / dataCount; |
| | | var xAxisPoints = []; |
| | | var startX = opts.area[3]; |
| | | var endX = opts.width - opts.area[1]; |
| | | categories.forEach(function(item, index) { |
| | | xAxisPoints.push(startX + index * eachSpacing); |
| | | xAxisPoints.push(startX + widthRatio / 2 * eachSpacing + index * eachSpacing); |
| | | }); |
| | | if (opts.xAxis.boundaryGap !== 'justify') { |
| | | if (opts.enableScroll === true) { |
| | | xAxisPoints.push(startX + categories.length * eachSpacing); |
| | | xAxisPoints.push(startX + widthRatio * eachSpacing + categories.length * eachSpacing); |
| | | } else { |
| | | xAxisPoints.push(endX); |
| | | } |
| | |
| | | return points; |
| | | } |
| | | |
| | | function getMountDataPoints(series, minRange, maxRange, xAxisPoints, eachSpacing, opts, mountOption) { |
| | | var process = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : 1; |
| | | var points = []; |
| | | var validHeight = opts.height - opts.area[0] - opts.area[2]; |
| | | var validWidth = opts.width - opts.area[1] - opts.area[3]; |
| | | var mountWidth = eachSpacing * mountOption.widthRatio; |
| | | series.forEach(function(item, index) { |
| | | if (item === null) { |
| | | points.push(null); |
| | | } else { |
| | | var point = {}; |
| | | point.color = item.color; |
| | | point.x = xAxisPoints[index]; |
| | | point.x += eachSpacing / 2; |
| | | var value = item.data; |
| | | var height = validHeight * (value - minRange) / (maxRange - minRange); |
| | | height *= process; |
| | | point.y = opts.height - height - opts.area[2]; |
| | | point.value = value; |
| | | point.width = mountWidth; |
| | | points.push(point); |
| | | } |
| | | }); |
| | | return points; |
| | | } |
| | | |
| | | function getBarDataPoints(data, minRange, maxRange, yAxisPoints, eachSpacing, opts, config) { |
| | | var process = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : 1; |
| | | var points = []; |
| | |
| | | var height0 = validHeight * (value0 - minRange) / (maxRange - minRange); |
| | | } else { |
| | | var value = item; |
| | | if (typeof item === 'object' && item !== null) { |
| | | value = item.value; |
| | | } |
| | | var height = validHeight * (value - minRange) / (maxRange - minRange); |
| | | var height0 = 0; |
| | | } |
| | |
| | | var height0 = validHeight * (value0 - minRange) / (maxRange - minRange); |
| | | } else { |
| | | var value = item; |
| | | if (typeof item === 'object' && item !== null) { |
| | | value = item.value; |
| | | } |
| | | var height = validHeight * (value - minRange) / (maxRange - minRange); |
| | | var height0 = 0; |
| | | } |
| | |
| | | minData = Math.min.apply(this, sorted); |
| | | maxData = Math.max.apply(this, sorted); |
| | | } |
| | | //为了兼容v1.9.0之前的项目 |
| | | // if (index > -1) { |
| | | // if (typeof opts.yAxis.data[index].min === 'number') { |
| | | // minData = Math.min(opts.yAxis.data[index].min, minData); |
| | | // } |
| | | // if (typeof opts.yAxis.data[index].max === 'number') { |
| | | // maxData = Math.max(opts.yAxis.data[index].max, maxData); |
| | | // } |
| | | // } else { |
| | | // if (typeof opts.yAxis.min === 'number') { |
| | | // minData = Math.min(opts.yAxis.min, minData); |
| | | // } |
| | | // if (typeof opts.yAxis.max === 'number') { |
| | | // maxData = Math.max(opts.yAxis.max, maxData); |
| | | // } |
| | | // } |
| | | if (minData === maxData) { |
| | | var rangeSpan = maxData || 10; |
| | | maxData += rangeSpan; |
| | | if(maxData == 0){ |
| | | maxData = 10; |
| | | }else{ |
| | | minData = 0; |
| | | } |
| | | } |
| | | var dataRange = getDataRange(minData, maxData); |
| | | var minRange = yData.min === undefined || yData.min === null ? dataRange.minRange : yData.min; |
| | | var maxRange = yData.max === undefined || yData.min === null ? dataRange.maxRange : yData.max; |
| | | var range = []; |
| | | var minRange = (yData.min === undefined || yData.min === null) ? dataRange.minRange : yData.min; |
| | | var maxRange = (yData.max === undefined || yData.max === null) ? dataRange.maxRange : yData.max; |
| | | var eachRange = (maxRange - minRange) / opts.yAxis.splitNumber; |
| | | var range = []; |
| | | for (var i = 0; i <= opts.yAxis.splitNumber; i++) { |
| | | range.push(minRange + eachRange * i); |
| | | } |
| | |
| | | } |
| | | if(yData.type === 'categories'){ |
| | | if(!yData.formatter){ |
| | | yData.formatter = (val) => {return val + (yData.unit || '')}; |
| | | yData.formatter = (val,index,opts) => {return val + (yData.unit || '')}; |
| | | } |
| | | yData.categories = yData.categories || opts.categories; |
| | | rangesArr[i] = yData.categories; |
| | | }else{ |
| | | if(!yData.formatter){ |
| | | yData.formatter = (val) => {return val.toFixed(yData.tofix) + (yData.unit || '')}; |
| | | yData.formatter = (val,index,opts) => {return util.toFixed(val, yData.tofix || 0) + (yData.unit || '')}; |
| | | } |
| | | rangesArr[i] = getYAxisTextList(newSeries[i], opts, config, columnstyle.type, yData, i); |
| | | } |
| | |
| | | position: yData.position ? yData.position : 'left', |
| | | width: 0 |
| | | }; |
| | | rangesFormatArr[i] = rangesArr[i].map(function(items) { |
| | | items = yData.formatter(items); |
| | | rangesFormatArr[i] = rangesArr[i].map(function(items,index) { |
| | | items = yData.formatter(items,index,opts); |
| | | yAxisWidthArr[i].width = Math.max(yAxisWidthArr[i].width, measureText(items, yAxisFontSizes, context) + 5); |
| | | return items; |
| | | }); |
| | |
| | | var yAxisWidthArr = new Array(1); |
| | | if(opts.type === 'bar'){ |
| | | rangesArr[0] = opts.categories; |
| | | if(!opts.yAxis.formatter){ |
| | | opts.yAxis.formatter = (val) => {return val + (opts.yAxis.unit || '')} |
| | | } |
| | | }else{ |
| | | if(!opts.yAxis.formatter){ |
| | | opts.yAxis.formatter = (val) => {return val.toFixed(opts.yAxis.tofix ) + (opts.yAxis.unit || '')} |
| | | } |
| | | rangesArr[0] = getYAxisTextList(series, opts, config, columnstyle.type, {}); |
| | | } |
| | | yAxisWidthArr[0] = { |
| | | position: 'left', |
| | | width: 0 |
| | | }; |
| | | var yAxisFontSize = opts.yAxis.fontSize * opts.pix || config.fontSize; |
| | | rangesFormatArr[0] = rangesArr[0].map(function(item) { |
| | | item = opts.yAxis.formatter(item); |
| | | yAxisWidthArr[0].width = Math.max(yAxisWidthArr[0].width, measureText(item, yAxisFontSize, context) + 5); |
| | | return item; |
| | | }); |
| | | yAxisWidthArr[0].width += 3 * opts.pix; |
| | | |
| | | if (opts.yAxis.disabled === true) { |
| | | yAxisWidthArr[0] = { |
| | | position: 'left', |
| | |
| | | position: 'left', |
| | | max: opts.yAxis.max, |
| | | min: opts.yAxis.min, |
| | | formatter: opts.yAxis.formatter |
| | | formatter: (val,index,opts) => {return val} |
| | | }; |
| | | if(opts.type === 'bar'){ |
| | | opts.yAxis.data[0].categories = opts.categories; |
| | | opts.yAxis.data[0].type = 'categories'; |
| | | } |
| | | } |
| | | var yAxisFontSize = opts.yAxis.fontSize * opts.pix || config.fontSize; |
| | | rangesFormatArr[0] = rangesArr[0].map(function(item,index) { |
| | | item = opts.yAxis.data[0].formatter(item,index,opts); |
| | | yAxisWidthArr[0].width = Math.max(yAxisWidthArr[0].width, measureText(item, yAxisFontSize, context) + 5); |
| | | return item; |
| | | }); |
| | | yAxisWidthArr[0].width += 3 * opts.pix; |
| | | } |
| | | return { |
| | | rangesFormat: rangesFormatArr, |
| | |
| | | let minAxis = opts.area[0]; |
| | | let items = []; |
| | | for (let i = 0; i < ranges.length; i++) { |
| | | let maxVal = ranges[i].shift(); |
| | | let minVal = ranges[i].pop(); |
| | | let maxVal = Math.max.apply(this, ranges[i]); |
| | | let minVal = Math.min.apply(this, ranges[i]); |
| | | let item = maxVal - (maxVal - minVal) * (point - minAxis) / spacingValid; |
| | | item = opts.yAxis.data[i].formatter ? opts.yAxis.data[i].formatter(item) : item.toFixed(0); |
| | | item = opts.yAxis.data && opts.yAxis.data[i].formatter ? opts.yAxis.data[i].formatter(item, i, opts) : item.toFixed(0); |
| | | items.push(String(item)) |
| | | } |
| | | return items; |
| | |
| | | context.lineTo(item.x, item.y - 4.5); |
| | | } |
| | | }); |
| | | } else if (shape === 'triangle') { |
| | | } else if (shape === 'none') { |
| | | return; |
| | | } |
| | | context.closePath(); |
| | |
| | | value = data[index].value |
| | | } |
| | | } |
| | | var formatVal = series.formatter ? series.formatter(value,index) : value; |
| | | var formatVal = series.formatter ? series.formatter(value,index,series,opts) : value; |
| | | context.setTextAlign('center'); |
| | | context.fillText(String(formatVal), item.x, item.y - 4 + textOffset * opts.pix); |
| | | context.closePath(); |
| | | context.stroke(); |
| | | context.setTextAlign('left'); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | function drawMountPointText(points, series, config, context, opts) { |
| | | // 绘制数据文案 |
| | | var data = series.data; |
| | | var textOffset = series.textOffset ? series.textOffset : 0; |
| | | points.forEach(function(item, index) { |
| | | if (item !== null) { |
| | | context.beginPath(); |
| | | var fontSize = series[index].textSize ? series[index].textSize * opts.pix : config.fontSize; |
| | | context.setFontSize(fontSize); |
| | | context.setFillStyle(series[index].textColor || opts.fontColor); |
| | | var value = item.value |
| | | var formatVal = series[index].formatter ? series[index].formatter(value,index,series,opts) : value; |
| | | context.setTextAlign('center'); |
| | | context.fillText(String(formatVal), item.x, item.y - 4 + textOffset * opts.pix); |
| | | context.closePath(); |
| | |
| | | if (typeof data[index] === 'object' && data[index] !== null) { |
| | | value = data[index].value ; |
| | | } |
| | | var formatVal = series.formatter ? series.formatter(value,index) : value; |
| | | var formatVal = series.formatter ? series.formatter(value,index,series,opts) : value; |
| | | context.setTextAlign('left'); |
| | | context.fillText(String(formatVal), item.x + 4 * opts.pix , item.y + fontSize / 2 - 3 ); |
| | | context.closePath(); |
| | |
| | | |
| | | function drawGaugeLabel(gaugeOption, radius, centerPosition, opts, config, context) { |
| | | radius -= gaugeOption.width / 2 + gaugeOption.labelOffset * opts.pix; |
| | | radius = radius < 10 ? 10 : radius; |
| | | let totalAngle = gaugeOption.startAngle - gaugeOption.endAngle + 1; |
| | | let splitAngle = totalAngle / gaugeOption.splitLine.splitNumber; |
| | | let totalNumber = gaugeOption.endNumber - gaugeOption.startNumber; |
| | |
| | | x: radius * Math.cos(nowAngle * Math.PI), |
| | | y: radius * Math.sin(nowAngle * Math.PI) |
| | | }; |
| | | var labelText = gaugeOption.formatter ? gaugeOption.formatter(nowNumber) : nowNumber; |
| | | var labelText = gaugeOption.formatter ? gaugeOption.formatter(nowNumber,i,opts) : nowNumber; |
| | | pos.x += centerPosition.x - measureText(labelText, config.fontSize, context) / 2; |
| | | pos.y += centerPosition.y; |
| | | var startX = pos.x; |
| | |
| | | } |
| | | nowNumber += splitNumber; |
| | | } |
| | | |
| | | } |
| | | |
| | | function drawRadarLabel(angleList, radius, centerPosition, opts, config, context) { |
| | | var radarOption = opts.extra.radar || {}; |
| | | radius += config.radarLabelTextMargin * opts.pix; |
| | | angleList.forEach(function(angle, index) { |
| | | if(radarOption.labelPointShow === true && opts.categories[index] !== ''){ |
| | | var posPoint = { |
| | | x: radius * Math.cos(angle), |
| | | y: radius * Math.sin(angle) |
| | | }; |
| | | var posPointAxis = convertCoordinateOrigin(posPoint.x, posPoint.y, centerPosition); |
| | | context.setFillStyle(radarOption.labelPointColor); |
| | | context.beginPath(); |
| | | context.arc(posPointAxis.x, posPointAxis.y, radarOption.labelPointRadius * opts.pix, 0, 2 * Math.PI, false); |
| | | context.closePath(); |
| | | context.fill(); |
| | | } |
| | | var pos = { |
| | | x: radius * Math.cos(angle), |
| | | y: radius * Math.sin(angle) |
| | | x: (radius + config.radarLabelTextMargin * opts.pix) * Math.cos(angle), |
| | | y: (radius + config.radarLabelTextMargin * opts.pix) * Math.sin(angle) |
| | | }; |
| | | var posRelativeCanvas = convertCoordinateOrigin(pos.x, pos.y, centerPosition); |
| | | var startX = posRelativeCanvas.x; |
| | |
| | | var lineRadius = config.pieChartLinePadding; |
| | | var textObjectCollection = []; |
| | | var lastTextObject = null; |
| | | var seriesConvert = series.map(function(item,index,series) { |
| | | var text = item.formatter ? item.formatter(item,index,series) : util.toFixed(item._proportion_.toFixed(4) * 100) + '%'; |
| | | var seriesConvert = series.map(function(item,index) { |
| | | var text = item.formatter ? item.formatter(item,index,series,opts) : util.toFixed(item._proportion_.toFixed(4) * 100) + '%'; |
| | | text = item.labelText ? item.labelText : text; |
| | | var arc = 2 * Math.PI - (item._start_ + 2 * Math.PI * item._proportion_ / 2); |
| | | if (item._rose_proportion_) { |
| | | arc = 2 * Math.PI - (item._start_ + 2 * Math.PI * item._rose_proportion_ / 2); |
| | |
| | | radius: radius, |
| | | textColor: item.textColor, |
| | | textSize: item.textSize, |
| | | labelShow: item.labelShow |
| | | }; |
| | | }); |
| | | for (let i = 0; i < seriesConvert.length; i++) { |
| | |
| | | textObjectCollection.push(lastTextObject); |
| | | } |
| | | for (let i = 0; i < textObjectCollection.length; i++) { |
| | | if(seriesConvert[i].labelShow === false){ |
| | | continue; |
| | | } |
| | | let item = textObjectCollection[i]; |
| | | let lineStartPoistion = convertCoordinateOrigin(item.lineStart.x, item.lineStart.y, center); |
| | | let lineEndPoistion = convertCoordinateOrigin(item.lineEnd.x, item.lineEnd.y, center); |
| | |
| | | context.closePath(); |
| | | context.beginPath(); |
| | | context.moveTo(textPosition.x + item.width, textPosition.y); |
| | | context.arc(curveStartX, textPosition.y, 2, 0, 2 * Math.PI); |
| | | context.arc(curveStartX, textPosition.y, 2 * opts.pix, 0, 2 * Math.PI); |
| | | context.closePath(); |
| | | context.fill(); |
| | | context.beginPath(); |
| | |
| | | context.setFontSize(config.fontSize); |
| | | let textWidth = measureText(labelText, config.fontSize, context); |
| | | let textX = offsetX - 0.5 * textWidth; |
| | | let textY = endY; |
| | | let textY = endY + 2 * opts.pix; |
| | | context.beginPath(); |
| | | context.setFillStyle(hexToRgb(toolTipOption.labelBgColor || config.toolTipBackground, toolTipOption.labelBgOpacity || config.toolTipOpacity)); |
| | | context.setStrokeStyle(toolTipOption.labelBgColor || config.toolTipBackground); |
| | |
| | | labelFontColor: '#666666', |
| | | labelBgColor: '#DFE8FF', |
| | | labelBgOpacity: 0.8, |
| | | yAxisIndex: 0 |
| | | labelAlign: 'left', |
| | | labelOffsetX: 0, |
| | | labelOffsetY: 0, |
| | | }, points[i]); |
| | | if (markLineOption.type == 'dash') { |
| | | context.setLineDash([markLineOption.dashLength, markLineOption.dashLength]); |
| | |
| | | context.stroke(); |
| | | context.setLineDash([]); |
| | | if (item.showLabel) { |
| | | let labelText = opts.yAxis.formatter ? opts.yAxis.formatter(item.value) : item.value; |
| | | let labelText = item.labelText ? item.labelText : item.value; |
| | | context.setFontSize(config.fontSize); |
| | | let textWidth = measureText(labelText, config.fontSize, context); |
| | | let yAxisWidth = opts.chartData.yAxisData.yAxisWidth[0].width; |
| | | let bgStartX = opts.area[3] - textWidth - config.toolTipPadding * 2; |
| | | let bgEndX = opts.area[3]; |
| | | let bgWidth = bgEndX - bgStartX; |
| | | let textX = bgEndX - config.toolTipPadding; |
| | | let bgWidth = textWidth + config.toolTipPadding * 2; |
| | | let bgStartX = item.labelAlign == 'left' ? opts.area[3] - bgWidth : opts.width - opts.area[1]; |
| | | bgStartX += item.labelOffsetX; |
| | | let bgStartY = item.y - 0.5 * config.fontSize - config.toolTipPadding; |
| | | bgStartY += item.labelOffsetY; |
| | | let textX = bgStartX + config.toolTipPadding; |
| | | let textY = item.y; |
| | | context.setFillStyle(hexToRgb(item.labelBgColor, item.labelBgOpacity)); |
| | | context.setStrokeStyle(item.labelBgColor); |
| | | context.setLineWidth(1 * opts.pix); |
| | | context.beginPath(); |
| | | context.rect(bgStartX, textY - 0.5 * config.fontSize - config.toolTipPadding, bgWidth, config.fontSize + 2 * config.toolTipPadding); |
| | | context.rect(bgStartX, bgStartY, bgWidth, config.fontSize + 2 * config.toolTipPadding); |
| | | context.closePath(); |
| | | context.stroke(); |
| | | context.fill(); |
| | | context.setFontSize(config.fontSize); |
| | | context.setTextAlign('right'); |
| | | context.setTextAlign('left'); |
| | | context.setFillStyle(item.labelFontColor); |
| | | context.fillText(String(labelText), textX, textY + 0.5 * config.fontSize); |
| | | context.fillText(String(labelText), textX, bgStartY + config.fontSize + config.toolTipPadding/2); |
| | | context.stroke(); |
| | | context.setTextAlign('left'); |
| | | } |
| | |
| | | let textWidth = measureText(labelText[i], config.fontSize, context); |
| | | let bgStartX, bgEndX, bgWidth; |
| | | if (widthArr[i].position == 'left') { |
| | | bgStartX = tStartLeft - widthArr[i].width; |
| | | bgStartX = tStartLeft - (textWidth + config.toolTipPadding * 2) - 2 * opts.pix; |
| | | bgEndX = Math.max(bgStartX, bgStartX + textWidth + config.toolTipPadding * 2); |
| | | } else { |
| | | bgStartX = tStartRight; |
| | | bgStartX = tStartRight + 2 * opts.pix; |
| | | bgEndX = Math.max(bgStartX + widthArr[i].width, bgStartX + textWidth + config.toolTipPadding * 2); |
| | | } |
| | | bgWidth = bgEndX - bgStartX; |
| | |
| | | context.setFillStyle(hexToRgb(toolTipOption.labelBgColor || config.toolTipBackground, toolTipOption.labelBgOpacity || config.toolTipOpacity)); |
| | | context.setStrokeStyle(toolTipOption.labelBgColor || config.toolTipBackground); |
| | | context.setLineWidth(1 * opts.pix); |
| | | context.rect(bgStartX, textY - 0.5 * config.fontSize - config.toolTipPadding, bgWidth, config.fontSize + 2 * |
| | | config.toolTipPadding); |
| | | context.rect(bgStartX, textY - 0.5 * config.fontSize - config.toolTipPadding, bgWidth, config.fontSize + 2 * config.toolTipPadding); |
| | | context.closePath(); |
| | | context.stroke(); |
| | | context.fill(); |
| | |
| | | function drawToolTipSplitArea(offsetX, opts, config, context, eachSpacing) { |
| | | var toolTipOption = assign({}, { |
| | | activeBgColor: '#000000', |
| | | activeBgOpacity: 0.08 |
| | | activeBgOpacity: 0.08, |
| | | activeWidth: eachSpacing |
| | | }, opts.extra.column); |
| | | toolTipOption.activeWidth = toolTipOption.activeWidth > eachSpacing ? eachSpacing : toolTipOption.activeWidth; |
| | | var startY = opts.area[0]; |
| | | var endY = opts.height - opts.area[2]; |
| | | context.beginPath(); |
| | | context.setFillStyle(hexToRgb(toolTipOption.activeBgColor, toolTipOption.activeBgOpacity)); |
| | | context.rect(offsetX - eachSpacing / 2, startY, eachSpacing, endY - startY); |
| | | context.rect(offsetX - toolTipOption.activeWidth / 2, startY, toolTipOption.activeWidth, endY - startY); |
| | | context.closePath(); |
| | | context.fill(); |
| | | context.setFillStyle("#FFFFFF"); |
| | |
| | | context.fill(); |
| | | context.setFillStyle("#FFFFFF"); |
| | | } |
| | | |
| | | |
| | | function drawToolTip(textList, offset, opts, config, context, eachSpacing, xAxisPoints) { |
| | | var toolTipOption = assign({}, { |
| | |
| | | var legendMarginRight = 5 * opts.pix; |
| | | var arrowWidth = toolTipOption.showArrow ? 8 * opts.pix : 0; |
| | | var isOverRightBorder = false; |
| | | if (opts.type == 'line' || opts.type == 'area' || opts.type == 'candle' || opts.type == 'mix') { |
| | | if (opts.type == 'line' || opts.type == 'mount' || opts.type == 'area' || opts.type == 'candle' || opts.type == 'mix') { |
| | | if (toolTipOption.splitLine == true) { |
| | | drawToolTipSplitLine(opts.tooltip.offset.x, opts, config, context); |
| | | } |
| | |
| | | context.setStrokeStyle(hexToRgb(toolTipOption.borderColor, toolTipOption.borderOpacity)); |
| | | var radius = toolTipOption.borderRadius; |
| | | if (isOverRightBorder) { |
| | | // 增加左侧仍然超出的判断 |
| | | if(toolTipWidth + arrowWidth > opts.width){ |
| | | offset.x = opts.width + Math.abs(opts._scrollDistance_ || 0) + arrowWidth + (toolTipWidth - opts.width) |
| | | } |
| | | if (toolTipOption.showArrow) { |
| | | context.moveTo(offset.x, offset.y + 10 * opts.pix); |
| | | context.lineTo(offset.x - arrowWidth, offset.y + 10 * opts.pix + 5 * opts.pix); |
| | |
| | | startX = offset.x - toolTipWidth - arrowWidth + 2 * config.toolTipPadding; |
| | | } |
| | | context.fillRect(startX, startY, legendWidth, config.fontSize); |
| | | // 圆形图例请注释上行,并把下行取消注释 |
| | | // context.arc(startX + legendWidth / 2 , startY + opts.fontSize / 2, 4 * opts.pix, 0, 2 * Math.PI); |
| | | context.closePath(); |
| | | context.fill(); |
| | | } |
| | | }); |
| | | // draw text list |
| | |
| | | context.arc(left + r3, top + height - r3, r3, Math.PI / 2, Math.PI); |
| | | } else { |
| | | context.moveTo(startX, item.y); |
| | | context.lineTo(startX + item.width - 2, item.y); |
| | | context.lineTo(startX + item.width - 2, opts.height - opts.area[2]); |
| | | context.lineTo(startX + item.width, item.y); |
| | | context.lineTo(startX + item.width, opts.height - opts.area[2]); |
| | | context.lineTo(startX, opts.height - opts.area[2]); |
| | | context.lineTo(startX, item.y); |
| | | context.setLineWidth(1) |
| | |
| | | } |
| | | context.setFillStyle(fillColor); |
| | | context.moveTo(startX, item.y); |
| | | context.fillRect(startX, item.y, item.width - 2, height); |
| | | context.fillRect(startX, item.y, item.width, height); |
| | | context.closePath(); |
| | | context.fill(); |
| | | } |
| | |
| | | var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process); |
| | | calPoints.push(points); |
| | | points = fixColumeMeterData(points, eachSpacing, series.length, seriesIndex, config, opts, columnOption.meterBorder); |
| | | if (seriesIndex == 0) { |
| | | for (let i = 0; i < points.length; i++) { |
| | | let item = points[i]; |
| | | if (item !== null && i > leftNum && i < rightNum) { |
| | | //画背景颜色 |
| | | context.beginPath(); |
| | | context.setFillStyle(columnOption.meterFillColor); |
| | | if (seriesIndex == 0 && columnOption.meterBorder > 0) { |
| | | context.setStrokeStyle(eachSeries.color); |
| | | context.setLineWidth(columnOption.meterBorder * opts.pix); |
| | | } |
| | | if(seriesIndex == 0){ |
| | | context.setFillStyle(columnOption.meterFillColor); |
| | | }else{ |
| | | context.setFillStyle(item.color || eachSeries.color); |
| | | } |
| | | var startX = item.x - item.width / 2; |
| | | var height = opts.height - item.y - opts.area[2]; |
| | | if (columnOption.barBorderCircle) { |
| | | var barBorderRadius = (item.width - columnOption.meterBorder*2) / 2; |
| | | if(barBorderRadius>height){ |
| | | barBorderRadius = height; |
| | | if ((columnOption.barBorderRadius && columnOption.barBorderRadius.length === 4) || columnOption.barBorderCircle === true) { |
| | | const left = startX; |
| | | const top = item.y; |
| | | const width = item.width; |
| | | const height = opts.height - opts.area[2] - item.y; |
| | | if (columnOption.barBorderCircle) { |
| | | columnOption.barBorderRadius = [width / 2, width / 2, 0, 0]; |
| | | } |
| | | context.moveTo(startX + columnOption.meterBorder, opts.height - opts.area[2]); |
| | | context.lineTo(startX + columnOption.meterBorder, item.y + barBorderRadius); |
| | | context.arc(startX + item.width/2, item.y + barBorderRadius, barBorderRadius, -Math.PI, 0); |
| | | context.lineTo(startX + item.width - columnOption.meterBorder , opts.height - opts.area[2]); |
| | | context.lineTo(startX, opts.height - opts.area[2]); |
| | | let [r0, r1, r2, r3] = columnOption.barBorderRadius; |
| | | let minRadius = Math.min(width/2,height/2); |
| | | r0 = r0 > minRadius ? minRadius : r0; |
| | | r1 = r1 > minRadius ? minRadius : r1; |
| | | r2 = r2 > minRadius ? minRadius : r2; |
| | | r3 = r3 > minRadius ? minRadius : r3; |
| | | r0 = r0 < 0 ? 0 : r0; |
| | | r1 = r1 < 0 ? 0 : r1; |
| | | r2 = r2 < 0 ? 0 : r2; |
| | | r3 = r3 < 0 ? 0 : r3; |
| | | context.arc(left + r0, top + r0, r0, -Math.PI, -Math.PI / 2); |
| | | context.arc(left + width - r1, top + r1, r1, -Math.PI / 2, 0); |
| | | context.arc(left + width - r2, top + height - r2, r2, 0, Math.PI / 2); |
| | | context.arc(left + r3, top + height - r3, r3, Math.PI / 2, Math.PI); |
| | | context.fill(); |
| | | }else{ |
| | | context.moveTo(startX, item.y); |
| | | context.fillRect(startX, item.y, item.width, height); |
| | | context.closePath(); |
| | | context.lineTo(startX + item.width, item.y); |
| | | context.lineTo(startX + item.width, opts.height - opts.area[2]); |
| | | context.lineTo(startX, opts.height - opts.area[2]); |
| | | context.lineTo(startX, item.y); |
| | | context.fill(); |
| | | } |
| | | //画边框线 |
| | | if (columnOption.meterBorder > 0) { |
| | | context.beginPath(); |
| | | context.setStrokeStyle(eachSeries.color); |
| | | context.setLineWidth(columnOption.meterBorder * opts.pix); |
| | | if (columnOption.barBorderCircle) { |
| | | var barBorderRadius = (item.width - columnOption.meterBorder)/ 2; |
| | | if(barBorderRadius>height){ |
| | | barBorderRadius = height; |
| | | } |
| | | context.moveTo(startX + columnOption.meterBorder * 0.5, opts.height - opts.area[2]); |
| | | context.lineTo(startX + columnOption.meterBorder * 0.5, item.y + barBorderRadius); |
| | | context.arc(startX + item.width/2, item.y + barBorderRadius - columnOption.meterBorder * 0.5, barBorderRadius, -Math.PI, 0); |
| | | context.lineTo(startX + item.width - columnOption.meterBorder * 0.5, opts.height - opts.area[2]); |
| | | }else{ |
| | | context.moveTo(startX + columnOption.meterBorder * 0.5, item.y + height); |
| | | context.lineTo(startX + columnOption.meterBorder * 0.5, item.y + columnOption.meterBorder * 0.5); |
| | | context.lineTo(startX + item.width - columnOption.meterBorder * 0.5, item.y + columnOption.meterBorder * 0.5); |
| | | context.lineTo(startX + item.width - columnOption.meterBorder * 0.5, item.y + height); |
| | | } |
| | | if (seriesIndex == 0 && columnOption.meterBorder > 0) { |
| | | context.closePath(); |
| | | context.stroke(); |
| | | } |
| | | } |
| | | }; |
| | | } else { |
| | | for (let i = 0; i < points.length; i++) { |
| | | let item = points[i]; |
| | | if (item !== null && i > leftNum && i < rightNum) { |
| | | context.beginPath(); |
| | | context.setFillStyle(item.color || eachSeries.color); |
| | | var startX = item.x - item.width / 2; |
| | | var height = opts.height - item.y - opts.area[2]; |
| | | if (columnOption.barBorderCircle) { |
| | | var barBorderRadius = item.width / 2; |
| | | if(barBorderRadius>height){ |
| | | barBorderRadius = height; |
| | | } |
| | | context.moveTo(startX, opts.height - opts.area[2]); |
| | | context.arc(startX + barBorderRadius, item.y + barBorderRadius, barBorderRadius, -Math.PI, -Math.PI / 2); |
| | | context.arc(startX + item.width - barBorderRadius, item.y + barBorderRadius, barBorderRadius, -Math.PI / 2, 0); |
| | | context.lineTo(startX + item.width, opts.height - opts.area[2]); |
| | | context.lineTo(startX, opts.height - opts.area[2]); |
| | | context.fill(); |
| | | }else{ |
| | | context.moveTo(startX, item.y); |
| | | context.fillRect(startX, item.y, item.width, height); |
| | | context.closePath(); |
| | | context.fill(); |
| | | } |
| | | } |
| | | }; |
| | | } |
| | | } |
| | | break; |
| | | } |
| | | }); |
| | |
| | | return { |
| | | xAxisPoints: xAxisPoints, |
| | | calPoints: calPoints, |
| | | eachSpacing: eachSpacing |
| | | }; |
| | | } |
| | | |
| | | function drawMountDataPoints(series, opts, config, context) { |
| | | let process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1; |
| | | let xAxisData = opts.chartData.xAxisData, |
| | | xAxisPoints = xAxisData.xAxisPoints, |
| | | eachSpacing = xAxisData.eachSpacing; |
| | | let mountOption = assign({}, { |
| | | type: 'mount', |
| | | widthRatio: 1, |
| | | borderWidth: 1, |
| | | barBorderCircle: false, |
| | | barBorderRadius: [], |
| | | linearType: 'none', |
| | | linearOpacity: 1, |
| | | customColor: [], |
| | | colorStop: 0, |
| | | }, opts.extra.mount); |
| | | mountOption.widthRatio = mountOption.widthRatio <= 0 ? 0 : mountOption.widthRatio; |
| | | mountOption.widthRatio = mountOption.widthRatio >= 2 ? 2 : mountOption.widthRatio; |
| | | let calPoints = []; |
| | | context.save(); |
| | | let leftNum = -2; |
| | | let rightNum = xAxisPoints.length + 2; |
| | | if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) { |
| | | context.translate(opts._scrollDistance_, 0); |
| | | leftNum = Math.floor(-opts._scrollDistance_ / eachSpacing) - 2; |
| | | rightNum = leftNum + opts.xAxis.itemCount + 4; |
| | | } |
| | | mountOption.customColor = fillCustomColor(mountOption.linearType, mountOption.customColor, series, config); |
| | | let ranges, minRange, maxRange; |
| | | ranges = [].concat(opts.chartData.yAxisData.ranges[0]); |
| | | minRange = ranges.pop(); |
| | | maxRange = ranges.shift(); |
| | | var points = getMountDataPoints(series, minRange, maxRange, xAxisPoints, eachSpacing, opts, mountOption, process); |
| | | switch (mountOption.type) { |
| | | case 'bar': |
| | | for (let i = 0; i < points.length; i++) { |
| | | let item = points[i]; |
| | | if (item !== null && i > leftNum && i < rightNum) { |
| | | var startX = item.x - eachSpacing*mountOption.widthRatio/2; |
| | | var height = opts.height - item.y - opts.area[2]; |
| | | context.beginPath(); |
| | | var fillColor = item.color || series[i].color |
| | | var strokeColor = item.color || series[i].color |
| | | if (mountOption.linearType !== 'none') { |
| | | var grd = context.createLinearGradient(startX, item.y, startX, opts.height - opts.area[2]); |
| | | //透明渐变 |
| | | if (mountOption.linearType == 'opacity') { |
| | | grd.addColorStop(0, hexToRgb(fillColor, mountOption.linearOpacity)); |
| | | grd.addColorStop(1, hexToRgb(fillColor, 1)); |
| | | } else { |
| | | grd.addColorStop(0, hexToRgb(mountOption.customColor[series[i].linearIndex], mountOption.linearOpacity)); |
| | | grd.addColorStop(mountOption.colorStop, hexToRgb(mountOption.customColor[series[i].linearIndex],mountOption.linearOpacity)); |
| | | grd.addColorStop(1, hexToRgb(fillColor, 1)); |
| | | } |
| | | fillColor = grd |
| | | } |
| | | // 圆角边框 |
| | | if ((mountOption.barBorderRadius && mountOption.barBorderRadius.length === 4) || mountOption.barBorderCircle === true) { |
| | | const left = startX; |
| | | const top = item.y; |
| | | const width = item.width; |
| | | const height = opts.height - opts.area[2] - item.y - mountOption.borderWidth * opts.pix / 2; |
| | | if (mountOption.barBorderCircle) { |
| | | mountOption.barBorderRadius = [width / 2, width / 2, 0, 0]; |
| | | } |
| | | let [r0, r1, r2, r3] = mountOption.barBorderRadius; |
| | | let minRadius = Math.min(width/2,height/2); |
| | | r0 = r0 > minRadius ? minRadius : r0; |
| | | r1 = r1 > minRadius ? minRadius : r1; |
| | | r2 = r2 > minRadius ? minRadius : r2; |
| | | r3 = r3 > minRadius ? minRadius : r3; |
| | | r0 = r0 < 0 ? 0 : r0; |
| | | r1 = r1 < 0 ? 0 : r1; |
| | | r2 = r2 < 0 ? 0 : r2; |
| | | r3 = r3 < 0 ? 0 : r3; |
| | | context.arc(left + r0, top + r0, r0, -Math.PI, -Math.PI / 2); |
| | | context.arc(left + width - r1, top + r1, r1, -Math.PI / 2, 0); |
| | | context.arc(left + width - r2, top + height - r2, r2, 0, Math.PI / 2); |
| | | context.arc(left + r3, top + height - r3, r3, Math.PI / 2, Math.PI); |
| | | } else { |
| | | context.moveTo(startX, item.y); |
| | | context.lineTo(startX + item.width, item.y); |
| | | context.lineTo(startX + item.width, opts.height - opts.area[2]); |
| | | context.lineTo(startX, opts.height - opts.area[2]); |
| | | context.lineTo(startX, item.y); |
| | | } |
| | | context.setStrokeStyle(strokeColor); |
| | | context.setFillStyle(fillColor); |
| | | if(mountOption.borderWidth > 0){ |
| | | context.setLineWidth(mountOption.borderWidth * opts.pix); |
| | | context.closePath(); |
| | | context.stroke(); |
| | | } |
| | | context.fill(); |
| | | } |
| | | }; |
| | | break; |
| | | case 'triangle': |
| | | for (let i = 0; i < points.length; i++) { |
| | | let item = points[i]; |
| | | if (item !== null && i > leftNum && i < rightNum) { |
| | | var startX = item.x - eachSpacing*mountOption.widthRatio/2; |
| | | var height = opts.height - item.y - opts.area[2]; |
| | | context.beginPath(); |
| | | var fillColor = item.color || series[i].color |
| | | var strokeColor = item.color || series[i].color |
| | | if (mountOption.linearType !== 'none') { |
| | | var grd = context.createLinearGradient(startX, item.y, startX, opts.height - opts.area[2]); |
| | | //透明渐变 |
| | | if (mountOption.linearType == 'opacity') { |
| | | grd.addColorStop(0, hexToRgb(fillColor, mountOption.linearOpacity)); |
| | | grd.addColorStop(1, hexToRgb(fillColor, 1)); |
| | | } else { |
| | | grd.addColorStop(0, hexToRgb(mountOption.customColor[series[i].linearIndex], mountOption.linearOpacity)); |
| | | grd.addColorStop(mountOption.colorStop, hexToRgb(mountOption.customColor[series[i].linearIndex],mountOption.linearOpacity)); |
| | | grd.addColorStop(1, hexToRgb(fillColor, 1)); |
| | | } |
| | | fillColor = grd |
| | | } |
| | | context.moveTo(startX, opts.height - opts.area[2]); |
| | | context.lineTo(item.x, item.y); |
| | | context.lineTo(startX + item.width, opts.height - opts.area[2]); |
| | | context.setStrokeStyle(strokeColor); |
| | | context.setFillStyle(fillColor); |
| | | if(mountOption.borderWidth > 0){ |
| | | context.setLineWidth(mountOption.borderWidth * opts.pix); |
| | | context.stroke(); |
| | | } |
| | | context.fill(); |
| | | } |
| | | }; |
| | | break; |
| | | case 'mount': |
| | | for (let i = 0; i < points.length; i++) { |
| | | let item = points[i]; |
| | | if (item !== null && i > leftNum && i < rightNum) { |
| | | var startX = item.x - eachSpacing*mountOption.widthRatio/2; |
| | | var height = opts.height - item.y - opts.area[2]; |
| | | context.beginPath(); |
| | | var fillColor = item.color || series[i].color |
| | | var strokeColor = item.color || series[i].color |
| | | if (mountOption.linearType !== 'none') { |
| | | var grd = context.createLinearGradient(startX, item.y, startX, opts.height - opts.area[2]); |
| | | //透明渐变 |
| | | if (mountOption.linearType == 'opacity') { |
| | | grd.addColorStop(0, hexToRgb(fillColor, mountOption.linearOpacity)); |
| | | grd.addColorStop(1, hexToRgb(fillColor, 1)); |
| | | } else { |
| | | grd.addColorStop(0, hexToRgb(mountOption.customColor[series[i].linearIndex], mountOption.linearOpacity)); |
| | | grd.addColorStop(mountOption.colorStop, hexToRgb(mountOption.customColor[series[i].linearIndex],mountOption.linearOpacity)); |
| | | grd.addColorStop(1, hexToRgb(fillColor, 1)); |
| | | } |
| | | fillColor = grd |
| | | } |
| | | context.moveTo(startX, opts.height - opts.area[2]); |
| | | context.bezierCurveTo(item.x - item.width/4, opts.height - opts.area[2], item.x - item.width/4, item.y, item.x, item.y); |
| | | context.bezierCurveTo(item.x + item.width/4, item.y, item.x + item.width/4, opts.height - opts.area[2], startX + item.width, opts.height - opts.area[2]); |
| | | context.setStrokeStyle(strokeColor); |
| | | context.setFillStyle(fillColor); |
| | | if(mountOption.borderWidth > 0){ |
| | | context.setLineWidth(mountOption.borderWidth * opts.pix); |
| | | context.stroke(); |
| | | } |
| | | context.fill(); |
| | | } |
| | | }; |
| | | break; |
| | | case 'sharp': |
| | | for (let i = 0; i < points.length; i++) { |
| | | let item = points[i]; |
| | | if (item !== null && i > leftNum && i < rightNum) { |
| | | var startX = item.x - eachSpacing*mountOption.widthRatio/2; |
| | | var height = opts.height - item.y - opts.area[2]; |
| | | context.beginPath(); |
| | | var fillColor = item.color || series[i].color |
| | | var strokeColor = item.color || series[i].color |
| | | if (mountOption.linearType !== 'none') { |
| | | var grd = context.createLinearGradient(startX, item.y, startX, opts.height - opts.area[2]); |
| | | //透明渐变 |
| | | if (mountOption.linearType == 'opacity') { |
| | | grd.addColorStop(0, hexToRgb(fillColor, mountOption.linearOpacity)); |
| | | grd.addColorStop(1, hexToRgb(fillColor, 1)); |
| | | } else { |
| | | grd.addColorStop(0, hexToRgb(mountOption.customColor[series[i].linearIndex], mountOption.linearOpacity)); |
| | | grd.addColorStop(mountOption.colorStop, hexToRgb(mountOption.customColor[series[i].linearIndex],mountOption.linearOpacity)); |
| | | grd.addColorStop(1, hexToRgb(fillColor, 1)); |
| | | } |
| | | fillColor = grd |
| | | } |
| | | context.moveTo(startX, opts.height - opts.area[2]); |
| | | context.quadraticCurveTo(item.x - 0, opts.height - opts.area[2] - height/4, item.x, item.y); |
| | | context.quadraticCurveTo(item.x + 0, opts.height - opts.area[2] - height/4, startX + item.width, opts.height - opts.area[2]) |
| | | context.setStrokeStyle(strokeColor); |
| | | context.setFillStyle(fillColor); |
| | | if(mountOption.borderWidth > 0){ |
| | | context.setLineWidth(mountOption.borderWidth * opts.pix); |
| | | context.stroke(); |
| | | } |
| | | context.fill(); |
| | | } |
| | | }; |
| | | break; |
| | | } |
| | | |
| | | if (opts.dataLabel !== false && process === 1) { |
| | | let ranges, minRange, maxRange; |
| | | ranges = [].concat(opts.chartData.yAxisData.ranges[0]); |
| | | minRange = ranges.pop(); |
| | | maxRange = ranges.shift(); |
| | | var points = getMountDataPoints(series, minRange, maxRange, xAxisPoints, eachSpacing, opts, mountOption, process); |
| | | drawMountPointText(points, series, config, context, opts); |
| | | } |
| | | context.restore(); |
| | | return { |
| | | xAxisPoints: xAxisPoints, |
| | | calPoints: points, |
| | | eachSpacing: eachSpacing |
| | | }; |
| | | } |
| | |
| | | const left = startX; |
| | | const width = item.width; |
| | | const top = item.y - item.width / 2; |
| | | const height = item.heigh; |
| | | const height = item.height; |
| | | if (columnOption.barBorderCircle) { |
| | | columnOption.barBorderRadius = [width / 2, width / 2, 0, 0]; |
| | | } |
| | |
| | | } else { |
| | | context.moveTo(startX, startY); |
| | | context.lineTo(item.x, startY); |
| | | context.lineTo(item.x, startY + item.width - 2); |
| | | context.lineTo(startX, startY + item.width - 2); |
| | | context.lineTo(item.x, startY + item.width); |
| | | context.lineTo(startX, startY + item.width); |
| | | context.lineTo(startX, startY); |
| | | context.setLineWidth(1) |
| | | context.setStrokeStyle(strokeColor); |
| | |
| | | var startX = item.x0; |
| | | context.setFillStyle(fillColor); |
| | | context.moveTo(startX, item.y - item.width/2); |
| | | context.fillRect(startX, item.y - item.width/2, item.height , item.width - 2); |
| | | context.fillRect(startX, item.y - item.width/2, item.height , item.width); |
| | | context.closePath(); |
| | | context.fill(); |
| | | } |
| | |
| | | if (opts.dataLabel !== false && process === 1) { |
| | | points.forEach(function(item, index) { |
| | | context.beginPath(); |
| | | var fontSize = series.textSize * opts.pix || config.fontSize; |
| | | var fontSize = eachSeries.textSize * opts.pix || config.fontSize; |
| | | context.setFontSize(fontSize); |
| | | context.setFillStyle(series.textColor || "#FFFFFF"); |
| | | context.setFillStyle(eachSeries.textColor || "#FFFFFF"); |
| | | context.setTextAlign('center'); |
| | | context.fillText(String(item.t), item.x, item.y + fontSize/2); |
| | | context.closePath(); |
| | |
| | | eachSpacing: eachSpacing |
| | | }; |
| | | } |
| | | |
| | | |
| | | function drawLineDataPoints(series, opts, config, context) { |
| | | var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1; |
| | |
| | | |
| | | function drawMixDataPoints(series, opts, config, context) { |
| | | let process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1; |
| | | let xAxisData = opts.chartData.xAxisData, |
| | | xAxisPoints = xAxisData.xAxisPoints, |
| | | eachSpacing = xAxisData.eachSpacing; |
| | | let columnOption = assign({}, { |
| | | width: eachSpacing / 2, |
| | | barBorderCircle: false, |
| | |
| | | customColor: [], |
| | | colorStop: 0, |
| | | }, opts.extra.mix.column); |
| | | let xAxisData = opts.chartData.xAxisData, |
| | | xAxisPoints = xAxisData.xAxisPoints, |
| | | eachSpacing = xAxisData.eachSpacing; |
| | | let areaOption = assign({}, { |
| | | opacity: 0.2, |
| | | gradient: false |
| | | }, opts.extra.mix.area); |
| | | let lineOption = assign({}, { |
| | | width: 2 |
| | | }, opts.extra.mix.line); |
| | | let endY = opts.height - opts.area[2]; |
| | | let calPoints = []; |
| | | var columnIndex = 0; |
| | |
| | | context.arc(left + r3, top + height - r3, r3, Math.PI / 2, Math.PI); |
| | | } else { |
| | | context.moveTo(startX, item.y); |
| | | context.lineTo(startX + item.width - 2, item.y); |
| | | context.lineTo(startX + item.width - 2, opts.height - opts.area[2]); |
| | | context.lineTo(startX + item.width, item.y); |
| | | context.lineTo(startX + item.width, opts.height - opts.area[2]); |
| | | context.lineTo(startX, opts.height - opts.area[2]); |
| | | context.lineTo(startX, item.y); |
| | | context.setLineWidth(1) |
| | |
| | | // 绘制区域数据 |
| | | context.beginPath(); |
| | | context.setStrokeStyle(eachSeries.color); |
| | | context.setFillStyle(hexToRgb(eachSeries.color, 0.2)); |
| | | context.setStrokeStyle(hexToRgb(eachSeries.color, areaOption.opacity)); |
| | | if (areaOption.gradient) { |
| | | let gradient = context.createLinearGradient(0, opts.area[0], 0, opts.height - opts.area[2]); |
| | | gradient.addColorStop('0', hexToRgb(eachSeries.color, areaOption.opacity)); |
| | | gradient.addColorStop('1.0', hexToRgb("#FFFFFF", 0.1)); |
| | | context.setFillStyle(gradient); |
| | | } else { |
| | | context.setFillStyle(hexToRgb(eachSeries.color, areaOption.opacity)); |
| | | } |
| | | context.setLineWidth(2 * opts.pix); |
| | | if (points.length > 1) { |
| | | var firstPoint = points[0]; |
| | |
| | | } |
| | | context.beginPath(); |
| | | context.setStrokeStyle(eachSeries.color); |
| | | context.setLineWidth(2 * opts.pix); |
| | | context.setLineWidth(lineOption.width * opts.pix); |
| | | if (points.length === 1) { |
| | | context.moveTo(points[0].x, points[0].y); |
| | | context.arc(points[0].x, points[0].y, 1, 0, 2 * Math.PI); |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | function drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints) { |
| | | var toolTipOption = opts.extra.tooltip || {}; |
| | | if (toolTipOption.horizentalLine && opts.tooltip && process === 1 && (opts.type == 'line' || opts.type == 'area' || opts.type == 'column' || opts.type == 'candle' || opts.type == 'mix')) { |
| | | if (toolTipOption.horizentalLine && opts.tooltip && process === 1 && (opts.type == 'line' || opts.type == 'area' || opts.type == 'column' || opts.type == 'mount' || opts.type == 'candle' || opts.type == 'mix')) { |
| | | drawToolTipHorizentalLine(opts, config, context, eachSpacing, xAxisPoints) |
| | | } |
| | | context.save(); |
| | |
| | | var scrollY = opts.height - opts.area[2] + config.xAxisHeight; |
| | | var scrollScreenWidth = endX - startX; |
| | | var scrollTotalWidth = eachSpacing * (xAxisPoints.length - 1); |
| | | if(opts.type == 'mount' && opts.extra && opts.extra.mount && opts.extra.mount.widthRatio && opts.extra.mount.widthRatio > 1){ |
| | | if(opts.extra.mount.widthRatio>2) opts.extra.mount.widthRatio = 2 |
| | | scrollTotalWidth += (opts.extra.mount.widthRatio - 1)*eachSpacing; |
| | | } |
| | | var scrollWidth = scrollScreenWidth * scrollScreenWidth / scrollTotalWidth; |
| | | var scrollLeft = 0; |
| | | if (opts._scrollDistance_) { |
| | |
| | | var xAxisFontSize = opts.xAxis.fontSize * opts.pix || config.fontSize; |
| | | if (config._xAxisTextAngle_ === 0) { |
| | | newCategories.forEach(function(item, index) { |
| | | var xitem = opts.xAxis.formatter ? opts.xAxis.formatter(item) : item; |
| | | var xitem = opts.xAxis.formatter ? opts.xAxis.formatter(item,index,opts) : item; |
| | | var offset = -measureText(String(xitem), xAxisFontSize, context) / 2; |
| | | if (boundaryGap == 'center') { |
| | | offset += eachSpacing / 2; |
| | |
| | | if (opts.xAxis.scrollShow) { |
| | | scrollHeight = 6 * opts.pix; |
| | | } |
| | | context.beginPath(); |
| | | context.setFontSize(xAxisFontSize); |
| | | context.setFillStyle(opts.xAxis.fontColor || opts.fontColor); |
| | | context.fillText(String(xitem), xAxisPoints[index] + offset, startY + xAxisFontSize + (config.xAxisHeight - scrollHeight - xAxisFontSize) / 2); |
| | | context.closePath(); |
| | | context.stroke(); |
| | | // 如果在主视图区域内 |
| | | var _scrollDistance_ = opts._scrollDistance_ || 0; |
| | | var truePoints = boundaryGap == 'center' ? xAxisPoints[index] + eachSpacing / 2 : xAxisPoints[index]; |
| | | if((truePoints - Math.abs(_scrollDistance_)) >= opts.area[3] && (truePoints - Math.abs(_scrollDistance_)) <= (opts.width - opts.area[1])){ |
| | | context.beginPath(); |
| | | context.setFontSize(xAxisFontSize); |
| | | context.setFillStyle(opts.xAxis.fontColor || opts.fontColor); |
| | | context.fillText(String(xitem), xAxisPoints[index] + offset, startY + xAxisFontSize + (config.xAxisHeight - scrollHeight - xAxisFontSize) / 2); |
| | | context.closePath(); |
| | | context.stroke(); |
| | | } |
| | | }); |
| | | } else { |
| | | newCategories.forEach(function(item, index) { |
| | | var xitem = opts.xAxis.formatter ? opts.xAxis.formatter(item) : item; |
| | | context.save(); |
| | | context.beginPath(); |
| | | context.setFontSize(xAxisFontSize); |
| | | context.setFillStyle(opts.xAxis.fontColor || opts.fontColor); |
| | | var textWidth = measureText(String(xitem), xAxisFontSize, context); |
| | | var offset = -textWidth; |
| | | if (boundaryGap == 'center') { |
| | | offset += eachSpacing / 2; |
| | | // 如果在主视图区域内 |
| | | var _scrollDistance_ = opts._scrollDistance_ || 0; |
| | | var truePoints = boundaryGap == 'center' ? xAxisPoints[index] + eachSpacing / 2 : xAxisPoints[index]; |
| | | if((truePoints - Math.abs(_scrollDistance_)) >= opts.area[3] && (truePoints - Math.abs(_scrollDistance_)) <= (opts.width - opts.area[1])){ |
| | | context.save(); |
| | | context.beginPath(); |
| | | context.setFontSize(xAxisFontSize); |
| | | context.setFillStyle(opts.xAxis.fontColor || opts.fontColor); |
| | | var textWidth = measureText(String(xitem), xAxisFontSize, context); |
| | | var offsetX = xAxisPoints[index]; |
| | | if (boundaryGap == 'center') { |
| | | offsetX = xAxisPoints[index] + eachSpacing / 2; |
| | | } |
| | | var scrollHeight = 0; |
| | | if (opts.xAxis.scrollShow) { |
| | | scrollHeight = 6 * opts.pix; |
| | | } |
| | | var offsetY = startY + 6 * opts.pix + xAxisFontSize - xAxisFontSize * Math.abs(Math.sin(config._xAxisTextAngle_)); |
| | | if(opts.xAxis.rotateAngle < 0){ |
| | | offsetX -= xAxisFontSize / 2; |
| | | textWidth = 0; |
| | | }else{ |
| | | offsetX += xAxisFontSize / 2; |
| | | textWidth = -textWidth; |
| | | } |
| | | context.translate(offsetX, offsetY); |
| | | context.rotate(-1 * config._xAxisTextAngle_); |
| | | context.fillText(String(xitem), textWidth , 0 ); |
| | | context.closePath(); |
| | | context.stroke(); |
| | | context.restore(); |
| | | } |
| | | var _calRotateTranslate = calRotateTranslate(xAxisPoints[index] + eachSpacing / 2, startY + xAxisFontSize / 2 + 5, opts.height), |
| | | transX = _calRotateTranslate.transX, |
| | | transY = _calRotateTranslate.transY; |
| | | |
| | | context.rotate(-1 * config._xAxisTextAngle_); |
| | | context.translate(transX, transY); |
| | | context.fillText(String(xitem), xAxisPoints[index] + offset, startY + xAxisFontSize + 5); |
| | | context.closePath(); |
| | | context.stroke(); |
| | | context.restore(); |
| | | }); |
| | | } |
| | | } |
| | |
| | | let xAxisPoints = opts.chartData.xAxisData.xAxisPoints, |
| | | xAxiseachSpacing = opts.chartData.xAxisData.eachSpacing; |
| | | let TotalWidth = xAxiseachSpacing * (xAxisPoints.length - 1); |
| | | if(opts.type == 'mount' && opts.extra && opts.extra.mount && opts.extra.mount.widthRatio && opts.extra.mount.widthRatio > 1 ){ |
| | | if(opts.extra.mount.widthRatio>2) opts.extra.mount.widthRatio = 2 |
| | | TotalWidth += (opts.extra.mount.widthRatio - 1)*xAxiseachSpacing; |
| | | } |
| | | let endX = startX + TotalWidth; |
| | | let points = []; |
| | | let startY = 1 |
| | |
| | | var startX = opts.area[3]; |
| | | var endX = opts.width - opts.area[1]; |
| | | var endY = opts.height - opts.area[2]; |
| | | var fillEndY = endY + config.xAxisHeight; |
| | | if (opts.xAxis.scrollShow) { |
| | | fillEndY -= 3 * opts.pix; |
| | | } |
| | | if (opts.xAxis.rotateLabel) { |
| | | fillEndY = opts.height - opts.area[2] + opts.fontSize * opts.pix / 2; |
| | | } |
| | | // set YAxis background |
| | | context.beginPath(); |
| | | context.setFillStyle(opts.background); |
| | | if (opts.enableScroll == true && opts.xAxis.scrollPosition && opts.xAxis.scrollPosition !== 'left') { |
| | | context.fillRect(0, 0, startX, fillEndY); |
| | | context.fillRect(0, 0, startX, endY + 2 * opts.pix); |
| | | } |
| | | if (opts.enableScroll == true && opts.xAxis.scrollPosition && opts.xAxis.scrollPosition !== 'right') { |
| | | context.fillRect(endX, 0, opts.width, fillEndY); |
| | | context.fillRect(endX, 0, opts.width, endY + 2 * opts.pix); |
| | | } |
| | | context.closePath(); |
| | | context.stroke(); |
| | |
| | | let textAlign = yData.textAlign || "right"; |
| | | //画Y轴刻度及文案 |
| | | rangesFormat.forEach(function(item, index) { |
| | | var pos = points[index] ? points[index] : endY; |
| | | var pos = points[index]; |
| | | context.beginPath(); |
| | | context.setFontSize(yAxisFontSize); |
| | | context.setLineWidth(1 * opts.pix); |
| | |
| | | context.stroke(); |
| | | startX += shapeWidth + shapeRight; |
| | | let fontTrans = 0.5 * lineHeight + 0.5 * fontSize - 2; |
| | | const legendText = item.legendText ? item.legendText : item.name; |
| | | context.beginPath(); |
| | | context.setFontSize(fontSize); |
| | | context.setFillStyle(item.show ? opts.legend.fontColor : opts.legend.hiddenColor); |
| | | context.fillText(item.name, startX, startY + fontTrans); |
| | | context.fillText(legendText, startX, startY + fontTrans); |
| | | context.closePath(); |
| | | context.stroke(); |
| | | if (opts.legend.position == 'top' || opts.legend.position == 'bottom') { |
| | | startX += measureText(item.name, fontSize, context) + itemGap; |
| | | startX += measureText(legendText, fontSize, context) + itemGap; |
| | | item.area[2] = startX; |
| | | } else { |
| | | item.area[2] = startX + measureText(item.name, fontSize, context) + itemGap;; |
| | | item.area[2] = startX + measureText(legendText, fontSize, context) + itemGap;; |
| | | startX -= shapeWidth + shapeRight; |
| | | startY += lineHeight; |
| | | } |
| | |
| | | } |
| | | |
| | | var radius = Math.min((opts.width - opts.area[1] - opts.area[3]) / 2 - config.pieChartLinePadding - config.pieChartTextPadding - config._pieTextMaxLength_, (opts.height - opts.area[0] - opts.area[2]) / 2 - config.pieChartLinePadding - config.pieChartTextPadding); |
| | | radius = radius < 10 ? 10 : radius; |
| | | if (pieOption.customRadius > 0) { |
| | | radius = pieOption.customRadius * opts.pix; |
| | | } |
| | |
| | | context.fill(); |
| | | } |
| | | if (opts.dataLabel !== false && process === 1) { |
| | | var valid = false; |
| | | for (var i = 0, len = series.length; i < len; i++) { |
| | | if (series[i].data > 0) { |
| | | valid = true; |
| | | break; |
| | | } |
| | | } |
| | | if (valid) { |
| | | drawPieText(series, opts, config, context, radius, centerPosition); |
| | | } |
| | | drawPieText(series, opts, config, context, radius, centerPosition); |
| | | } |
| | | if (process === 1 && opts.type === 'ring') { |
| | | drawRingTitle(opts, config, context, centerPosition); |
| | |
| | | y: opts.area[0] + (opts.height - opts.area[0] - opts.area[2]) / 2 |
| | | }; |
| | | var radius = Math.min((opts.width - opts.area[1] - opts.area[3]) / 2 - config.pieChartLinePadding - config.pieChartTextPadding - config._pieTextMaxLength_, (opts.height - opts.area[0] - opts.area[2]) / 2 - config.pieChartLinePadding - config.pieChartTextPadding); |
| | | radius = radius < 10 ? 10 : radius; |
| | | var minRadius = roseOption.minRadius || radius * 0.5; |
| | | series = getRoseDataPoints(series, roseOption.type, minRadius, radius, process); |
| | | var activeRadius = roseOption.activeRadius * opts.pix; |
| | |
| | | }); |
| | | |
| | | if (opts.dataLabel !== false && process === 1) { |
| | | var valid = false; |
| | | for (var i = 0, len = series.length; i < len; i++) { |
| | | if (series[i].data > 0) { |
| | | valid = true; |
| | | break; |
| | | } |
| | | } |
| | | if (valid) { |
| | | drawPieText(series, opts, config, context, radius, centerPosition); |
| | | } |
| | | drawPieText(series, opts, config, context, radius, centerPosition); |
| | | } |
| | | return { |
| | | center: centerPosition, |
| | |
| | | startAngle: 0.75, |
| | | endAngle: 0.25, |
| | | type: 'default', |
| | | direction: 'cw', |
| | | lineCap: 'round', |
| | | width: 12 , |
| | | gap: 2 , |
| | | linearType: 'none', |
| | |
| | | radius -= 5 * opts.pix; |
| | | radius -= arcbarOption.width / 2; |
| | | } |
| | | radius = radius < 10 ? 10 : radius; |
| | | arcbarOption.customColor = fillCustomColor(arcbarOption.linearType, arcbarOption.customColor, series, config); |
| | | |
| | | for (let i = 0; i < series.length; i++) { |
| | |
| | | //背景颜色 |
| | | context.setLineWidth(arcbarOption.width * opts.pix); |
| | | context.setStrokeStyle(arcbarOption.backgroundColor || '#E9E9E9'); |
| | | context.setLineCap('round'); |
| | | context.setLineCap(arcbarOption.lineCap); |
| | | context.beginPath(); |
| | | if (arcbarOption.type == 'default') { |
| | | context.arc(centerPosition.x, centerPosition.y, radius - (arcbarOption.width * opts.pix + arcbarOption.gap * opts.pix) * i, arcbarOption.startAngle * Math.PI, arcbarOption.endAngle * Math.PI, false); |
| | | context.arc(centerPosition.x, centerPosition.y, radius - (arcbarOption.width * opts.pix + arcbarOption.gap * opts.pix) * i, arcbarOption.startAngle * Math.PI, arcbarOption.endAngle * Math.PI, arcbarOption.direction == 'ccw'); |
| | | } else { |
| | | context.arc(centerPosition.x, centerPosition.y, radius - (arcbarOption.width * opts.pix + arcbarOption.gap * opts.pix) * i, 0, 2 * Math.PI, false); |
| | | context.arc(centerPosition.x, centerPosition.y, radius - (arcbarOption.width * opts.pix + arcbarOption.gap * opts.pix) * i, 0, 2 * Math.PI, arcbarOption.direction == 'ccw'); |
| | | } |
| | | context.stroke(); |
| | | //进度条 |
| | |
| | | } |
| | | context.setLineWidth(arcbarOption.width * opts.pix); |
| | | context.setStrokeStyle(fillColor); |
| | | context.setLineCap('round'); |
| | | context.setLineCap(arcbarOption.lineCap); |
| | | context.beginPath(); |
| | | context.arc(centerPosition.x, centerPosition.y, radius - (arcbarOption.width * opts.pix + arcbarOption.gap * opts.pix) * i, arcbarOption.startAngle * Math.PI, eachSeries._proportion_ * Math.PI, false); |
| | | context.arc(centerPosition.x, centerPosition.y, radius - (arcbarOption.width * opts.pix + arcbarOption.gap * opts.pix) * i, arcbarOption.startAngle * Math.PI, eachSeries._proportion_ * Math.PI, arcbarOption.direction == 'ccw'); |
| | | context.stroke(); |
| | | } |
| | | drawRingTitle(opts, config, context, centerPosition); |
| | |
| | | var radius = Math.min(centerPosition.x, centerPosition.y); |
| | | radius -= 5 * opts.pix; |
| | | radius -= gaugeOption.width / 2; |
| | | radius = radius < 10 ? 10 : radius; |
| | | var innerRadius = radius - gaugeOption.width; |
| | | var totalAngle = 0; |
| | | //判断仪表盘的样式:default百度样式,progress新样式 |
| | |
| | | } |
| | | context.restore(); |
| | | //## 第三步画进度条 |
| | | series = getArcbarDataPoints(series, gaugeOption, process); |
| | | series = getGaugeArcbarDataPoints(series, gaugeOption, process); |
| | | context.setLineWidth(gaugeOption.width); |
| | | context.setStrokeStyle(series[0].color); |
| | | context.setLineCap('round'); |
| | |
| | | var radarOption = assign({}, { |
| | | gridColor: '#cccccc', |
| | | gridType: 'radar', |
| | | gridEval:1, |
| | | axisLabel:false, |
| | | axisLabelTofix:0, |
| | | labelColor:'#666666', |
| | | labelPointShow:false, |
| | | labelPointRadius:3, |
| | | labelPointColor:'#cccccc', |
| | | opacity: 0.2, |
| | | gridCount: 3, |
| | | border:false, |
| | | borderWidth:2 |
| | | borderWidth:2, |
| | | linearType: 'none', |
| | | customColor: [], |
| | | }, opts.extra.radar); |
| | | var coordinateAngle = getRadarCoordinateSeries(opts.categories.length); |
| | | var centerPosition = { |
| | |
| | | var yr = (opts.height - opts.area[0] - opts.area[2]) / 2 |
| | | var radius = Math.min(xr - (getMaxTextListLength(opts.categories, config.fontSize, context) + config.radarLabelTextMargin), yr - config.radarLabelTextMargin); |
| | | radius -= config.radarLabelTextMargin * opts.pix; |
| | | radius = radius < 10 ? 10 : radius; |
| | | // 画分割线 |
| | | context.beginPath(); |
| | | context.setLineWidth(1 * opts.pix); |
| | | context.setStrokeStyle(radarOption.gridColor); |
| | | coordinateAngle.forEach(function(angle) { |
| | | coordinateAngle.forEach(function(angle,index) { |
| | | var pos = convertCoordinateOrigin(radius * Math.cos(angle), radius * Math.sin(angle), centerPosition); |
| | | context.moveTo(centerPosition.x, centerPosition.y); |
| | | context.lineTo(pos.x, pos.y); |
| | | if (index % radarOption.gridEval == 0) { |
| | | context.lineTo(pos.x, pos.y); |
| | | } |
| | | }); |
| | | context.stroke(); |
| | | context.closePath(); |
| | |
| | | for (var i = 1; i <= radarOption.gridCount; i++) { |
| | | _loop(i); |
| | | } |
| | | radarOption.customColor = fillCustomColor(radarOption.linearType, radarOption.customColor, series, config); |
| | | var radarDataPoints = getRadarDataPoints(coordinateAngle, centerPosition, radius, series, opts, process); |
| | | radarDataPoints.forEach(function(eachSeries, seriesIndex) { |
| | | // 绘制区域数据 |
| | | context.beginPath(); |
| | | context.setLineWidth(radarOption.borderWidth * opts.pix); |
| | | context.setStrokeStyle(eachSeries.color); |
| | | context.setFillStyle(hexToRgb(eachSeries.color, radarOption.opacity)); |
| | | |
| | | var fillcolor = hexToRgb(eachSeries.color, radarOption.opacity); |
| | | if (radarOption.linearType == 'custom') { |
| | | var grd; |
| | | if(context.createCircularGradient){ |
| | | grd = context.createCircularGradient(centerPosition.x, centerPosition.y, radius) |
| | | }else{ |
| | | grd = context.createRadialGradient(centerPosition.x, centerPosition.y, 0,centerPosition.x, centerPosition.y, radius) |
| | | } |
| | | grd.addColorStop(0, hexToRgb(radarOption.customColor[series[seriesIndex].linearIndex], radarOption.opacity)) |
| | | grd.addColorStop(1, hexToRgb(eachSeries.color, radarOption.opacity)) |
| | | fillcolor = grd |
| | | } |
| | | |
| | | context.setFillStyle(fillcolor); |
| | | eachSeries.data.forEach(function(item, index) { |
| | | if (index === 0) { |
| | | context.moveTo(item.position.x, item.position.y); |
| | |
| | | drawPointShape(points, eachSeries.color, eachSeries.pointShape, context, opts); |
| | | } |
| | | }); |
| | | // 画刻度值 |
| | | if(radarOption.axisLabel === true){ |
| | | const maxData = Math.max(radarOption.max, Math.max.apply(null, dataCombine(series))); |
| | | const stepLength = radius / radarOption.gridCount; |
| | | const fontSize = opts.fontSize * opts.pix; |
| | | context.setFontSize(fontSize); |
| | | context.setFillStyle(opts.fontColor); |
| | | context.setTextAlign('left'); |
| | | for (var i = 0; i < radarOption.gridCount + 1; i++) { |
| | | let label = i * maxData / radarOption.gridCount; |
| | | label = label.toFixed(radarOption.axisLabelTofix); |
| | | context.fillText(String(label), centerPosition.x + 3 * opts.pix, centerPosition.y - i * stepLength + fontSize / 2); |
| | | } |
| | | } |
| | | |
| | | // draw label text |
| | | drawRadarLabel(coordinateAngle, radius, centerPosition, opts, config, context); |
| | | |
| | |
| | | }; |
| | | } |
| | | |
| | | function normalInt(min, max, iter) { |
| | | iter = iter == 0 ? 1 : iter; |
| | | var arr = []; |
| | | for (var i = 0; i < iter; i++) { |
| | | arr[i] = Math.random(); |
| | | }; |
| | | return Math.floor(arr.reduce(function(i, j) { |
| | | return i + j |
| | | }) / iter * (max - min)) + min; |
| | | }; |
| | | // 经纬度转墨卡托 |
| | | function lonlat2mercator(longitude, latitude) { |
| | | var mercator = Array(2); |
| | | var x = longitude * 20037508.34 / 180; |
| | | var y = Math.log(Math.tan((90 + latitude) * Math.PI / 360)) / (Math.PI / 180); |
| | | y = y * 20037508.34 / 180; |
| | | mercator[0] = x; |
| | | mercator[1] = y; |
| | | return mercator; |
| | | } |
| | | |
| | | function collisionNew(area, points, width, height) { |
| | | var isIn = false; |
| | | for (let i = 0; i < points.length; i++) { |
| | | if (points[i].area) { |
| | | if (area[3] < points[i].area[1] || area[0] > points[i].area[2] || area[1] > points[i].area[3] || area[2] < points[i].area[0]) { |
| | | if (area[0] < 0 || area[1] < 0 || area[2] > width || area[3] > height) { |
| | | isIn = true; |
| | | break; |
| | | } else { |
| | | isIn = false; |
| | | } |
| | | } else { |
| | | isIn = true; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | return isIn; |
| | | }; |
| | | // 墨卡托转经纬度 |
| | | function mercator2lonlat(longitude, latitude) { |
| | | var lonlat = Array(2) |
| | | var x = longitude / 20037508.34 * 180; |
| | | var y = latitude / 20037508.34 * 180; |
| | | y = 180 / Math.PI * (2 * Math.atan(Math.exp(y * Math.PI / 180)) - Math.PI / 2); |
| | | lonlat[0] = x; |
| | | lonlat[1] = y; |
| | | return lonlat; |
| | | } |
| | | |
| | | function getBoundingBox(data) { |
| | | var bounds = {},coords; |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | function drawMapDataPoints(series, opts, config, context) { |
| | | var mapOption = assign({}, { |
| | | border: true, |
| | | mercator: false, |
| | | borderWidth: 1, |
| | | active:true, |
| | | borderColor: '#666666', |
| | | fillOpacity: 0.6, |
| | | activeBorderColor: '#f04864', |
| | |
| | | context.beginPath(); |
| | | context.setLineWidth(mapOption.borderWidth * opts.pix); |
| | | context.setStrokeStyle(mapOption.borderColor); |
| | | context.setFillStyle(hexToRgb(series[i].color, mapOption.fillOpacity)); |
| | | if (opts.tooltip) { |
| | | context.setFillStyle(hexToRgb(series[i].color, series[i].fillOpacity||mapOption.fillOpacity)); |
| | | if (mapOption.active == true && opts.tooltip) { |
| | | if (opts.tooltip.index == i) { |
| | | context.setStrokeStyle(mapOption.activeBorderColor); |
| | | context.setFillStyle(hexToRgb(mapOption.activeFillColor, mapOption.activeFillOpacity)); |
| | |
| | | context.stroke(); |
| | | } |
| | | } |
| | | if (opts.dataLabel == true) { |
| | | } |
| | | if (opts.dataLabel == true) { |
| | | for (var i = 0; i < data.length; i++) { |
| | | var centerPoint = data[i].properties.centroid; |
| | | if (centerPoint) { |
| | | if (mapOption.mercator) { |
| | |
| | | } |
| | | point = coordinateToPoint(centerPoint[1], centerPoint[0], bounds, scale, xoffset, yoffset); |
| | | let fontSize = data[i].textSize * opts.pix || config.fontSize; |
| | | let fontColor = data[i].textColor || opts.fontColor; |
| | | if(mapOption.active && mapOption.activeTextColor && opts.tooltip && opts.tooltip.index == i){ |
| | | fontColor = mapOption.activeTextColor; |
| | | } |
| | | let text = data[i].properties.name; |
| | | context.beginPath(); |
| | | context.setFontSize(fontSize) |
| | | context.setFillStyle(data[i].textColor || opts.fontColor) |
| | | context.setFillStyle(fontColor) |
| | | context.fillText(text, point.x - measureText(text, fontSize, context) / 2, point.y + fontSize / 2); |
| | | context.closePath(); |
| | | context.stroke(); |
| | |
| | | drawToolTipBridge(opts, config, context, 1); |
| | | context.draw(); |
| | | } |
| | | |
| | | function normalInt(min, max, iter) { |
| | | iter = iter == 0 ? 1 : iter; |
| | | var arr = []; |
| | | for (var i = 0; i < iter; i++) { |
| | | arr[i] = Math.random(); |
| | | }; |
| | | return Math.floor(arr.reduce(function(i, j) { |
| | | return i + j |
| | | }) / iter * (max - min)) + min; |
| | | }; |
| | | |
| | | function collisionNew(area, points, width, height) { |
| | | var isIn = false; |
| | | for (let i = 0; i < points.length; i++) { |
| | | if (points[i].area) { |
| | | if (area[3] < points[i].area[1] || area[0] > points[i].area[2] || area[1] > points[i].area[3] || area[2] < points[i].area[0]) { |
| | | if (area[0] < 0 || area[1] < 0 || area[2] > width || area[3] > height) { |
| | | isIn = true; |
| | | break; |
| | | } else { |
| | | isIn = false; |
| | | } |
| | | } else { |
| | | isIn = true; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | return isIn; |
| | | }; |
| | | |
| | | function getWordCloudPoint(opts, type, context) { |
| | | let points = opts.series; |
| | |
| | | return points; |
| | | } |
| | | |
| | | |
| | | function drawWordCloudDataPoints(series, opts, config, context) { |
| | | let process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1; |
| | | let wordOption = assign({}, { |
| | |
| | | borderWidth: 2, |
| | | borderColor: '#FFFFFF', |
| | | fillOpacity: 1, |
| | | minSize: 0, |
| | | labelAlign: 'right', |
| | | linearType: 'none', |
| | | customColor: [], |
| | |
| | | }; |
| | | let activeWidth = funnelOption.activeWidth * opts.pix; |
| | | let radius = Math.min((opts.width - opts.area[1] - opts.area[3]) / 2 - activeWidth, (opts.height - opts.area[0] - opts.area[2]) / 2 - activeWidth); |
| | | series = getFunnelDataPoints(series, radius, funnelOption.type, eachSpacing, process); |
| | | let seriesNew = getFunnelDataPoints(series, radius, funnelOption, eachSpacing, process); |
| | | context.save(); |
| | | context.translate(centerPosition.x, centerPosition.y); |
| | | funnelOption.customColor = fillCustomColor(funnelOption.linearType, funnelOption.customColor, series, config); |
| | | if(funnelOption.type == 'pyramid'){ |
| | | for (let i = 0; i < series.length; i++) { |
| | | if (i == series.length -1) { |
| | | for (let i = 0; i < seriesNew.length; i++) { |
| | | if (i == seriesNew.length -1) { |
| | | if (opts.tooltip) { |
| | | if (opts.tooltip.index == i) { |
| | | context.beginPath(); |
| | | context.setFillStyle(hexToRgb(series[i].color, funnelOption.activeOpacity)); |
| | | context.setFillStyle(hexToRgb(seriesNew[i].color, funnelOption.activeOpacity)); |
| | | context.moveTo(-activeWidth, -eachSpacing); |
| | | context.lineTo(-series[i].radius - activeWidth, 0); |
| | | context.lineTo(series[i].radius + activeWidth, 0); |
| | | context.lineTo(-seriesNew[i].radius - activeWidth, 0); |
| | | context.lineTo(seriesNew[i].radius + activeWidth, 0); |
| | | context.lineTo(activeWidth, -eachSpacing); |
| | | context.lineTo(-activeWidth, -eachSpacing); |
| | | context.closePath(); |
| | | context.fill(); |
| | | } |
| | | } |
| | | series[i].funnelArea = [centerPosition.x - series[i].radius, centerPosition.y - eachSpacing * (i + 1), centerPosition.x + series[i].radius, centerPosition.y - eachSpacing * i]; |
| | | seriesNew[i].funnelArea = [centerPosition.x - seriesNew[i].radius, centerPosition.y - eachSpacing * (i + 1), centerPosition.x + seriesNew[i].radius, centerPosition.y - eachSpacing * i]; |
| | | context.beginPath(); |
| | | context.setLineWidth(funnelOption.borderWidth * opts.pix); |
| | | context.setStrokeStyle(funnelOption.borderColor); |
| | | var fillColor = hexToRgb(series[i].color, funnelOption.fillOpacity); |
| | | var fillColor = hexToRgb(seriesNew[i].color, funnelOption.fillOpacity); |
| | | if (funnelOption.linearType == 'custom') { |
| | | var grd = context.createLinearGradient(series[i].radius, -eachSpacing, -series[i].radius, -eachSpacing); |
| | | grd.addColorStop(0, hexToRgb(series[i].color, funnelOption.fillOpacity)); |
| | | grd.addColorStop(0.5, hexToRgb(funnelOption.customColor[series[i].linearIndex], funnelOption.fillOpacity)); |
| | | grd.addColorStop(1, hexToRgb(series[i].color, funnelOption.fillOpacity)); |
| | | var grd = context.createLinearGradient(seriesNew[i].radius, -eachSpacing, -seriesNew[i].radius, -eachSpacing); |
| | | grd.addColorStop(0, hexToRgb(seriesNew[i].color, funnelOption.fillOpacity)); |
| | | grd.addColorStop(0.5, hexToRgb(funnelOption.customColor[seriesNew[i].linearIndex], funnelOption.fillOpacity)); |
| | | grd.addColorStop(1, hexToRgb(seriesNew[i].color, funnelOption.fillOpacity)); |
| | | fillColor = grd |
| | | } |
| | | context.setFillStyle(fillColor); |
| | | context.moveTo(0, -eachSpacing); |
| | | context.lineTo(-series[i].radius, 0); |
| | | context.lineTo(series[i].radius, 0); |
| | | context.lineTo(-seriesNew[i].radius, 0); |
| | | context.lineTo(seriesNew[i].radius, 0); |
| | | context.lineTo(0, -eachSpacing); |
| | | context.closePath(); |
| | | context.fill(); |
| | |
| | | if (opts.tooltip) { |
| | | if (opts.tooltip.index == i) { |
| | | context.beginPath(); |
| | | context.setFillStyle(hexToRgb(series[i].color, funnelOption.activeOpacity)); |
| | | context.setFillStyle(hexToRgb(seriesNew[i].color, funnelOption.activeOpacity)); |
| | | context.moveTo(0, 0); |
| | | context.lineTo(-series[i].radius - activeWidth, 0); |
| | | context.lineTo(-series[i + 1].radius - activeWidth, -eachSpacing); |
| | | context.lineTo(series[i + 1].radius + activeWidth, -eachSpacing); |
| | | context.lineTo(series[i].radius + activeWidth, 0); |
| | | context.lineTo(-seriesNew[i].radius - activeWidth, 0); |
| | | context.lineTo(-seriesNew[i + 1].radius - activeWidth, -eachSpacing); |
| | | context.lineTo(seriesNew[i + 1].radius + activeWidth, -eachSpacing); |
| | | context.lineTo(seriesNew[i].radius + activeWidth, 0); |
| | | context.lineTo(0, 0); |
| | | context.closePath(); |
| | | context.fill(); |
| | | } |
| | | } |
| | | series[i].funnelArea = [centerPosition.x - series[i].radius, centerPosition.y - eachSpacing * (i + 1), centerPosition.x + series[i].radius, centerPosition.y - eachSpacing * i]; |
| | | seriesNew[i].funnelArea = [centerPosition.x - seriesNew[i].radius, centerPosition.y - eachSpacing * (i + 1), centerPosition.x + seriesNew[i].radius, centerPosition.y - eachSpacing * i]; |
| | | context.beginPath(); |
| | | context.setLineWidth(funnelOption.borderWidth * opts.pix); |
| | | context.setStrokeStyle(funnelOption.borderColor); |
| | | var fillColor = hexToRgb(series[i].color, funnelOption.fillOpacity); |
| | | var fillColor = hexToRgb(seriesNew[i].color, funnelOption.fillOpacity); |
| | | if (funnelOption.linearType == 'custom') { |
| | | var grd = context.createLinearGradient(series[i].radius, -eachSpacing, -series[i].radius, -eachSpacing); |
| | | grd.addColorStop(0, hexToRgb(series[i].color, funnelOption.fillOpacity)); |
| | | grd.addColorStop(0.5, hexToRgb(funnelOption.customColor[series[i].linearIndex], funnelOption.fillOpacity)); |
| | | grd.addColorStop(1, hexToRgb(series[i].color, funnelOption.fillOpacity)); |
| | | var grd = context.createLinearGradient(seriesNew[i].radius, -eachSpacing, -seriesNew[i].radius, -eachSpacing); |
| | | grd.addColorStop(0, hexToRgb(seriesNew[i].color, funnelOption.fillOpacity)); |
| | | grd.addColorStop(0.5, hexToRgb(funnelOption.customColor[seriesNew[i].linearIndex], funnelOption.fillOpacity)); |
| | | grd.addColorStop(1, hexToRgb(seriesNew[i].color, funnelOption.fillOpacity)); |
| | | fillColor = grd |
| | | } |
| | | context.setFillStyle(fillColor); |
| | | context.moveTo(0, 0); |
| | | context.lineTo(-series[i].radius, 0); |
| | | context.lineTo(-series[i + 1].radius, -eachSpacing); |
| | | context.lineTo(series[i + 1].radius, -eachSpacing); |
| | | context.lineTo(series[i].radius, 0); |
| | | context.lineTo(-seriesNew[i].radius, 0); |
| | | context.lineTo(-seriesNew[i + 1].radius, -eachSpacing); |
| | | context.lineTo(seriesNew[i + 1].radius, -eachSpacing); |
| | | context.lineTo(seriesNew[i].radius, 0); |
| | | context.lineTo(0, 0); |
| | | context.closePath(); |
| | | context.fill(); |
| | |
| | | context.translate(0, -eachSpacing) |
| | | } |
| | | }else{ |
| | | for (let i = 0; i < series.length; i++) { |
| | | if (i == 0) { |
| | | context.translate(0, - (seriesNew.length - 1) * eachSpacing); |
| | | for (let i = 0; i < seriesNew.length; i++) { |
| | | if (i == seriesNew.length - 1) { |
| | | if (opts.tooltip) { |
| | | if (opts.tooltip.index == i) { |
| | | context.beginPath(); |
| | | context.setFillStyle(hexToRgb(series[i].color, funnelOption.activeOpacity)); |
| | | context.moveTo(-activeWidth, 0); |
| | | context.lineTo(-series[i].radius - activeWidth, -eachSpacing); |
| | | context.lineTo(series[i].radius + activeWidth, -eachSpacing); |
| | | context.lineTo(activeWidth, 0); |
| | | context.lineTo(-activeWidth, 0); |
| | | context.setFillStyle(hexToRgb(seriesNew[i].color, funnelOption.activeOpacity)); |
| | | context.moveTo(-activeWidth - funnelOption.minSize/2, 0); |
| | | context.lineTo(-seriesNew[i].radius - activeWidth, -eachSpacing); |
| | | context.lineTo(seriesNew[i].radius + activeWidth, -eachSpacing); |
| | | context.lineTo(activeWidth + funnelOption.minSize/2, 0); |
| | | context.lineTo(-activeWidth - funnelOption.minSize/2, 0); |
| | | context.closePath(); |
| | | context.fill(); |
| | | } |
| | | } |
| | | series[i].funnelArea = [centerPosition.x - series[i].radius, centerPosition.y - eachSpacing, centerPosition.x + series[i].radius, centerPosition.y]; |
| | | seriesNew[i].funnelArea = [centerPosition.x - seriesNew[i].radius, centerPosition.y - eachSpacing, centerPosition.x + seriesNew[i].radius, centerPosition.y ]; |
| | | context.beginPath(); |
| | | context.setLineWidth(funnelOption.borderWidth * opts.pix); |
| | | context.setStrokeStyle(funnelOption.borderColor); |
| | | var fillColor = hexToRgb(series[i].color, funnelOption.fillOpacity); |
| | | var fillColor = hexToRgb(seriesNew[i].color, funnelOption.fillOpacity); |
| | | if (funnelOption.linearType == 'custom') { |
| | | var grd = context.createLinearGradient(series[i].radius, -eachSpacing, -series[i].radius, -eachSpacing); |
| | | grd.addColorStop(0, hexToRgb(series[i].color, funnelOption.fillOpacity)); |
| | | grd.addColorStop(0.5, hexToRgb(funnelOption.customColor[series[i].linearIndex], funnelOption.fillOpacity)); |
| | | grd.addColorStop(1, hexToRgb(series[i].color, funnelOption.fillOpacity)); |
| | | var grd = context.createLinearGradient(seriesNew[i].radius, -eachSpacing, -seriesNew[i].radius, -eachSpacing); |
| | | grd.addColorStop(0, hexToRgb(seriesNew[i].color, funnelOption.fillOpacity)); |
| | | grd.addColorStop(0.5, hexToRgb(funnelOption.customColor[seriesNew[i].linearIndex], funnelOption.fillOpacity)); |
| | | grd.addColorStop(1, hexToRgb(seriesNew[i].color, funnelOption.fillOpacity)); |
| | | fillColor = grd |
| | | } |
| | | context.setFillStyle(fillColor); |
| | | context.moveTo(0, 0); |
| | | context.lineTo(-series[i].radius, -eachSpacing); |
| | | context.lineTo(series[i].radius, -eachSpacing); |
| | | context.lineTo(-funnelOption.minSize/2, 0); |
| | | context.lineTo(-seriesNew[i].radius, -eachSpacing); |
| | | context.lineTo(seriesNew[i].radius, -eachSpacing); |
| | | context.lineTo(funnelOption.minSize/2, 0); |
| | | context.lineTo(0, 0); |
| | | context.closePath(); |
| | | context.fill(); |
| | |
| | | if (opts.tooltip) { |
| | | if (opts.tooltip.index == i) { |
| | | context.beginPath(); |
| | | context.setFillStyle(hexToRgb(series[i].color, funnelOption.activeOpacity)); |
| | | context.setFillStyle(hexToRgb(seriesNew[i].color, funnelOption.activeOpacity)); |
| | | context.moveTo(0, 0); |
| | | context.lineTo(-series[i - 1].radius - activeWidth, 0); |
| | | context.lineTo(-series[i].radius - activeWidth, -eachSpacing); |
| | | context.lineTo(series[i].radius + activeWidth, -eachSpacing); |
| | | context.lineTo(series[i - 1].radius + activeWidth, 0); |
| | | context.lineTo(-seriesNew[i + 1].radius - activeWidth, 0); |
| | | context.lineTo(-seriesNew[i].radius - activeWidth, -eachSpacing); |
| | | context.lineTo(seriesNew[i].radius + activeWidth, -eachSpacing); |
| | | context.lineTo(seriesNew[i + 1].radius + activeWidth, 0); |
| | | context.lineTo(0, 0); |
| | | context.closePath(); |
| | | context.fill(); |
| | | } |
| | | } |
| | | series[i].funnelArea = [centerPosition.x - series[i].radius, centerPosition.y - eachSpacing * (i + 1), centerPosition.x + series[i].radius, centerPosition.y - eachSpacing * i]; |
| | | seriesNew[i].funnelArea = [centerPosition.x - seriesNew[i].radius, centerPosition.y - eachSpacing * (seriesNew.length - i), centerPosition.x + seriesNew[i].radius, centerPosition.y - eachSpacing * (seriesNew.length - i - 1)]; |
| | | context.beginPath(); |
| | | context.setLineWidth(funnelOption.borderWidth * opts.pix); |
| | | context.setStrokeStyle(funnelOption.borderColor); |
| | | var fillColor = hexToRgb(series[i].color, funnelOption.fillOpacity); |
| | | var fillColor = hexToRgb(seriesNew[i].color, funnelOption.fillOpacity); |
| | | if (funnelOption.linearType == 'custom') { |
| | | var grd = context.createLinearGradient(series[i].radius, -eachSpacing, -series[i].radius, -eachSpacing); |
| | | grd.addColorStop(0, hexToRgb(series[i].color, funnelOption.fillOpacity)); |
| | | grd.addColorStop(0.5, hexToRgb(funnelOption.customColor[series[i].linearIndex], funnelOption.fillOpacity)); |
| | | grd.addColorStop(1, hexToRgb(series[i].color, funnelOption.fillOpacity)); |
| | | var grd = context.createLinearGradient(seriesNew[i].radius, -eachSpacing, -seriesNew[i].radius, -eachSpacing); |
| | | grd.addColorStop(0, hexToRgb(seriesNew[i].color, funnelOption.fillOpacity)); |
| | | grd.addColorStop(0.5, hexToRgb(funnelOption.customColor[seriesNew[i].linearIndex], funnelOption.fillOpacity)); |
| | | grd.addColorStop(1, hexToRgb(seriesNew[i].color, funnelOption.fillOpacity)); |
| | | fillColor = grd |
| | | } |
| | | context.setFillStyle(fillColor); |
| | | context.moveTo(0, 0); |
| | | context.lineTo(-series[i - 1].radius, 0); |
| | | context.lineTo(-series[i].radius, -eachSpacing); |
| | | context.lineTo(series[i].radius, -eachSpacing); |
| | | context.lineTo(series[i - 1].radius, 0); |
| | | context.lineTo(-seriesNew[i + 1].radius, 0); |
| | | context.lineTo(-seriesNew[i].radius, -eachSpacing); |
| | | context.lineTo(seriesNew[i].radius, -eachSpacing); |
| | | context.lineTo(seriesNew[i + 1].radius, 0); |
| | | context.lineTo(0, 0); |
| | | context.closePath(); |
| | | context.fill(); |
| | |
| | | context.stroke(); |
| | | } |
| | | } |
| | | context.translate(0, -eachSpacing) |
| | | context.translate(0, eachSpacing) |
| | | } |
| | | } |
| | | |
| | | context.restore(); |
| | | if (opts.dataLabel !== false && process === 1) { |
| | | drawFunnelText(series, opts, context, eachSpacing, funnelOption.labelAlign, activeWidth, centerPosition); |
| | | drawFunnelText(seriesNew, opts, context, eachSpacing, funnelOption.labelAlign, activeWidth, centerPosition); |
| | | } |
| | | if (process === 1) { |
| | | drawFunnelCenterText(seriesNew, opts, context, eachSpacing, funnelOption.labelAlign, activeWidth, centerPosition); |
| | | } |
| | | return { |
| | | center: centerPosition, |
| | | radius: radius, |
| | | series: series |
| | | series: seriesNew |
| | | }; |
| | | } |
| | | |
| | | function drawFunnelText(series, opts, context, eachSpacing, labelAlign, activeWidth, centerPosition) { |
| | | for (let i = 0; i < series.length; i++) { |
| | | let item = series[i]; |
| | | if(item.labelShow === false){ |
| | | continue; |
| | | } |
| | | let startX, endX, startY, fontSize; |
| | | let text = item.formatter ? item.formatter(item,i,series) : util.toFixed(item._proportion_ * 100) + '%'; |
| | | let text = item.formatter ? item.formatter(item,i,series,opts) : util.toFixed(item._proportion_ * 100) + '%'; |
| | | text = item.labelText ? item.labelText : text; |
| | | if (labelAlign == 'right') { |
| | | if(opts.extra.funnel.type === 'pyramid'){ |
| | | if (i == series.length -1) { |
| | | startX = (item.funnelArea[2] + centerPosition.x) / 2; |
| | | } else { |
| | | startX = (item.funnelArea[2] + series[i + 1].funnelArea[2]) / 2; |
| | | } |
| | | }else{ |
| | | if (i == 0) { |
| | | startX = (item.funnelArea[2] + centerPosition.x) / 2; |
| | | } else { |
| | | startX = (item.funnelArea[2] + series[i - 1].funnelArea[2]) / 2; |
| | | } |
| | | if (i == series.length -1) { |
| | | startX = (item.funnelArea[2] + centerPosition.x) / 2; |
| | | } else { |
| | | startX = (item.funnelArea[2] + series[i + 1].funnelArea[2]) / 2; |
| | | } |
| | | endX = startX + activeWidth * 2; |
| | | startY = item.funnelArea[1] + eachSpacing / 2; |
| | |
| | | context.closePath(); |
| | | context.beginPath(); |
| | | context.moveTo(endX, startY); |
| | | context.arc(endX, startY, 2, 0, 2 * Math.PI); |
| | | context.arc(endX, startY, 2 * opts.pix, 0, 2 * Math.PI); |
| | | context.closePath(); |
| | | context.fill(); |
| | | context.beginPath(); |
| | |
| | | context.closePath(); |
| | | context.stroke(); |
| | | context.closePath(); |
| | | } else { |
| | | if(opts.extra.funnel.type === 'pyramid'){ |
| | | if (i == series.length -1) { |
| | | startX = (item.funnelArea[0] + centerPosition.x) / 2; |
| | | } else { |
| | | startX = (item.funnelArea[0] + series[i + 1].funnelArea[0]) / 2; |
| | | } |
| | | }else{ |
| | | if (i == 0) { |
| | | startX = (item.funnelArea[0] + centerPosition.x) / 2; |
| | | } else { |
| | | startX = (item.funnelArea[0] + series[i - 1].funnelArea[0]) / 2; |
| | | } |
| | | } |
| | | if (labelAlign == 'left') { |
| | | if (i == series.length -1) { |
| | | startX = (item.funnelArea[0] + centerPosition.x) / 2; |
| | | } else { |
| | | startX = (item.funnelArea[0] + series[i + 1].funnelArea[0]) / 2; |
| | | } |
| | | endX = startX - activeWidth * 2; |
| | | startY = item.funnelArea[1] + eachSpacing / 2; |
| | |
| | | context.stroke(); |
| | | context.closePath(); |
| | | } |
| | | |
| | | } |
| | | } |
| | | |
| | | function drawFunnelCenterText(series, opts, context, eachSpacing, labelAlign, activeWidth, centerPosition) { |
| | | for (let i = 0; i < series.length; i++) { |
| | | let item = series[i]; |
| | | let startY, fontSize; |
| | | if (item.centerText) { |
| | | startY = item.funnelArea[1] + eachSpacing / 2; |
| | | fontSize = item.centerTextSize * opts.pix || opts.fontSize * opts.pix; |
| | | context.beginPath(); |
| | | context.setFontSize(fontSize); |
| | | context.setFillStyle(item.centerTextColor || "#FFFFFF"); |
| | | context.fillText(item.centerText, centerPosition.x - measureText(item.centerText, fontSize, context) / 2, startY + fontSize / 2 - 2); |
| | | context.closePath(); |
| | | context.stroke(); |
| | | context.closePath(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | function drawCanvas(opts, context) { |
| | | context.draw(); |
| | |
| | | var _this = this; |
| | | var series = opts.series; |
| | | //兼容ECharts饼图类数据格式 |
| | | if (type === 'pie' || type === 'ring' || type === 'rose' || type === 'funnel') { |
| | | if (type === 'pie' || type === 'ring' || type === 'mount' || type === 'rose' || type === 'funnel') { |
| | | series = fixPieSeries(series, opts, config); |
| | | } |
| | | var categories = opts.categories; |
| | | if (type === 'mount') { |
| | | categories = []; |
| | | for (let j = 0; j < series.length; j++) { |
| | | if(series[j].show !== false) categories.push(series[j].name) |
| | | } |
| | | opts.categories = categories; |
| | | } |
| | | series = fillSeries(series, opts, config); |
| | | var duration = opts.animation ? opts.duration : 0; |
| | | _this.animationInstance && _this.animationInstance.stop(); |
| | |
| | | |
| | | let _calYAxisData = {}, |
| | | yAxisWidth = 0; |
| | | if (opts.type === 'line' || opts.type === 'column' || opts.type === 'area' || opts.type === 'mix' || opts.type === 'candle' || opts.type === 'scatter' || opts.type === 'bubble' || opts.type === 'bar') { |
| | | if (opts.type === 'line' || opts.type === 'column'|| opts.type === 'mount' || opts.type === 'area' || opts.type === 'mix' || opts.type === 'candle' || opts.type === 'scatter' || opts.type === 'bubble' || opts.type === 'bar') { |
| | | _calYAxisData = calYAxisData(series, opts, config, context); |
| | | yAxisWidth = _calYAxisData.yAxisWidth; |
| | | //如果显示Y轴标题 |
| | |
| | | }; |
| | | } |
| | | } |
| | | |
| | | //计算右对齐偏移距离 |
| | | if (opts.enableScroll && opts.xAxis.scrollAlign == 'right' && opts._scrollDistance_ === undefined) { |
| | | let offsetLeft = 0, |
| | |
| | | let totalWidth = eachSpacing * (xAxisPoints.length - 1); |
| | | let screenWidth = endX - startX; |
| | | offsetLeft = screenWidth - totalWidth; |
| | | _this.scrollOption = { |
| | | currentOffset: offsetLeft, |
| | | startTouchX: offsetLeft, |
| | | distance: 0, |
| | | lastMoveTime: 0 |
| | | }; |
| | | _this.scrollOption.currentOffset = offsetLeft; |
| | | _this.scrollOption.startTouchX = offsetLeft; |
| | | _this.scrollOption.distance = 0; |
| | | _this.scrollOption.lastMoveTime = 0; |
| | | opts._scrollDistance_ = offsetLeft; |
| | | } |
| | | |
| | | if (type === 'pie' || type === 'ring' || type === 'rose') { |
| | | config._pieTextMaxLength_ = opts.dataLabel === false ? 0 : getPieTextMaxLength(seriesMA, config, context, opts); |
| | | } |
| | | |
| | | switch (type) { |
| | | case 'word': |
| | | this.animationInstance = new Animation({ |
| | |
| | | case 'map': |
| | | context.clearRect(0, 0, opts.width, opts.height); |
| | | drawMapDataPoints(series, opts, config, context); |
| | | setTimeout(()=>{ |
| | | this.uevent.trigger('renderComplete'); |
| | | },50) |
| | | break; |
| | | case 'funnel': |
| | | this.animationInstance = new Animation({ |
| | |
| | | } |
| | | }); |
| | | break; |
| | | case 'mount': |
| | | this.animationInstance = new Animation({ |
| | | timing: opts.timing, |
| | | duration: duration, |
| | | onProcess: function onProcess(process) { |
| | | context.clearRect(0, 0, opts.width, opts.height); |
| | | if (opts.rotate) { |
| | | contextRotate(context, opts); |
| | | } |
| | | drawYAxisGrid(categories, opts, config, context); |
| | | drawXAxis(categories, opts, config, context); |
| | | var _drawMountDataPoints = drawMountDataPoints(series, opts, config, context, process), |
| | | xAxisPoints = _drawMountDataPoints.xAxisPoints, |
| | | calPoints = _drawMountDataPoints.calPoints, |
| | | eachSpacing = _drawMountDataPoints.eachSpacing; |
| | | opts.chartData.xAxisPoints = xAxisPoints; |
| | | opts.chartData.calPoints = calPoints; |
| | | opts.chartData.eachSpacing = eachSpacing; |
| | | drawYAxis(series, opts, config, context); |
| | | if (opts.enableMarkLine !== false && process === 1) { |
| | | drawMarkLine(opts, config, context); |
| | | } |
| | | drawLegend(opts.series, opts, config, context, opts.chartData); |
| | | drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints); |
| | | drawCanvas(opts, context); |
| | | }, |
| | | onAnimationFinish: function onAnimationFinish() { |
| | | _this.uevent.trigger('renderComplete'); |
| | | } |
| | | }); |
| | | break; |
| | | case 'bar': |
| | | this.animationInstance = new Animation({ |
| | | timing: opts.timing, |
| | |
| | | }); |
| | | break; |
| | | case 'ring': |
| | | this.animationInstance = new Animation({ |
| | | timing: opts.timing, |
| | | duration: duration, |
| | | onProcess: function onProcess(process) { |
| | | context.clearRect(0, 0, opts.width, opts.height); |
| | | if (opts.rotate) { |
| | | contextRotate(context, opts); |
| | | } |
| | | opts.chartData.pieData = drawPieDataPoints(series, opts, config, context, process); |
| | | drawLegend(opts.series, opts, config, context, opts.chartData); |
| | | drawToolTipBridge(opts, config, context, process); |
| | | drawCanvas(opts, context); |
| | | }, |
| | | onAnimationFinish: function onAnimationFinish() { |
| | | _this.uevent.trigger('renderComplete'); |
| | | } |
| | | }); |
| | | break; |
| | | case 'pie': |
| | | this.animationInstance = new Animation({ |
| | | timing: opts.timing, |
| | |
| | | showTitle: false, |
| | | disabled: false, |
| | | disableGrid: false, |
| | | gridSet: 'number', |
| | | splitNumber: 5, |
| | | gridType: 'solid', |
| | | dashLength: 4 * opts.pix, |
| | |
| | | }, opts.yAxis); |
| | | opts.xAxis = assign({}, { |
| | | rotateLabel: false, |
| | | rotateAngle:45, |
| | | disabled: false, |
| | | disableGrid: false, |
| | | splitNumber: 5, |
| | |
| | | opts.rotate = opts.rotate ? true : false; |
| | | opts.canvas2d = opts.canvas2d ? true : false; |
| | | |
| | | let config$$1 = JSON.parse(JSON.stringify(config)); |
| | | let config$$1 = assign({}, config); |
| | | config$$1.color = opts.color ? opts.color : config$$1.color; |
| | | config$$1.yAxisTitleWidth = opts.yAxis.disabled !== true && opts.yAxis.title ? config$$1.yAxisTitleWidth : 0; |
| | | if (opts.type == 'pie') { |
| | | config$$1.pieChartLinePadding = opts.dataLabel === false ? 0 : opts.extra.pie.labelWidth * opts.pix || config$$1.pieChartLinePadding * opts.pix; |
| | | } |
| | |
| | | config$$1.pieChartLinePadding = opts.dataLabel === false ? 0 : opts.extra.rose.labelWidth * opts.pix || config$$1.pieChartLinePadding * opts.pix; |
| | | } |
| | | config$$1.pieChartTextPadding = opts.dataLabel === false ? 0 : config$$1.pieChartTextPadding * opts.pix; |
| | | config$$1.yAxisSplit = opts.yAxis.splitNumber ? opts.yAxis.splitNumber : config.yAxisSplit; |
| | | |
| | | //屏幕旋转 |
| | | config$$1.rotate = opts.rotate; |
| | |
| | | if (opts.enableScroll && opts.xAxis.scrollShow) { |
| | | config$$1.xAxisHeight += 6 * opts.pix; |
| | | } |
| | | config$$1.xAxisLineHeight = config.xAxisLineHeight * opts.pix; |
| | | config$$1.fontSize = opts.fontSize * opts.pix; |
| | | config$$1.titleFontSize = config.titleFontSize * opts.pix; |
| | | config$$1.subtitleFontSize = config.subtitleFontSize * opts.pix; |
| | | config$$1.toolTipPadding = config.toolTipPadding * opts.pix; |
| | | config$$1.toolTipLineHeight = config.toolTipLineHeight * opts.pix; |
| | | config$$1.columePadding = config.columePadding * opts.pix; |
| | | //this.context = opts.context ? opts.context : uni.createCanvasContext(opts.canvasId, opts.$this); |
| | | //v2.0版本后需要自行获取context并传入opts进行初始化,这么做是为了确保uCharts可以跨更多端使用,并保证了自定义组件this实例不被循环嵌套。如果您觉得不便请取消上面注释,采用v1.0版本的方式使用,对此给您带来的不便敬请谅解! |
| | | if(!opts.context){ |
| | | throw new Error('[uCharts] 未获取到context!注意:v2.0版本后,需要自行获取canvas的绘图上下文并传入opts.context!'); |
| | | } |
| | |
| | | let scrollPosition = data.scrollPosition || 'current'; |
| | | switch (scrollPosition) { |
| | | case 'current': |
| | | //this.opts._scrollDistance_ = this.scrollOption.currentOffset; |
| | | this.opts._scrollDistance_ = this.scrollOption.currentOffset; |
| | | break; |
| | | case 'left': |
| | | this.opts._scrollDistance_ = 0; |
| | |
| | | } |
| | | this.scrollOption = { |
| | | currentOffset: offsetLeft, |
| | | startTouchX: 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); |
| | | }; |
| | | |
| | | uCharts.prototype.dobuleZoom = function(e) { |
| | | if (this.opts.enableScroll !== true) { |
| | | console.log('[uCharts] 请启用滚动条后使用') |
| | | return; |
| | | } |
| | | const tcs = e.changedTouches; |
| | | if (tcs.length < 2) { |
| | | return; |
| | | } |
| | | for (var 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), |
| | | xAxisPoints = _getXAxisPoints0.xAxisPoints, |
| | | startX = _getXAxisPoints0.startX, |
| | | endX = _getXAxisPoints0.endX, |
| | | 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); |
| | | } |
| | | |
| | | uCharts.prototype.stopAnimation = function() { |
| | | this.animationInstance && this.animationInstance.stop(); |
| | |
| | | }; |
| | | } |
| | | } |
| | | drawCharts.call(this, opts.type, opts, this.config, this.context); |
| | | } |
| | | if (this.opts.type === 'mount') { |
| | | var index = option.index == undefined ? this.getCurrentDataIndex(e).index : option.index; |
| | | if (index > -1) { |
| | | var opts = assign({}, this.opts, {animation: false}); |
| | | var seriesData = assign({}, opts._series_[index]); |
| | | var textList = [{ |
| | | text: option.formatter ? option.formatter(seriesData, undefined, index, opts) : seriesData.name + ': ' + seriesData.data, |
| | | color: seriesData.color |
| | | }]; |
| | | var 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 currMoveTime = Date.now(); |
| | | let duration = currMoveTime - this.scrollOption.lastMoveTime; |
| | | if (duration < Math.floor(1000 / Limit)) return; |
| | | if (this.scrollOption.startTouchX == 0) return; |
| | | this.scrollOption.lastMoveTime = currMoveTime; |
| | | var touches = null; |
| | | if (e.changedTouches) { |
| | |
| | | distance = _scrollOption.distance; |
| | | this.scrollOption.currentOffset = currentOffset + distance; |
| | | this.scrollOption.distance = 0; |
| | | this.scrollOption.moveCount = 0; |
| | | } |
| | | }; |
| | | |