| | |
| | | 'use strict'; |
| | | |
| | | var config = { |
| | | version: 'v2.4.4-20221102', |
| | | version: 'v2.5.0-20230101', |
| | | yAxisWidth: 15, |
| | | xAxisHeight: 22, |
| | | xAxisTextPadding: 3, |
| | | padding: [10, 10, 10, 10], |
| | | pixelRatio: 1, |
| | | rotate: false, |
| | | fontSize: 13, |
| | | fontColor: '#666666', |
| | |
| | | pieChartTextPadding: 5, |
| | | titleFontSize: 20, |
| | | subtitleFontSize: 15, |
| | | toolTipPadding: 3, |
| | | toolTipBackground: '#000000', |
| | | toolTipOpacity: 0.7, |
| | | toolTipLineHeight: 20, |
| | | radarLabelTextMargin: 13, |
| | | }; |
| | | |
| | |
| | | seriesItem.style = item.style; |
| | | seriesItem.pointShape = item.pointShape; |
| | | seriesItem.disableLegend = item.disableLegend; |
| | | seriesItem.legendShape = item.legendShape; |
| | | seriesItem.name = item.name; |
| | | seriesItem.show = item.show; |
| | | seriesItem.data = item.formatter ? item.formatter(item.data[tmpindex]) : item.data[tmpindex]; |
| | |
| | | }; |
| | | return { |
| | | text: option.formatter ? option.formatter(item, titleText, index, opts) : item.name + ': ' + item.data, |
| | | color: item.color |
| | | color: item.color, |
| | | legendShape: opts.extra.tooltip.legendShape == 'auto'? item.legendShape : opts.extra.tooltip.legendShape |
| | | }; |
| | | }); |
| | | var offset = { |
| | |
| | | return { |
| | | text: option.formatter ? option.formatter(item, categories[index], index, opts) : item.name + ': ' + item.data, |
| | | color: item.color, |
| | | disableLegend: item.disableLegend ? true : false |
| | | disableLegend: item.disableLegend ? true : false, |
| | | legendShape: opts.extra.tooltip.legendShape == 'auto'? item.legendShape : opts.extra.tooltip.legendShape |
| | | }; |
| | | }); |
| | | textList = textList.filter(function(item) { |
| | |
| | | } |
| | | let text1 = { |
| | | text: '开盘:' + item.data[0], |
| | | color: color[0] |
| | | color: color[0], |
| | | legendShape: opts.extra.tooltip.legendShape == 'auto'? item.legendShape : opts.extra.tooltip.legendShape |
| | | }; |
| | | let text2 = { |
| | | text: '收盘:' + item.data[1], |
| | | color: color[1] |
| | | color: color[1], |
| | | legendShape: opts.extra.tooltip.legendShape == 'auto'? item.legendShape : opts.extra.tooltip.legendShape |
| | | }; |
| | | let text3 = { |
| | | text: '最低:' + item.data[2], |
| | | color: color[2] |
| | | color: color[2], |
| | | legendShape: opts.extra.tooltip.legendShape == 'auto'? item.legendShape : opts.extra.tooltip.legendShape |
| | | }; |
| | | let text4 = { |
| | | text: '最高:' + item.data[3], |
| | | color: color[3] |
| | | color: color[3], |
| | | legendShape: opts.extra.tooltip.legendShape == 'auto'? item.legendShape : opts.extra.tooltip.legendShape |
| | | }; |
| | | textList.push(text1, text2, text3, text4); |
| | | }); |
| | |
| | | function calCategoriesData(categories, opts, config, eachSpacing, context) { |
| | | var result = { |
| | | angle: 0, |
| | | xAxisHeight: config.xAxisHeight |
| | | xAxisHeight: opts.xAxis.lineHeight * opts.pix + opts.xAxis.marginTop * opts.pix |
| | | }; |
| | | var fontSize = opts.xAxis.fontSize * opts.pix || config.fontSize; |
| | | var fontSize = opts.xAxis.fontSize * opts.pix; |
| | | 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) { |
| | | 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; |
| | | } |
| | | let tempHeight = opts.xAxis.marginTop * opts.pix * 2 + Math.abs(maxTextLength * Math.sin(result.angle)) |
| | | tempHeight = tempHeight < fontSize + opts.xAxis.marginTop * opts.pix * 2 ? tempHeight + opts.xAxis.marginTop * opts.pix * 2 : tempHeight; |
| | | result.xAxisHeight = tempHeight; |
| | | } |
| | | if (opts.enableScroll && opts.xAxis.scrollShow) { |
| | | result.xAxisHeight += 6 * opts.pix; |
| | | } |
| | | if (opts.xAxis.disabled){ |
| | | result.xAxisHeight = 0; |
| | |
| | | }, opts.extra.bar); |
| | | var result = { |
| | | angle: 0, |
| | | xAxisHeight: config.xAxisHeight |
| | | xAxisHeight: opts.xAxis.lineHeight * opts.pix + opts.xAxis.marginTop * opts.pix |
| | | }; |
| | | result.ranges = getXAxisTextList(series, opts, config, columnstyle.type); |
| | | result.rangesFormat = result.ranges.map(function(item) { |
| | |
| | | // 计算X轴刻度的属性譬如每个刻度的间隔,刻度的起始点\结束点以及总长 |
| | | var eachSpacing = result.eachSpacing; |
| | | var textLength = xAxisScaleValues.map(function(item) { |
| | | return measureText(item, opts.xAxis.fontSize * opts.pix || config.fontSize, context); |
| | | return measureText(item, opts.xAxis.fontSize * opts.pix, context); |
| | | }); |
| | | // get max length of categories text |
| | | var maxTextLength = Math.max.apply(this, textLength); |
| | | // 如果刻度值文本内容过长,则将其逆时针旋转45° |
| | | if (maxTextLength + 2 * config.xAxisTextPadding > eachSpacing) { |
| | | result.angle = 45 * Math.PI / 180; |
| | | result.xAxisHeight = 2 * config.xAxisTextPadding + maxTextLength * Math.sin(result.angle); |
| | | } |
| | | if (opts.xAxis.disabled === true) { |
| | | result.xAxisHeight = 0; |
| | | } |
| | |
| | | } |
| | | |
| | | function getGaugeAxisPoints(categories, startAngle, endAngle) { |
| | | let totalAngle = startAngle - endAngle + 1; |
| | | let totalAngle; |
| | | if (endAngle < startAngle) { |
| | | totalAngle = 2 + endAngle - startAngle; |
| | | } else { |
| | | totalAngle = startAngle - endAngle; |
| | | } |
| | | let tempStartAngle = startAngle; |
| | | for (let i = 0; i < categories.length; i++) { |
| | | categories[i].value = categories[i].value === null ? 0 : categories[i].value; |
| | |
| | | } else { |
| | | item.color = gaugeOption.pointer.color; |
| | | } |
| | | let totalAngle = gaugeOption.startAngle - gaugeOption.endAngle + 1; |
| | | let totalAngle; |
| | | if (gaugeOption.endAngle < gaugeOption.startAngle) { |
| | | totalAngle = 2 + gaugeOption.endAngle - gaugeOption.startAngle; |
| | | } else { |
| | | totalAngle = gaugeOption.startAngle - gaugeOption.endAngle; |
| | | } |
| | | item._endAngle_ = totalAngle * item.data + gaugeOption.startAngle; |
| | | item._oldAngle_ = gaugeOption.oldAngle; |
| | | if (gaugeOption.oldAngle < gaugeOption.endAngle) { |
| | |
| | | return points; |
| | | } |
| | | |
| | | function getMountDataPoints(series, minRange, maxRange, xAxisPoints, eachSpacing, opts, mountOption) { |
| | | var process = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : 1; |
| | | function getLineDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, lineOption, process){ |
| | | var process = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : 1; |
| | | var boundaryGap = opts.xAxis.boundaryGap; |
| | | var points = []; |
| | | var validHeight = opts.height - opts.area[0] - opts.area[2]; |
| | | var validWidth = opts.width - opts.area[1] - opts.area[3]; |
| | | data.forEach(function(item, index) { |
| | | if (item === null) { |
| | | points.push(null); |
| | | } else { |
| | | var point = {}; |
| | | point.color = item.color; |
| | | if(lineOption.animation == 'vertical'){ |
| | | point.x = xAxisPoints[index]; |
| | | var value = item; |
| | | if (typeof item === 'object' && item !== null) { |
| | | if (item.constructor.toString().indexOf('Array') > -1) { |
| | | let xranges, xminRange, xmaxRange; |
| | | xranges = [].concat(opts.chartData.xAxisData.ranges); |
| | | xminRange = xranges.shift(); |
| | | xmaxRange = xranges.pop(); |
| | | value = item[1]; |
| | | point.x = opts.area[3] + validWidth * (item[0] - xminRange) / (xmaxRange - xminRange); |
| | | } else { |
| | | value = item.value; |
| | | } |
| | | } |
| | | if (boundaryGap == 'center') { |
| | | point.x += eachSpacing / 2; |
| | | } |
| | | var height = validHeight * (value - minRange) / (maxRange - minRange); |
| | | height *= process; |
| | | point.y = opts.height - height - opts.area[2]; |
| | | points.push(point); |
| | | }else{ |
| | | point.x = xAxisPoints[0] + eachSpacing * index * process; |
| | | var value = item; |
| | | if (boundaryGap == 'center') { |
| | | point.x += eachSpacing / 2; |
| | | } |
| | | var height = validHeight * (value - minRange) / (maxRange - minRange); |
| | | point.y = opts.height - height - opts.area[2]; |
| | | points.push(point); |
| | | } |
| | | } |
| | | }); |
| | | return points; |
| | | } |
| | | |
| | | function getColumnDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, zeroPoints, process){ |
| | | var process = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : 1; |
| | | var points = []; |
| | | var validHeight = opts.height - opts.area[0] - opts.area[2]; |
| | | var validWidth = opts.width - opts.area[1] - opts.area[3]; |
| | | data.forEach(function(item, index) { |
| | | if (item === null) { |
| | | points.push(null); |
| | | } else { |
| | | var point = {}; |
| | | point.color = item.color; |
| | | point.x = xAxisPoints[index]; |
| | | var value = item; |
| | | if (typeof item === 'object' && item !== null) { |
| | | if (item.constructor.toString().indexOf('Array') > -1) { |
| | | let xranges, xminRange, xmaxRange; |
| | | xranges = [].concat(opts.chartData.xAxisData.ranges); |
| | | xminRange = xranges.shift(); |
| | | xmaxRange = xranges.pop(); |
| | | value = item[1]; |
| | | point.x = opts.area[3] + validWidth * (item[0] - xminRange) / (xmaxRange - xminRange); |
| | | } else { |
| | | value = item.value; |
| | | } |
| | | } |
| | | point.x += eachSpacing / 2; |
| | | var height = validHeight * (value * process - minRange) / (maxRange - minRange); |
| | | point.y = opts.height - height - opts.area[2]; |
| | | points.push(point); |
| | | } |
| | | }); |
| | | return points; |
| | | } |
| | | |
| | | function getMountDataPoints(series, minRange, maxRange, xAxisPoints, eachSpacing, opts, mountOption, zeroPoints) { |
| | | var process = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : 1; |
| | | var points = []; |
| | | var validHeight = opts.height - opts.area[0] - opts.area[2]; |
| | | var validWidth = opts.width - opts.area[1] - opts.area[3]; |
| | |
| | | point.x = xAxisPoints[index]; |
| | | point.x += eachSpacing / 2; |
| | | var value = item.data; |
| | | var height = validHeight * (value - minRange) / (maxRange - minRange); |
| | | height *= process; |
| | | var height = validHeight * (value * process - minRange) / (maxRange - minRange); |
| | | point.y = opts.height - height - opts.area[2]; |
| | | point.value = value; |
| | | point.width = mountWidth; |
| | |
| | | var yAxisWidthArr = new Array(1); |
| | | if(opts.type === 'bar'){ |
| | | rangesArr[0] = opts.categories; |
| | | if(!opts.yAxis.formatter){ |
| | | opts.yAxis.formatter = (val,index,opts) => {return val + (opts.yAxis.unit || '')} |
| | | } |
| | | }else{ |
| | | if(!opts.yAxis.formatter){ |
| | | opts.yAxis.formatter = (val,index,opts) => {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,index) { |
| | | item = opts.yAxis.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; |
| | | if (opts.yAxis.disabled === true) { |
| | | yAxisWidthArr[0] = { |
| | | position: 'left', |
| | |
| | | position: 'left', |
| | | max: opts.yAxis.max, |
| | | min: opts.yAxis.min, |
| | | formatter: (val,index,opts) => {return val} |
| | | formatter: opts.yAxis.formatter |
| | | }; |
| | | 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, |
| | |
| | | context.stroke(); |
| | | } |
| | | |
| | | function drawActivePoint(points, color, shape, context, opts, option, seriesIndex) { |
| | | if(!opts.tooltip){ |
| | | return |
| | | } |
| | | if(opts.tooltip.group.length>0 && opts.tooltip.group.includes(seriesIndex) == false){ |
| | | return |
| | | } |
| | | var pointIndex = typeof opts.tooltip.index === 'number' ? opts.tooltip.index : opts.tooltip.index[opts.tooltip.group.indexOf(seriesIndex)]; |
| | | context.beginPath(); |
| | | if (option.activeType == 'hollow') { |
| | | context.setStrokeStyle(color); |
| | | context.setFillStyle(opts.background); |
| | | context.setLineWidth(2 * opts.pix); |
| | | } else { |
| | | context.setStrokeStyle("#ffffff"); |
| | | context.setFillStyle(color); |
| | | context.setLineWidth(1 * opts.pix); |
| | | } |
| | | if (shape === 'diamond') { |
| | | points.forEach(function(item, index) { |
| | | if (item !== null && pointIndex == index ) { |
| | | context.moveTo(item.x, item.y - 4.5); |
| | | context.lineTo(item.x - 4.5, item.y); |
| | | context.lineTo(item.x, item.y + 4.5); |
| | | context.lineTo(item.x + 4.5, item.y); |
| | | context.lineTo(item.x, item.y - 4.5); |
| | | } |
| | | }); |
| | | } else if (shape === 'circle') { |
| | | points.forEach(function(item, index) { |
| | | if (item !== null && pointIndex == index) { |
| | | context.moveTo(item.x + 2.5 * opts.pix, item.y); |
| | | context.arc(item.x, item.y, 3 * opts.pix, 0, 2 * Math.PI, false); |
| | | } |
| | | }); |
| | | } else if (shape === 'square') { |
| | | points.forEach(function(item, index) { |
| | | if (item !== null && pointIndex == index) { |
| | | context.moveTo(item.x - 3.5, item.y - 3.5); |
| | | context.rect(item.x - 3.5, item.y - 3.5, 7, 7); |
| | | } |
| | | }); |
| | | } else if (shape === 'triangle') { |
| | | points.forEach(function(item, index) { |
| | | if (item !== null && pointIndex == index) { |
| | | context.moveTo(item.x, item.y - 4.5); |
| | | context.lineTo(item.x - 4.5, item.y + 4.5); |
| | | context.lineTo(item.x + 4.5, item.y + 4.5); |
| | | context.lineTo(item.x, item.y - 4.5); |
| | | } |
| | | }); |
| | | } else if (shape === 'none') { |
| | | return; |
| | | } |
| | | context.closePath(); |
| | | context.fill(); |
| | | context.stroke(); |
| | | } |
| | | |
| | | function drawRingTitle(opts, config, context, center) { |
| | | var titlefontSize = opts.title.fontSize || config.titleFontSize; |
| | | var subtitlefontSize = opts.subtitle.fontSize || config.subtitleFontSize; |
| | |
| | | }); |
| | | } |
| | | |
| | | function drawMountPointText(points, series, config, context, opts) { |
| | | function drawColumePointText(points, series, config, context, opts) { |
| | | // 绘制数据文案 |
| | | var data = series.data; |
| | | var textOffset = series.textOffset ? series.textOffset : 0; |
| | | var Position = opts.extra.column.labelPosition; |
| | | points.forEach(function(item, index) { |
| | | if (item !== null) { |
| | | context.beginPath(); |
| | | var fontSize = series.textSize ? series.textSize * opts.pix : config.fontSize; |
| | | context.setFontSize(fontSize); |
| | | context.setFillStyle(series.textColor || opts.fontColor); |
| | | var value = data[index] |
| | | if (typeof data[index] === 'object' && data[index] !== null) { |
| | | if (data[index].constructor.toString().indexOf('Array')>-1) { |
| | | value = data[index][1]; |
| | | } else { |
| | | value = data[index].value |
| | | } |
| | | } |
| | | var formatVal = series.formatter ? series.formatter(value,index,series,opts) : value; |
| | | context.setTextAlign('center'); |
| | | var startY = item.y - 4 * opts.pix + textOffset * opts.pix; |
| | | if(item.y > series.zeroPoints){ |
| | | startY = item.y + textOffset * opts.pix + fontSize; |
| | | } |
| | | if(Position == 'insideTop'){ |
| | | startY = item.y + fontSize + textOffset * opts.pix; |
| | | if(item.y > series.zeroPoints){ |
| | | startY = item.y - textOffset * opts.pix - 4 * opts.pix; |
| | | } |
| | | } |
| | | if(Position == 'center'){ |
| | | startY = item.y + textOffset * opts.pix + (opts.height - opts.area[2] - item.y + fontSize)/2; |
| | | if(series.zeroPoints < opts.height - opts.area[2]){ |
| | | startY = item.y + textOffset * opts.pix + (series.zeroPoints - item.y + fontSize)/2; |
| | | } |
| | | if(item.y > series.zeroPoints){ |
| | | startY = item.y - textOffset * opts.pix - (item.y - series.zeroPoints - fontSize)/2; |
| | | } |
| | | if(opts.extra.column.type == 'stack'){ |
| | | startY = item.y + textOffset * opts.pix + (item.y0 - item.y + fontSize)/2; |
| | | } |
| | | } |
| | | if(Position == 'bottom'){ |
| | | startY = opts.height - opts.area[2] + textOffset * opts.pix - 4 * opts.pix; |
| | | if(series.zeroPoints < opts.height - opts.area[2]){ |
| | | startY = series.zeroPoints + textOffset * opts.pix - 4 * opts.pix; |
| | | } |
| | | if(item.y > series.zeroPoints){ |
| | | startY = series.zeroPoints - textOffset * opts.pix + fontSize + 2 * opts.pix; |
| | | } |
| | | if(opts.extra.column.type == 'stack'){ |
| | | startY = item.y0 + textOffset * opts.pix - 4 * opts.pix; |
| | | } |
| | | } |
| | | context.fillText(String(formatVal), item.x, startY); |
| | | context.closePath(); |
| | | context.stroke(); |
| | | context.setTextAlign('left'); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | function drawMountPointText(points, series, config, context, opts, zeroPoints) { |
| | | // 绘制数据文案 |
| | | var data = series.data; |
| | | var textOffset = series.textOffset ? series.textOffset : 0; |
| | | var Position = opts.extra.mount.labelPosition; |
| | | points.forEach(function(item, index) { |
| | | if (item !== null) { |
| | | context.beginPath(); |
| | |
| | | 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); |
| | | var startY = item.y - 4 * opts.pix + textOffset * opts.pix; |
| | | if(item.y > zeroPoints){ |
| | | startY = item.y + textOffset * opts.pix + fontSize; |
| | | } |
| | | context.fillText(String(formatVal), item.x, startY); |
| | | context.closePath(); |
| | | context.stroke(); |
| | | context.setTextAlign('left'); |
| | |
| | | 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 totalAngle; |
| | | if (gaugeOption.endAngle < gaugeOption.startAngle) { |
| | | totalAngle = 2 + gaugeOption.endAngle - gaugeOption.startAngle; |
| | | } else { |
| | | totalAngle = gaugeOption.startAngle - gaugeOption.endAngle; |
| | | } |
| | | let splitAngle = totalAngle / gaugeOption.splitLine.splitNumber; |
| | | let totalNumber = gaugeOption.endNumber - gaugeOption.startNumber; |
| | | let splitNumber = totalNumber / gaugeOption.splitLine.splitNumber; |
| | |
| | | context.closePath(); |
| | | context.fill(); |
| | | } |
| | | if(radarOption.labelShow === true){ |
| | | var pos = { |
| | | x: (radius + config.radarLabelTextMargin * opts.pix) * Math.cos(angle), |
| | | y: (radius + config.radarLabelTextMargin * opts.pix) * Math.sin(angle) |
| | |
| | | context.fillText(opts.categories[index] || '', startX, startY + config.fontSize / 2); |
| | | context.closePath(); |
| | | context.stroke(); |
| | | } |
| | | }); |
| | | |
| | | } |
| | |
| | | context.setFillStyle(hexToRgb(toolTipOption.labelBgColor || config.toolTipBackground, toolTipOption.labelBgOpacity || config.toolTipOpacity)); |
| | | context.setStrokeStyle(toolTipOption.labelBgColor || config.toolTipBackground); |
| | | context.setLineWidth(1 * opts.pix); |
| | | context.rect(textX - config.toolTipPadding, textY, textWidth + 2 * config.toolTipPadding, config.fontSize + 2 * config.toolTipPadding); |
| | | context.rect(textX - toolTipOption.boxPadding * opts.pix, textY, textWidth + 2 * toolTipOption.boxPadding * opts.pix, config.fontSize + 2 * toolTipOption.boxPadding * opts.pix); |
| | | context.closePath(); |
| | | context.stroke(); |
| | | context.fill(); |
| | | context.beginPath(); |
| | | context.setFontSize(config.fontSize); |
| | | context.setFillStyle(toolTipOption.labelFontColor || opts.fontColor); |
| | | context.fillText(String(labelText), textX, textY + config.toolTipPadding + config.fontSize); |
| | | context.fillText(String(labelText), textX, textY + toolTipOption.boxPadding * opts.pix + config.fontSize); |
| | | context.closePath(); |
| | | context.stroke(); |
| | | } |
| | |
| | | let item = assign({}, { |
| | | lineColor: '#DE4A42', |
| | | showLabel: false, |
| | | labelFontSize: 13, |
| | | labelPadding: 6, |
| | | labelFontColor: '#666666', |
| | | labelBgColor: '#DFE8FF', |
| | | labelBgOpacity: 0.8, |
| | |
| | | context.stroke(); |
| | | context.setLineDash([]); |
| | | if (item.showLabel) { |
| | | let fontSize = item.labelFontSize * opts.pix; |
| | | let labelText = item.labelText ? item.labelText : item.value; |
| | | context.setFontSize(config.fontSize); |
| | | let textWidth = measureText(labelText, config.fontSize, context); |
| | | let bgWidth = textWidth + config.toolTipPadding * 2; |
| | | context.setFontSize(fontSize); |
| | | let textWidth = measureText(labelText, fontSize, context); |
| | | let bgWidth = textWidth + item.labelPadding * opts.pix * 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; |
| | | let bgStartY = item.y - 0.5 * fontSize - item.labelPadding * opts.pix; |
| | | bgStartY += item.labelOffsetY; |
| | | let textX = bgStartX + config.toolTipPadding; |
| | | let textX = bgStartX + item.labelPadding * opts.pix; |
| | | 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, bgStartY, bgWidth, config.fontSize + 2 * config.toolTipPadding); |
| | | context.rect(bgStartX, bgStartY, bgWidth, fontSize + 2 * item.labelPadding * opts.pix); |
| | | context.closePath(); |
| | | context.stroke(); |
| | | context.fill(); |
| | | context.setFontSize(config.fontSize); |
| | | context.setFontSize(fontSize); |
| | | context.setTextAlign('left'); |
| | | context.setFillStyle(item.labelFontColor); |
| | | context.fillText(String(labelText), textX, bgStartY + config.fontSize + config.toolTipPadding/2); |
| | | context.fillText(String(labelText), textX, bgStartY + fontSize + item.labelPadding * opts.pix/2); |
| | | context.stroke(); |
| | | context.setTextAlign('left'); |
| | | } |
| | |
| | | context.stroke(); |
| | | context.setLineDash([]); |
| | | if (toolTipOption.yAxisLabel) { |
| | | let boxPadding = toolTipOption.boxPadding * opts.pix; |
| | | let labelText = calTooltipYAxisData(opts.tooltip.offset.y, opts.series, opts, config, eachSpacing); |
| | | let widthArr = opts.chartData.yAxisData.yAxisWidth; |
| | | let tStartLeft = opts.area[3]; |
| | | let tStartRight = opts.width - opts.area[1]; |
| | | for (let i = 0; i < labelText.length; i++) { |
| | | context.setFontSize(config.fontSize); |
| | | let textWidth = measureText(labelText[i], config.fontSize, context); |
| | | context.setFontSize(toolTipOption.fontSize * opts.pix); |
| | | let textWidth = measureText(labelText[i], toolTipOption.fontSize * opts.pix, context); |
| | | let bgStartX, bgEndX, bgWidth; |
| | | if (widthArr[i].position == 'left') { |
| | | bgStartX = tStartLeft - (textWidth + config.toolTipPadding * 2) - 2 * opts.pix; |
| | | bgEndX = Math.max(bgStartX, bgStartX + textWidth + config.toolTipPadding * 2); |
| | | bgStartX = tStartLeft - (textWidth + boxPadding * 2) - 2 * opts.pix; |
| | | bgEndX = Math.max(bgStartX, bgStartX + textWidth + boxPadding * 2); |
| | | } else { |
| | | bgStartX = tStartRight + 2 * opts.pix; |
| | | bgEndX = Math.max(bgStartX + widthArr[i].width, bgStartX + textWidth + config.toolTipPadding * 2); |
| | | bgEndX = Math.max(bgStartX + widthArr[i].width, bgStartX + textWidth + boxPadding * 2); |
| | | } |
| | | bgWidth = bgEndX - bgStartX; |
| | | let textX = bgStartX + (bgWidth - textWidth) / 2; |
| | |
| | | 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 - boxPadding, bgWidth, config.fontSize + 2 * boxPadding); |
| | | context.closePath(); |
| | | context.stroke(); |
| | | context.fill(); |
| | |
| | | borderWidth: 0, |
| | | borderRadius: 0, |
| | | borderOpacity: 0.7, |
| | | boxPadding: 3, |
| | | fontColor: '#FFFFFF', |
| | | fontSize: 13, |
| | | lineHeight: 20, |
| | | legendShow: true, |
| | | legendShape: 'auto', |
| | | splitLine: true, |
| | | }, opts.extra.tooltip); |
| | | if(toolTipOption.showCategory==true && opts.categories){ |
| | | textList.unshift({text:opts.categories[opts.tooltip.index],color:null}) |
| | | } |
| | | var legendWidth = 4 * opts.pix; |
| | | var fontSize = toolTipOption.fontSize * opts.pix; |
| | | var lineHeight = toolTipOption.lineHeight * opts.pix; |
| | | var boxPadding = toolTipOption.boxPadding * opts.pix; |
| | | var legendWidth = fontSize; |
| | | var legendMarginRight = 5 * opts.pix; |
| | | if(toolTipOption.legendShow == false){ |
| | | legendWidth = 0; |
| | | legendMarginRight = 0; |
| | | } |
| | | var arrowWidth = toolTipOption.showArrow ? 8 * opts.pix : 0; |
| | | var isOverRightBorder = false; |
| | | if (opts.type == 'line' || opts.type == 'mount' || opts.type == 'area' || opts.type == 'candle' || opts.type == 'mix') { |
| | |
| | | }, offset); |
| | | offset.y -= 8 * opts.pix; |
| | | var textWidth = textList.map(function(item) { |
| | | return measureText(item.text, config.fontSize, context); |
| | | return measureText(item.text, fontSize, context); |
| | | }); |
| | | var toolTipWidth = legendWidth + legendMarginRight + 4 * config.toolTipPadding + Math.max.apply(null, textWidth); |
| | | var toolTipHeight = 2 * config.toolTipPadding + textList.length * config.toolTipLineHeight; |
| | | var toolTipWidth = legendWidth + legendMarginRight + 4 * boxPadding + Math.max.apply(null, textWidth); |
| | | var toolTipHeight = 2 * boxPadding + textList.length * lineHeight; |
| | | if (toolTipOption.showBox == false) { |
| | | return |
| | | } |
| | |
| | | } |
| | | // draw background rect |
| | | context.beginPath(); |
| | | context.setFillStyle(hexToRgb(toolTipOption.bgColor || config.toolTipBackground, toolTipOption.bgOpacity || config.toolTipOpacity)); |
| | | context.setFillStyle(hexToRgb(toolTipOption.bgColor, toolTipOption.bgOpacity)); |
| | | context.setLineWidth(toolTipOption.borderWidth * opts.pix); |
| | | 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(toolTipWidth > offset.x){ |
| | | offset.x = opts.width + Math.abs(opts._scrollDistance_ || 0) + arrowWidth + (toolTipWidth - opts.width) |
| | | } |
| | | if (toolTipOption.showArrow) { |
| | |
| | | context.stroke(); |
| | | } |
| | | // draw legend |
| | | if(toolTipOption.legendShow){ |
| | | textList.forEach(function(item, index) { |
| | | if (item.color !== null) { |
| | | context.beginPath(); |
| | | context.setFillStyle(item.color); |
| | | var startX = offset.x + arrowWidth + 2 * config.toolTipPadding; |
| | | var startY = offset.y + (config.toolTipLineHeight - config.fontSize) / 2 + config.toolTipLineHeight * index + config.toolTipPadding + 1; |
| | | var startX = offset.x + arrowWidth + 2 * boxPadding; |
| | | var startY = offset.y + (lineHeight - fontSize) / 2 + lineHeight * index + boxPadding + 1; |
| | | if (isOverRightBorder) { |
| | | startX = offset.x - toolTipWidth - arrowWidth + 2 * config.toolTipPadding; |
| | | startX = offset.x - toolTipWidth - arrowWidth + 2 * boxPadding; |
| | | } |
| | | context.fillRect(startX, startY, legendWidth, config.fontSize); |
| | | // 圆形图例请注释上行,并把下行取消注释 |
| | | // context.arc(startX + legendWidth / 2 , startY + opts.fontSize / 2, 4 * opts.pix, 0, 2 * Math.PI); |
| | | switch (item.legendShape) { |
| | | case 'line': |
| | | context.moveTo(startX, startY + 0.5 * legendWidth - 2 * opts.pix); |
| | | context.fillRect(startX, startY + 0.5 * legendWidth - 2 * opts.pix, legendWidth, 4 * opts.pix); |
| | | break; |
| | | case 'triangle': |
| | | context.moveTo(startX + 7.5 * opts.pix, startY + 0.5 * legendWidth - 5 * opts.pix); |
| | | context.lineTo(startX + 2.5 * opts.pix, startY + 0.5 * legendWidth + 5 * opts.pix); |
| | | context.lineTo(startX + 12.5 * opts.pix, startY + 0.5 * legendWidth + 5 * opts.pix); |
| | | context.lineTo(startX + 7.5 * opts.pix, startY + 0.5 * legendWidth - 5 * opts.pix); |
| | | break; |
| | | case 'diamond': |
| | | context.moveTo(startX + 7.5 * opts.pix, startY + 0.5 * legendWidth - 5 * opts.pix); |
| | | context.lineTo(startX + 2.5 * opts.pix, startY + 0.5 * legendWidth); |
| | | context.lineTo(startX + 7.5 * opts.pix, startY + 0.5 * legendWidth + 5 * opts.pix); |
| | | context.lineTo(startX + 12.5 * opts.pix, startY + 0.5 * legendWidth); |
| | | context.lineTo(startX + 7.5 * opts.pix, startY + 0.5 * legendWidth - 5 * opts.pix); |
| | | break; |
| | | case 'circle': |
| | | context.moveTo(startX + 7.5 * opts.pix, startY + 0.5 * legendWidth); |
| | | context.arc(startX + 7.5 * opts.pix, startY + 0.5 * legendWidth, 5 * opts.pix, 0, 2 * Math.PI); |
| | | break; |
| | | case 'rect': |
| | | context.moveTo(startX, startY + 0.5 * legendWidth - 5 * opts.pix); |
| | | context.fillRect(startX, startY + 0.5 * legendWidth - 5 * opts.pix, 15 * opts.pix, 10 * opts.pix); |
| | | break; |
| | | case 'square': |
| | | context.moveTo(startX + 2 * opts.pix, startY + 0.5 * legendWidth - 5 * opts.pix); |
| | | context.fillRect(startX + 2 * opts.pix, startY + 0.5 * legendWidth - 5 * opts.pix, 10 * opts.pix, 10 * opts.pix); |
| | | break; |
| | | default: |
| | | context.moveTo(startX, startY + 0.5 * legendWidth - 5 * opts.pix); |
| | | context.fillRect(startX, startY + 0.5 * legendWidth - 5 * opts.pix, 15 * opts.pix, 10 * opts.pix); |
| | | } |
| | | context.closePath(); |
| | | context.fill(); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | // draw text list |
| | | textList.forEach(function(item, index) { |
| | | var startX = offset.x + arrowWidth + 2 * config.toolTipPadding + legendWidth + legendMarginRight; |
| | | var startX = offset.x + arrowWidth + 2 * boxPadding + legendWidth + legendMarginRight; |
| | | if (isOverRightBorder) { |
| | | startX = offset.x - toolTipWidth - arrowWidth + 2 * config.toolTipPadding + +legendWidth + legendMarginRight; |
| | | startX = offset.x - toolTipWidth - arrowWidth + 2 * boxPadding + legendWidth + legendMarginRight; |
| | | } |
| | | var startY = offset.y + (config.toolTipLineHeight - config.fontSize) / 2 + config.toolTipLineHeight * index + config.toolTipPadding; |
| | | var startY = offset.y + lineHeight * index + (lineHeight - fontSize)/2 - 1 + boxPadding + fontSize; |
| | | context.beginPath(); |
| | | context.setFontSize(config.fontSize); |
| | | context.setFontSize(fontSize); |
| | | context.setTextBaseline('normal'); |
| | | context.setFillStyle(toolTipOption.fontColor); |
| | | context.fillText(item.text, startX, startY + config.fontSize); |
| | | context.fillText(item.text, startX, startY); |
| | | context.closePath(); |
| | | context.stroke(); |
| | | }); |
| | |
| | | linearOpacity: 1, |
| | | customColor: [], |
| | | colorStop: 0, |
| | | labelPosition: 'outside' |
| | | }, opts.extra.column); |
| | | let calPoints = []; |
| | | context.save(); |
| | |
| | | ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]); |
| | | minRange = ranges.pop(); |
| | | maxRange = ranges.shift(); |
| | | |
| | | // 计算0轴坐标 |
| | | let spacingValid = opts.height - opts.area[0] - opts.area[2]; |
| | | let zeroHeight = spacingValid * (0 - minRange) / (maxRange - minRange); |
| | | let zeroPoints = opts.height - Math.round(zeroHeight) - opts.area[2]; |
| | | eachSeries.zeroPoints = zeroPoints; |
| | | var data = eachSeries.data; |
| | | switch (columnOption.type) { |
| | | case 'group': |
| | | var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process); |
| | | var points = getColumnDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, zeroPoints, process); |
| | | var tooltipPoints = getStackDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, seriesIndex, series, process); |
| | | calPoints.push(tooltipPoints); |
| | | points = fixColumeData(points, eachSpacing, series.length, seriesIndex, config, opts); |
| | |
| | | var fillColor = item.color || eachSeries.color |
| | | var strokeColor = item.color || eachSeries.color |
| | | if (columnOption.linearType !== 'none') { |
| | | var grd = context.createLinearGradient(startX, item.y, startX, opts.height - opts.area[2]); |
| | | var grd = context.createLinearGradient(startX, item.y, startX, zeroPoints); |
| | | //透明渐变 |
| | | if (columnOption.linearType == 'opacity') { |
| | | grd.addColorStop(0, hexToRgb(fillColor, columnOption.linearOpacity)); |
| | |
| | | // 圆角边框 |
| | | if ((columnOption.barBorderRadius && columnOption.barBorderRadius.length === 4) || columnOption.barBorderCircle === true) { |
| | | const left = startX; |
| | | const top = item.y; |
| | | const top = item.y > zeroPoints ? zeroPoints : item.y; |
| | | const width = item.width; |
| | | const height = opts.height - opts.area[2] - item.y; |
| | | const height = Math.abs(zeroPoints - item.y); |
| | | if (columnOption.barBorderCircle) { |
| | | columnOption.barBorderRadius = [width / 2, width / 2, 0, 0]; |
| | | } |
| | | if(item.y > zeroPoints){ |
| | | columnOption.barBorderRadius = [0, 0,width / 2, width / 2]; |
| | | } |
| | | let [r0, r1, r2, r3] = columnOption.barBorderRadius; |
| | | let minRadius = Math.min(width/2,height/2); |
| | |
| | | } 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.width, zeroPoints); |
| | | context.lineTo(startX, zeroPoints); |
| | | context.lineTo(startX, item.y); |
| | | context.setLineWidth(1) |
| | | context.setStrokeStyle(strokeColor); |
| | |
| | | const left = startX; |
| | | const top = item.y; |
| | | const width = item.width; |
| | | const height = opts.height - opts.area[2] - item.y; |
| | | const height = zeroPoints - item.y; |
| | | if (columnOption.barBorderCircle) { |
| | | columnOption.barBorderRadius = [width / 2, width / 2, 0, 0]; |
| | | } |
| | |
| | | }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.width, zeroPoints); |
| | | context.lineTo(startX, zeroPoints); |
| | | context.lineTo(startX, item.y); |
| | | context.fill(); |
| | | } |
| | |
| | | var data = eachSeries.data; |
| | | switch (columnOption.type) { |
| | | case 'group': |
| | | var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process); |
| | | var points = getColumnDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process); |
| | | points = fixColumeData(points, eachSpacing, series.length, seriesIndex, config, opts); |
| | | drawPointText(points, eachSeries, config, context, opts); |
| | | drawColumePointText(points, eachSeries, config, context, opts); |
| | | break; |
| | | case 'stack': |
| | | var points = getStackDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, seriesIndex, series, process); |
| | | drawPointText(points, eachSeries, config, context, opts); |
| | | drawColumePointText(points, eachSeries, config, context, opts); |
| | | break; |
| | | case 'meter': |
| | | var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process); |
| | | drawPointText(points, eachSeries, config, context, opts); |
| | | drawColumePointText(points, eachSeries, config, context, opts); |
| | | break; |
| | | } |
| | | }); |
| | |
| | | ranges = [].concat(opts.chartData.yAxisData.ranges[0]); |
| | | minRange = ranges.pop(); |
| | | maxRange = ranges.shift(); |
| | | var points = getMountDataPoints(series, minRange, maxRange, xAxisPoints, eachSpacing, opts, mountOption, process); |
| | | |
| | | // 计算0轴坐标 |
| | | let spacingValid = opts.height - opts.area[0] - opts.area[2]; |
| | | let zeroHeight = spacingValid * (0 - minRange) / (maxRange - minRange); |
| | | let zeroPoints = opts.height - Math.round(zeroHeight) - opts.area[2]; |
| | | |
| | | var points = getMountDataPoints(series, minRange, maxRange, xAxisPoints, eachSpacing, opts, mountOption, zeroPoints, process); |
| | | switch (mountOption.type) { |
| | | case 'bar': |
| | | for (let i = 0; i < points.length; i++) { |
| | |
| | | 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]); |
| | | var grd = context.createLinearGradient(startX, item.y, startX, zeroPoints); |
| | | //透明渐变 |
| | | if (mountOption.linearType == 'opacity') { |
| | | grd.addColorStop(0, hexToRgb(fillColor, mountOption.linearOpacity)); |
| | |
| | | // 圆角边框 |
| | | if ((mountOption.barBorderRadius && mountOption.barBorderRadius.length === 4) || mountOption.barBorderCircle === true) { |
| | | const left = startX; |
| | | const top = item.y; |
| | | const top = item.y > zeroPoints ? zeroPoints : item.y; |
| | | const width = item.width; |
| | | const height = opts.height - opts.area[2] - item.y - mountOption.borderWidth * opts.pix / 2; |
| | | const height = Math.abs(zeroPoints - item.y); |
| | | if (mountOption.barBorderCircle) { |
| | | mountOption.barBorderRadius = [width / 2, width / 2, 0, 0]; |
| | | } |
| | | if(item.y > zeroPoints){ |
| | | mountOption.barBorderRadius = [0, 0,width / 2, width / 2]; |
| | | } |
| | | let [r0, r1, r2, r3] = mountOption.barBorderRadius; |
| | | let minRadius = Math.min(width/2,height/2); |
| | |
| | | } 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.width, zeroPoints); |
| | | context.lineTo(startX, zeroPoints); |
| | | context.lineTo(startX, item.y); |
| | | } |
| | | context.setStrokeStyle(strokeColor); |
| | |
| | | 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]); |
| | | var grd = context.createLinearGradient(startX, item.y, startX, zeroPoints); |
| | | //透明渐变 |
| | | if (mountOption.linearType == 'opacity') { |
| | | grd.addColorStop(0, hexToRgb(fillColor, mountOption.linearOpacity)); |
| | |
| | | } |
| | | fillColor = grd |
| | | } |
| | | context.moveTo(startX, opts.height - opts.area[2]); |
| | | context.moveTo(startX, zeroPoints); |
| | | context.lineTo(item.x, item.y); |
| | | context.lineTo(startX + item.width, opts.height - opts.area[2]); |
| | | context.lineTo(startX + item.width, zeroPoints); |
| | | context.setStrokeStyle(strokeColor); |
| | | context.setFillStyle(fillColor); |
| | | if(mountOption.borderWidth > 0){ |
| | |
| | | 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]); |
| | | var grd = context.createLinearGradient(startX, item.y, startX, zeroPoints); |
| | | //透明渐变 |
| | | if (mountOption.linearType == 'opacity') { |
| | | grd.addColorStop(0, hexToRgb(fillColor, mountOption.linearOpacity)); |
| | |
| | | } |
| | | 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.moveTo(startX, zeroPoints); |
| | | context.bezierCurveTo(item.x - item.width/4, zeroPoints, 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, zeroPoints, startX + item.width, zeroPoints); |
| | | context.setStrokeStyle(strokeColor); |
| | | context.setFillStyle(fillColor); |
| | | if(mountOption.borderWidth > 0){ |
| | |
| | | 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]); |
| | | var grd = context.createLinearGradient(startX, item.y, startX, zeroPoints); |
| | | //透明渐变 |
| | | if (mountOption.linearType == 'opacity') { |
| | | grd.addColorStop(0, hexToRgb(fillColor, mountOption.linearOpacity)); |
| | |
| | | } |
| | | 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.moveTo(startX, zeroPoints); |
| | | context.quadraticCurveTo(item.x - 0, zeroPoints - height/4, item.x, item.y); |
| | | context.quadraticCurveTo(item.x + 0, zeroPoints - height/4, startX + item.width, zeroPoints) |
| | | context.setStrokeStyle(strokeColor); |
| | | context.setFillStyle(fillColor); |
| | | if(mountOption.borderWidth > 0){ |
| | |
| | | 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); |
| | | var points = getMountDataPoints(series, minRange, maxRange, xAxisPoints, eachSpacing, opts, mountOption, zeroPoints, process); |
| | | drawMountPointText(points, series, config, context, opts, zeroPoints); |
| | | } |
| | | context.restore(); |
| | | return { |
| | |
| | | opacity: 0.2, |
| | | addLine: false, |
| | | width: 2, |
| | | gradient: false |
| | | gradient: false, |
| | | activeType: 'none' |
| | | }, opts.extra.area); |
| | | let xAxisData = opts.chartData.xAxisData, |
| | | xAxisPoints = xAxisData.xAxisPoints, |
| | |
| | | } else { |
| | | let item = points[0]; |
| | | context.moveTo(item.x - eachSpacing / 2, item.y); |
| | | context.lineTo(item.x + eachSpacing / 2, item.y); |
| | | context.lineTo(item.x + eachSpacing / 2, endY); |
| | | context.lineTo(item.x - eachSpacing / 2, endY); |
| | | context.moveTo(item.x - eachSpacing / 2, item.y); |
| | | // context.lineTo(item.x + eachSpacing / 2, item.y); |
| | | // context.lineTo(item.x + eachSpacing / 2, endY); |
| | | // context.lineTo(item.x - eachSpacing / 2, endY); |
| | | // context.moveTo(item.x - eachSpacing / 2, item.y); |
| | | } |
| | | context.closePath(); |
| | | context.fill(); |
| | |
| | | context.setLineWidth(areaOption.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); |
| | | // context.arc(points[0].x, points[0].y, 1, 0, 2 * Math.PI); |
| | | } else { |
| | | context.moveTo(points[0].x, points[0].y); |
| | | let startPoint = 0; |
| | |
| | | if (opts.dataPointShape !== false) { |
| | | drawPointShape(points, eachSeries.color, eachSeries.pointShape, context, opts); |
| | | } |
| | | drawActivePoint(points, eachSeries.color, eachSeries.pointShape, context, opts, areaOption,seriesIndex); |
| | | }); |
| | | |
| | | if (opts.dataLabel !== false && process === 1) { |
| | |
| | | var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1; |
| | | var lineOption = assign({}, { |
| | | type: 'straight', |
| | | width: 2 |
| | | width: 2, |
| | | activeType: 'none', |
| | | linearType: 'none', |
| | | onShadow: false, |
| | | animation: 'vertical', |
| | | }, opts.extra.line); |
| | | lineOption.width *= opts.pix; |
| | | let xAxisData = opts.chartData.xAxisData, |
| | |
| | | rightSpace = leftSpace + (opts.xAxis.itemCount + 4) * eachSpacing; |
| | | } |
| | | series.forEach(function(eachSeries, seriesIndex) { |
| | | // 这段很神奇的代码用于解决ios16的setStrokeStyle失效的bug |
| | | context.beginPath(); |
| | | context.setStrokeStyle(eachSeries.color); |
| | | context.moveTo(-10000, -10000); |
| | | context.lineTo(-10001, -10001); |
| | | context.stroke(); |
| | | let ranges, minRange, maxRange; |
| | | ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]); |
| | | minRange = ranges.pop(); |
| | | maxRange = ranges.shift(); |
| | | var data = eachSeries.data; |
| | | var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process); |
| | | var points = getLineDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, lineOption, process); |
| | | calPoints.push(points); |
| | | var splitPointList = splitPoints(points,eachSeries); |
| | | if (eachSeries.lineType == 'dash') { |
| | |
| | | context.setLineDash([dashLength, dashLength]); |
| | | } |
| | | context.beginPath(); |
| | | context.setStrokeStyle(eachSeries.color); |
| | | var strokeColor = eachSeries.color; |
| | | if (lineOption.linearType !== 'none' && eachSeries.linearColor && eachSeries.linearColor.length > 0) { |
| | | var grd = context.createLinearGradient(opts.chartData.xAxisData.startX, opts.height/2, opts.chartData.xAxisData.endX, opts.height/2); |
| | | for (var i = 0; i < eachSeries.linearColor.length; i++) { |
| | | grd.addColorStop(eachSeries.linearColor[i][0], hexToRgb(eachSeries.linearColor[i][1], 1)); |
| | | } |
| | | strokeColor = grd |
| | | } |
| | | context.setStrokeStyle(strokeColor); |
| | | if (lineOption.onShadow == true && eachSeries.setShadow && eachSeries.setShadow.length > 0) { |
| | | context.setShadow(eachSeries.setShadow[0], eachSeries.setShadow[1], eachSeries.setShadow[2], eachSeries.setShadow[3]); |
| | | }else{ |
| | | context.setShadow(0, 0, 0, 'rgba(0,0,0,0)'); |
| | | } |
| | | context.setLineWidth(lineOption.width); |
| | | splitPointList.forEach(function(points, index) { |
| | | 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); |
| | | // context.arc(points[0].x, points[0].y, 1, 0, 2 * Math.PI); |
| | | } else { |
| | | context.moveTo(points[0].x, points[0].y); |
| | | let startPoint = 0; |
| | |
| | | if (opts.dataPointShape !== false) { |
| | | drawPointShape(points, eachSeries.color, eachSeries.pointShape, context, opts); |
| | | } |
| | | drawActivePoint(points, eachSeries.color, eachSeries.pointShape, context, opts, lineOption); |
| | | }); |
| | | if (opts.dataLabel !== false && process === 1) { |
| | | series.forEach(function(eachSeries, seriesIndex) { |
| | |
| | | } else { |
| | | let item = points[0]; |
| | | context.moveTo(item.x - eachSpacing / 2, item.y); |
| | | context.lineTo(item.x + eachSpacing / 2, item.y); |
| | | context.lineTo(item.x + eachSpacing / 2, endY); |
| | | context.lineTo(item.x - eachSpacing / 2, endY); |
| | | context.moveTo(item.x - eachSpacing / 2, item.y); |
| | | // context.lineTo(item.x + eachSpacing / 2, item.y); |
| | | // context.lineTo(item.x + eachSpacing / 2, endY); |
| | | // context.lineTo(item.x - eachSpacing / 2, endY); |
| | | // context.moveTo(item.x - eachSpacing / 2, item.y); |
| | | } |
| | | context.closePath(); |
| | | context.fill(); |
| | |
| | | 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); |
| | | // context.arc(points[0].x, points[0].y, 1, 0, 2 * Math.PI); |
| | | } else { |
| | | context.moveTo(points[0].x, points[0].y); |
| | | let startPoint = 0; |
| | |
| | | // 如果在主视图区域内 |
| | | 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])){ |
| | | if((truePoints - Math.abs(_scrollDistance_)) >= (opts.area[3] - 1) && (truePoints - Math.abs(_scrollDistance_)) <= (opts.width - opts.area[1] + 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.fillText(String(xitem), xAxisPoints[index] + offset, startY + opts.xAxis.marginTop * opts.pix + (opts.xAxis.lineHeight - opts.xAxis.fontSize) * opts.pix / 2 + opts.xAxis.fontSize * opts.pix); |
| | | 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])){ |
| | | if((truePoints - Math.abs(_scrollDistance_)) >= (opts.area[3] - 1) && (truePoints - Math.abs(_scrollDistance_)) <= (opts.width - opts.area[1] + 1)){ |
| | | context.save(); |
| | | context.beginPath(); |
| | | context.setFontSize(xAxisFontSize); |
| | |
| | | if (opts.xAxis.scrollShow) { |
| | | scrollHeight = 6 * opts.pix; |
| | | } |
| | | var offsetY = startY + 6 * opts.pix + xAxisFontSize - xAxisFontSize * Math.abs(Math.sin(config._xAxisTextAngle_)); |
| | | var offsetY = startY + opts.xAxis.marginTop * opts.pix + xAxisFontSize - xAxisFontSize * Math.abs(Math.sin(config._xAxisTextAngle_)); |
| | | if(opts.xAxis.rotateAngle < 0){ |
| | | offsetX -= xAxisFontSize / 2; |
| | | textWidth = 0; |
| | |
| | | } |
| | | } |
| | | context.restore(); |
| | | |
| | | //画X轴标题 |
| | | if (opts.xAxis.title) { |
| | | context.beginPath(); |
| | | context.setFontSize(opts.xAxis.titleFontSize * opts.pix); |
| | | context.setFillStyle(opts.xAxis.titleFontColor); |
| | | context.fillText(String(opts.xAxis.title), opts.width - opts.area[1] + opts.xAxis.titleOffsetX * opts.pix,opts.height - opts.area[2] + opts.xAxis.marginTop * opts.pix + (opts.xAxis.lineHeight - opts.xAxis.titleFontSize) * opts.pix / 2 + (opts.xAxis.titleFontSize + opts.xAxis.titleOffsetY) * opts.pix); |
| | | context.closePath(); |
| | | context.stroke(); |
| | | } |
| | | |
| | | //绘制X轴轴线 |
| | | if (opts.xAxis.axisLine) { |
| | | context.beginPath(); |
| | |
| | | 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; |
| | | if(radius < minRadius){ |
| | | radius = minRadius + 10; |
| | | } |
| | | series = getRoseDataPoints(series, roseOption.type, minRadius, radius, process); |
| | | var activeRadius = roseOption.activeRadius * opts.pix; |
| | | roseOption.customColor = fillCustomColor(roseOption.linearType, roseOption.customColor, series, config); |
| | |
| | | context.arc(centerPosition.x, centerPosition.y, innerRadius, gaugeOption.startAngle * Math.PI, gaugeOption.endAngle * Math.PI, false); |
| | | context.stroke(); |
| | | //## 第二步画刻度线 |
| | | totalAngle = gaugeOption.startAngle - gaugeOption.endAngle + 1; |
| | | if (gaugeOption.endAngle < gaugeOption.startAngle) { |
| | | totalAngle = 2 + gaugeOption.endAngle - gaugeOption.startAngle; |
| | | } else { |
| | | totalAngle = gaugeOption.startAngle - gaugeOption.endAngle; |
| | | } |
| | | let splitAngle = totalAngle / gaugeOption.splitLine.splitNumber; |
| | | let childAngle = totalAngle / gaugeOption.splitLine.splitNumber / gaugeOption.splitLine.childNumber; |
| | | let startX = -radius - gaugeOption.width * 0.5 - gaugeOption.splitLine.fixRadius; |
| | |
| | | } |
| | | context.save(); |
| | | //画刻度线 |
| | | totalAngle = gaugeOption.startAngle - gaugeOption.endAngle + 1; |
| | | if (gaugeOption.endAngle < gaugeOption.startAngle) { |
| | | totalAngle = 2 + gaugeOption.endAngle - gaugeOption.startAngle; |
| | | } else { |
| | | totalAngle = gaugeOption.startAngle - gaugeOption.endAngle; |
| | | } |
| | | let splitAngle = totalAngle / gaugeOption.splitLine.splitNumber; |
| | | let childAngle = totalAngle / gaugeOption.splitLine.splitNumber / gaugeOption.splitLine.childNumber; |
| | | let startX = -radius - gaugeOption.width * 0.5 - gaugeOption.splitLine.fixRadius; |
| | |
| | | gridEval:1, |
| | | axisLabel:false, |
| | | axisLabelTofix:0, |
| | | labelShow:true, |
| | | labelColor:'#666666', |
| | | labelPointShow:false, |
| | | labelPointRadius:3, |
| | |
| | | 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; |
| | | radius = radarOption.radius ? radarOption.radius : radius; |
| | | // 画分割线 |
| | | context.beginPath(); |
| | | context.setLineWidth(1 * opts.pix); |
| | |
| | | |
| | | |
| | | function drawCanvas(opts, context) { |
| | | context.save(); |
| | | context.translate(0, 0.5); |
| | | context.restore(); |
| | | context.draw(); |
| | | } |
| | | |
| | |
| | | disableGrid: false, |
| | | splitNumber: 5, |
| | | calibration:false, |
| | | fontColor: '#666666', |
| | | fontSize: 13, |
| | | lineHeight: 20, |
| | | marginTop: 0, |
| | | gridType: 'solid', |
| | | dashLength: 4, |
| | | scrollAlign: 'left', |
| | | boundaryGap: 'center', |
| | | axisLine: true, |
| | | axisLineColor: '#cccccc' |
| | | axisLineColor: '#cccccc', |
| | | titleFontSize: 13, |
| | | titleOffsetY: 0, |
| | | titleOffsetX: 0, |
| | | titleFontColor: '#666666' |
| | | }, opts.xAxis); |
| | | opts.xAxis.scrollPosition = opts.xAxis.scrollAlign; |
| | | opts.legend = assign({}, { |
| | |
| | | formatter: {}, |
| | | hiddenColor: '#CECECE' |
| | | }, opts.legend); |
| | | opts.extra = assign({}, opts.extra); |
| | | opts.extra = assign({ |
| | | tooltip:{ |
| | | legendShape: 'auto' |
| | | } |
| | | }, opts.extra); |
| | | opts.rotate = opts.rotate ? true : false; |
| | | opts.animation = opts.animation ? true : false; |
| | | opts.rotate = opts.rotate ? true : false; |
| | |
| | | //适配高分屏 |
| | | opts.padding = opts.padding ? opts.padding : config$$1.padding; |
| | | config$$1.yAxisWidth = config.yAxisWidth * opts.pix; |
| | | config$$1.xAxisHeight = config.xAxisHeight * opts.pix; |
| | | if (opts.enableScroll && opts.xAxis.scrollShow) { |
| | | config$$1.xAxisHeight += 6 * 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; |
| | | if(!opts.context){ |
| | | throw new Error('[uCharts] 未获取到context!注意:v2.0版本后,需要自行获取canvas的绘图上下文并传入opts.context!'); |
| | | } |
| | |
| | | } |
| | | this.context.setTextAlign = function(e) { |
| | | return this.textAlign = e; |
| | | } |
| | | this.context.setTextBaseline = function(e) { |
| | | return this.textBaseline = e; |
| | | } |
| | | this.context.setShadow = function(offsetX,offsetY,blur,color) { |
| | | this.shadowColor = color; |
| | | this.shadowOffsetX = offsetX; |
| | | this.shadowOffsetY = offsetY; |
| | | this.shadowBlur = blur; |
| | | } |
| | | this.context.draw = function() {} |
| | | } |
| | |
| | | textList: option.textList !== undefined ? option.textList : textList, |
| | | offset: option.offset !== undefined ? option.offset : offset, |
| | | option: option, |
| | | index: index |
| | | index: index, |
| | | group: current.group |
| | | }; |
| | | } |
| | | } |
| | |
| | | var seriesData = assign({}, opts._series_[index]); |
| | | var textList = [{ |
| | | text: option.formatter ? option.formatter(seriesData, undefined, index, opts) : seriesData.name + ': ' + seriesData.data, |
| | | color: seriesData.color |
| | | color: seriesData.color, |
| | | legendShape: this.opts.extra.tooltip.legendShape == 'auto' ? seriesData.legendShape : this.opts.extra.tooltip.legendShape |
| | | }]; |
| | | var offset = { |
| | | x: opts.chartData.calPoints[index].x, |
| | |
| | | var seriesData = assign({}, opts._series_[index]); |
| | | var textList = [{ |
| | | text: option.formatter ? option.formatter(seriesData, undefined, index, opts) : seriesData.name + ': ' + seriesData.data, |
| | | color: seriesData.color |
| | | color: seriesData.color, |
| | | legendShape: this.opts.extra.tooltip.legendShape == 'auto' ? seriesData.legendShape : this.opts.extra.tooltip.legendShape |
| | | }]; |
| | | var offset = { |
| | | x: _touches$.x, |
| | |
| | | seriesData.name = seriesData.properties.name |
| | | var textList = [{ |
| | | text: option.formatter ? option.formatter(seriesData, undefined, index, this.opts) : seriesData.name, |
| | | color: seriesData.color |
| | | color: seriesData.color, |
| | | legendShape: this.opts.extra.tooltip.legendShape == 'auto' ? seriesData.legendShape : this.opts.extra.tooltip.legendShape |
| | | }]; |
| | | var offset = { |
| | | x: _touches$.x, |
| | |
| | | var seriesData = assign({}, this.opts.series[index]); |
| | | var textList = [{ |
| | | text: option.formatter ? option.formatter(seriesData, undefined, index, this.opts) : seriesData.name, |
| | | color: seriesData.color |
| | | color: seriesData.color, |
| | | legendShape: this.opts.extra.tooltip.legendShape == 'auto' ? seriesData.legendShape : this.opts.extra.tooltip.legendShape |
| | | }]; |
| | | var offset = { |
| | | x: _touches$.x, |
| | |
| | | var textList = seriesData.map((item) => { |
| | | return { |
| | | text: option.formatter ? option.formatter(item, this.opts.categories[index], index, this.opts) : item.name + ': ' + item.data, |
| | | color: item.color |
| | | color: item.color, |
| | | legendShape: this.opts.extra.tooltip.legendShape == 'auto' ? item.legendShape : this.opts.extra.tooltip.legendShape |
| | | }; |
| | | }); |
| | | var offset = { |