uCharts简介,这是官方介绍,上面有全部的示例,我这篇只是取一部分实现的
需要引入u-charts.js,这个文件的代码我放在最后面,当然也可以官方Gitee下载
效果图

代码:
<template>
<view>
<canvas canvas-id="canvasLineA" id="canvasLineA" class="charts" @touchmove="moveLineA" @touchend="moveLineA"></canvas>
<!-- 画布,图表的HTML部分-->
</view>
</template>
<script>
import uCharts from '../../components/u-charts/u-charts.js'; //引入js文件
var _self; //用于全局使用this
var canvaLineA = null; //uCharts实例
export default {
data() {
return {
cWidth: '',
cHeight: '', //画布的宽高
data: {
//数据
categories: ["2012", "2013", "2014", "2015", "2016", "2017"],
series: [{
name: "成交量A",
data: [35, 8, 25, 37, 4, 20]
}, {
name: "成交量B",
data: [70, 40, 65, 100, 44, 68]
}, {
name: "成交量C",
data: [100, 80, 4, 150, 112, 132]
}]
}
}
},
onLoad() {
this.cWidth = uni.upx2px(750);
this.cHeight = uni.upx2px(500); //设置宽高
_self = this //声明this
_self.showLineA("canvasLineA", _self.data); //触发执行函数
},
methods: {
showLineA(canvasId, chartData) {
canvaLineA = new uCharts({
//这些配置项的意思看这:https://www.kancloud.cn/qiun/ucharts/1172125
$this: _self, //指针
canvasId: canvasId, //id
type: 'line', //类型
colors: ['#facc14', '#f04864', '#90ed7d'], //每一条的颜色
fontSize: 11, //字体大小
padding: [15, 15, 0, 15], //空白区域值
legend: {
//图例相关配置
show: true,
padding: 5,
lineHeight: 11,
margin: 0,
},
dataLabel: false, //显示数据标签内容值
categories: chartData.categories, //数据类别
series: chartData.series, //数据列表
xAxis: {
//X轴配置
gridColor: '#CCCCCC', //X轴网格颜色
gridType: 'dash', //X轴网格线型 'solid'为实线、'dash'为虚线`
dashLength: 8, //X轴网格为虚线时,单段虚线长度
},
yAxis: {
//y轴配置
gridType: 'dash',
gridColor: '#CCCCCC',
dashLength: 8,
},
width: _self.cWidth, //canvas宽度,单位为px
height: _self.cHeight, //canvas高度,单位为px
extra: {
//扩展配置
line: {
type: 'curve' //曲线 curve曲线,straight直线
}
}
});
},
moveLineA(e) {
canvaLineA.showToolTip(e, {
//详情框
format: function(item, category) {
return category + ' ' + item.name + ':' + item.data
}
});
}
}
}
</script>
<style>
.charts {
width: 750upx;
height: 500upx;
background-color: #FFFFFF;
}
</style>
u-charts.js
/*
* uCharts v1.9.5.20201214
* uni-app平台高性能跨全端图表,支持H5、APP、小程序(微信/支付宝/百度/头条/QQ/360)
* Copyright (c) 2019 QIUN秋云 https://www.ucharts.cn All rights reserved.
* Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
*
* uCharts官方网站
* https://www.uCharts.cn
*
* 开源地址:
* https://gitee.com/uCharts/uCharts
*
* uni-app插件市场地址:
* http://ext.dcloud.net.cn/plugin?id=271
*
*/
'use strict';
var config = {
yAxisWidth: 15,
yAxisSplit: 5,
xAxisHeight: 15,
xAxisLineHeight: 15,
legendHeight: 15,
yAxisTitleWidth: 15,
padding: [10, 10, 10, 10],
pixelRatio: 1,
rotate: false,
columePadding: 3,
fontSize: 13,
//dataPointShape: ['diamond', 'circle', 'triangle', 'rect'],
dataPointShape: ['circle', 'circle', 'circle', 'circle'],
colors: ['#1890ff', '#2fc25b', '#facc14', '#f04864', '#8543e0', '#90ed7d'],
pieChartLinePadding: 15,
pieChartTextPadding: 5,
xAxisTextPadding: 3,
titleColor: '#333333',
titleFontSize: 20,
subtitleColor: '#999999',
subtitleFontSize: 15,
toolTipPadding: 3,
toolTipBackground: '#000000',
toolTipOpacity: 0.7,
toolTipLineHeight: 20,
radarLabelTextMargin: 15,
gaugeLabelTextMargin: 15
};
let assign = function (target, ...varArgs) {
if (target == null) {
throw new TypeError('Cannot convert undefined or null to object');
}
if (!varArgs || varArgs.length <= 0) {
return target;
}
// 深度合并对象
function deepAssign(obj1, obj2) {
for (let key in obj2) {
obj1[key] = obj1[key] && obj1[key].toString() === "[object Object]" ?
deepAssign(obj1[key], obj2[key]) : obj1[key] = obj2[key];
}
return obj1;
}
varArgs.forEach(val => {
target = deepAssign(target, val);
});
return target;
};
var util = {
toFixed: function toFixed(num, limit) {
limit = limit || 2;
if (this.isFloat(num)) {
num = num.toFixed(limit);
}
return num;
},
isFloat: function isFloat(num) {
return num % 1 !== 0;
},
approximatelyEqual: function approximatelyEqual(num1, num2) {
return Math.abs(num1 - num2) < 1e-10;
},
isSameSign: function isSameSign(num1, num2) {
return Math.abs(num1) === num1 && Math.abs(num2) === num2 || Math.abs(num1) !== num1 && Math.abs(num2) !== num2;
},
isSameXCoordinateArea: function isSameXCoordinateArea(p1, p2) {
return this.isSameSign(p1.x, p2.x);
},
isCollision: function isCollision(obj1, obj2) {
obj1.end = {
};
obj1.end.x = obj1.start.x + obj1.width;
obj1.end.y = obj1.start.y - obj1.height;
obj2.end = {
};
obj2.end.x = obj2.start.x + obj2.width;
obj2.end.y = obj2.start.y - obj2.height;
var flag = obj2.start.x > obj1.end.x || obj2.end.x < obj1.start.x || obj2.end.y > obj1.start.y || obj2.start.y < obj1.end.y;
return !flag;
}
};
//兼容H5点击事件
function getH5Offset(e) {
e.mp = {
changedTouches: []
};
e.mp.changedTouches.push({
x: e.offsetX,
y: e.offsetY
});
return e;
}
// hex 转 rgba
function hexToRgb(hexValue, opc) {
var rgx = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
var hex = hexValue.replace(rgx, function(m, r, g, b) {
return r + r + g + g + b + b;
});
var rgb = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
var r = parseInt(rgb[1], 16);
var g = parseInt(rgb[2], 16);
var b = parseInt(rgb[3], 16);
return 'rgba(' + r + ',' + g + ',' + b + ',' + opc + ')';
}
function findRange(num, type, limit) {
if (isNaN(num)) {
throw new Error('[uCharts] unvalid series data!');
}
limit = limit || 10;
type = type ? type : 'upper';
var multiple = 1;
while (limit < 1) {
limit *= 10;
multiple *= 10;
}
if (type === 'upper') {
num = Math.ceil(num * multiple);
} else {
num = Math.floor(num * multiple);
}
while (num % limit !== 0) {
if (type === 'upper') {
num++;
} else {
num--;
}
}
return num / multiple;
}
function calCandleMA(dayArr, nameArr, colorArr, kdata) {
let seriesTemp = [];
for (let k = 0; k < dayArr.length; k++) {
let seriesItem = {
data: [],
name: nameArr[k],
color: colorArr[k]
};
for (let i = 0, len = kdata.length; i < len; i++) {
if (i < dayArr[k]) {
seriesItem.data.push(null);
continue;
}
let sum = 0;
for (let j = 0; j < dayArr[k]; j++) {
sum += kdata[i - j][1];
}
seriesItem.data.push(+(sum / dayArr[k]).toFixed(3));
}
seriesTemp.push(seriesItem);
}
return seriesTemp;
}
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);
var validDistance = distance;
if (distance >= 0) {
validDistance = 0;
self.event.trigger('scrollLeft');
} else if (Math.abs(distance) >= dataChartWidth - dataChartAreaWidth) {
validDistance = dataChartAreaWidth - dataChartWidth;
self.event.trigger('scrollRight');
}
return validDistance;
}
function isInAngleRange(angle, startAngle, endAngle) {
function adjust(angle) {
while (angle < 0) {
angle += 2 * Math.PI;
}
while (angle > 2 * Math.PI) {
angle -= 2 * Math.PI;
}
return angle;
}
angle = adjust(angle);
startAngle = adjust(startAngle);
endAngle = adjust(endAngle);
if (startAngle > endAngle) {
endAngle += 2 * Math.PI;
if (angle < startAngle) {
angle += 2 * Math.PI;
}
}
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 isNotMiddlePoint(points, i) {
if (points[i - 1] && points[i + 1]) {
return points[i].y >= Math.max(points[i - 1].y, points[i + 1].y) || points[i].y <= Math.min(points[i - 1].y,points[i + 1].y);
} else {
return false;
}
}
function isNotMiddlePointX(points, i) {
if (points[i - 1] && points[i + 1]) {
return points[i].x >= Math.max(points[i - 1].x, points[i + 1].x) || points[i].x <= Math.min(points[i - 1].x,points[i + 1].x);
} else {
return false;
}
}
var a = 0.2;
var b = 0.2;
var pAx = null;
var pAy = null;
var pBx = null;
var pBy = null;
if (i < 1) {
pAx = points[0].x + (points[1].x - points[0].x) * a;
pAy = points[0].y + (points[1].y - points[0].y) * a;
} else {
pAx = points[i].x + (points[i + 1].x - points[i - 1].x) * a;
pAy = points[i].y + (points[i + 1].y - points[i - 1].y) * a;
}
if (i > points.length - 3) {
var last = points.length - 1;
pBx = points[last].x - (points[last].x - points[last - 1].x) * b;
pBy = points[last].y - (points[last].y - points[last - 1].y) * b;
} else {
pBx = points[i + 1].x - (points[i + 2].x - points[i].x) * b;
pBy = points[i + 1].y - (points[i + 2].y - points[i].y) * b;
}
if (isNotMiddlePoint(points, i + 1)) {
pBy = points[i + 1].y;
}
if (isNotMiddlePoint(points, i)) {
pAy = points[i].y;
}
if (isNotMiddlePointX(points, i + 1)) {
pBx = points[i + 1].x;
}
if (isNotMiddlePointX(points, i)) {
pAx = points[i].x;
}
if (pAy >= Math.max(points[i].y, points[i + 1].y) || pAy <= Math.min(points[i].y, points[i + 1].y)) {
pAy = points[i].y;
}
if (pBy >= Math.max(points[i].y, points[i + 1].y) || pBy <= Math.min(points[i].y, points[i + 1].y)) {
pBy = points[i + 1].y;
}
if (pAx >= Math.max(points[i].x, points[i + 1].x) || pAx <= Math.min(points[i].x, points[i + 1].x)) {
pAx = points[i].x;
}
if (pBx >= Math.max(points[i].x, points[i + 1].x) || pBx <= Math.min(points[i].x, points[i + 1].x)) {
pBx = points[i + 1].x;
}
return {
ctrA: {
x: pAx,
y: pAy
},
ctrB: {
x: pBx,
y: pBy
}
};
}
function convertCoordinateOrigin(x, y, center) {
return {
x: center.x + x,
y: center.y - y
};
}
function avoidCollision(obj, target) {
if (target) {
// is collision test
while (util.isCollision(obj, target)) {
if (obj.start.x > 0) {
obj.start.y--;
} else if (obj.start.x < 0) {
obj.start.y++;
} else {
if (obj.start.y > 0) {
obj.start.y++;
} else {
obj.start.y--;
}
}
}
}
return obj;
}
function fillSeries(series, opts, config) {
var index = 0;
return series.map(function(item) {
if (!item.color) {
item.color = config.colors[index];
index = (index + 1) % config.colors.length;
}
if (!item.index) {
item.index = 0;
}
if (!item.type) {
item.type = opts.type;
}
if (typeof item.show == "undefined") {
item.show = true;
}
if (!item.type) {
item.type = opts.type;
}
if (!item.pointShape) {
item.pointShape = "circle";
}
if (!item.legendShape) {
switch (item.type) {
case 'line':
item.legendShape = "line";
break;
case 'column':
item.legendShape = "rect";
break;
case 'area':
item.legendShape = "triangle";
break;
default:
item.legendShape = "circle";
}
}
return item;
});
}
function getDataRange(minData, maxData) {
var limit = 0;
var range = maxData - minData;
if (range >= 10000) {
limit = 1000;
} else if (range >= 1000) {
limit = 100;
} else if (range >= 100) {
limit = 10;
} else if (range >= 10) {
limit = 5;
} else if (range >= 1) {
limit = 1;
} else if (range >= 0.1) {
limit = 0.1;
} else if (range >= 0.01) {
limit = 0.01;
} else if (range >= 0.001) {
limit = 0.001;
} else if (range >= 0.0001) {
limit = 0.0001;
} else if (range >= 0.00001) {
limit = 0.00001;
} else {
limit = 0.000001;
}
return {
minRange: findRange(minData, 'lower', limit),
maxRange: findRange(maxData, 'upper', limit)
};
}
function measureText(text) {
var fontSize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : config.fontSize;
text = String(text);
var text = text.split('');
var width = 0;
for (let i = 0; i < text.length; i++) {
let item = text[i];
if (/[a-zA-Z]/.test(item)) {
width += 7;
} else if (/[0-9]/.test(item)) {
width += 5.5;
} else if (/\./.test(item)) {
width += 2.7;
} else if (/-/.test(item)) {
width += 3.25;
} else if (/[\u4e00-\u9fa5]/.test(item)) {
width += 10;
} else if (/\(|\)/.test(item)) {
width += 3.73;
} else if (/\s/.test(item)) {
width += 2.5;
} else if (/%/.test(item)) {
width += 8;
} else {
width += 10;
}
}
return width * fontSize / 10;
}
function dataCombine(series) {
return series.reduce(function(a, b) {
return (a.data ? a.data : a).concat(b.data);
}, []);
}
function dataCombineStack(series, len) {
var sum = new Array(len);
for (var j = 0; j < sum.length; j++) {
sum[j] = 0;
}
for (var i = 0; i < series.length; i++) {
for (var j = 0; j < sum.length; j++) {
sum[j] += series[i].data[j];
}
}
return series.reduce(function(a, b) {
return (a.data ? a.data : a).concat(b.data).concat(sum);
}, []);
}
function getTouches(touches, opts, e) {
let x, y;
if (touches.clientX) {
if (opts.rotate) {
y = opts.height - touches.clientX * opts.pixelRatio;
x = (touches.pageY - e.currentTarget.offsetTop - (opts.height / opts.pixelRatio / 2) * (opts.pixelRatio - 1)) * opts.pixelRatio;
} else {
x = touches.clientX * opts.pixelRatio;
y = (touches.pageY - e.currentTarget.offsetTop - (opts.height / opts.pixelRatio / 2) * (opts.pixelRatio - 1)) * opts.pixelRatio;
}
} else {
if (opts.rotate) {
y = opts.height - touches.x * opts.pixelRatio;
x = touches.y * opts.pixelRatio;
} else {
x = touches.x * opts.pixelRatio;
y = touches.y * opts.pixelRatio;
}
}
return {
x: x,
y: y
}
}
function getSeriesDataItem(series, index) {
var data = [];
for (let i = 0; i < series.length; i++) {
let item = series[i];
if (item.data[index] !== null && typeof item.data[index] !== 'undefined' && item.show) {
let seriesItem = {
};
seriesItem.color = item.color;
seriesItem.type = item.type;
seriesItem.style = item.style;
seriesItem.pointShape = item.pointShape;
seriesItem.disableLegend = item.disableLegend;
seriesItem.name = item.name;
seriesItem.show = item.show;
seriesItem.data = item.format ? item.format(item.data[index]) : item.data[index];
data.push(seriesItem);
}
}
return data;
}
function getMaxTextListLength(list) {
var lengthList = list.map(function(item) {
return measureText(item);
});
return Math.max.apply(null, lengthList);
}
function getRadarCoordinateSeries(length) {
var eachAngle = 2 * Math.PI / length;
var CoordinateSeries = [];
for (var i = 0; i < length; i++) {
CoordinateSeries.push(eachAngle * i);
}
return CoordinateSeries.map(function(item) {
return -1 * item + Math.PI / 2;
});
}
function getToolTipData(seriesData, calPoints, index, categories) {
var option = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {
};
var textList = seriesData.map(function(item) {
let titleText=[];
if(categories){
titleText=categories;
}else{
titleText=item.data;
}
return {
text: option.format ? option.format(item, titleText[index]) : item.name + ': ' + item.data,
color: item.color
};
});
var validCalPoints = [];
var offset = {
x: 0,
y: 0
};
for (let i = 0; i < calPoints.length; i++) {
let points = calPoints[i];
if (typeof points[index] !== 'undefined' && points[index] !== null) {
validCalPoints.push(points[index]);
}
}
for (let i = 0; i < validCalPoints.length; i++) {
let item = validCalPoints[i];
offset.x = Math.round(item.x);
offset.y += item.y;
}
offset.y /= validCalPoints.length;
return {
textList: textList,
offset: offset
};
}
function getMixToolTipData(seriesData, calPoints, index, categories) {
var option = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {
};
var textList = seriesData.map(function(item) {
return {
text: option.format ? option.format(item, categories[index]) : item.name + ': ' + item.data,
color: item.color,
disableLegend: item.disableLegend ? true : false
};
});
textList = textList.filter(function(item) {
if (item.disableLegend !== true) {
return item;
}
});
var validCalPoints = [];
var offset = {
x: 0,
y: 0
};
for (let i = 0; i < calPoints.length; i++) {
let points = calPoints[i];
if (typeof points[index] !== 'undefined' && points[index] !== null) {
validCalPoints.push(points[index]);
}
}
for (let i = 0; i < validCalPoints.length; i++) {
let item = validCalPoints[i];
offset.x = Math.round(item.x);
offset.y += item.y;
}
offset.y /= validCalPoints.length;
return {
textList: textList,
offset: offset
};
}
function getCandleToolTipData(series, seriesData, calPoints, index, categories, extra) {
var option = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : {
};
let upColor = extra.color.upFill;
let downColor = extra.color.downFill;
//颜色顺序为开盘,收盘,最低,最高
let color = [upColor, upColor, downColor, upColor];
var textList = [];
let text0 = {
text: categories[index],
color: null
};
textList.push(text0);
seriesData.map(function(item) {
if (index == 0) {
if(item.data[1] - item.data[0] < 0){
color[1] = downColor;
}else{
color[1] = upColor;
}
} else {
if (item.data[0] < series[index - 1][1]) {
color[0] = downColor;
}
if (item.data[1] < item.data[0]) {
color[1] = downColor;
}
if (item.data[2] > series[index - 1][1]) {
color[2] = upColor;
}
if (item.data[3] < series[index - 1][1]) {
color[3] = downColor;
}
}
let text1 = {
text: '开盘:' + item.data[0],
color: color[0]
};
let text2 = {
text: '收盘:' + item.data[1],
color: color[1]
};
let text3 = {
text: '最低:' + item.data[2],
color: color[2]
};
let text4 = {
text: '最高:' + item.data[3],
color: color[3]
};
textList.push(text1, text2, text3, text4);
});
var validCalPoints = [];
var offset = {
x: 0,
y: 0
};
for (let i = 0; i < calPoints.length; i++) {
let points = calPoints[i];
if (typeof points[index] !== 'undefined' && points[index] !== null) {
validCalPoints.push(points[index]);
}
}
offset.x = Math.round(validCalPoints[0][0].x);
return {
textList: textList,
offset: offset
};
}
function filterSeries(series) {
let tempSeries = [];
for (let i = 0; i < series.length; i++) {
if (series[i].show == true) {
tempSeries.push(series[i])
}
}
return tempSeries;
}
function findCurrentIndex(currentPoints, calPoints, opts, config) {
var offset = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;
var currentIndex = -1;
var spacing = opts.chartData.eachSpacing/2;
let xAxisPoints=[];
if(calPoints.length>0){
for(let i=1;i<opts.chartData.xAxisPoints.length;i++){
xAxisPoints.push(opts.chartData.xAxisPoints[i]-spacing)
}
if((opts.type=='line' || opts.type=='area') && opts.xAxis.boundaryGap=='justify'){
spacing = opts.chartData.eachSpacing/2;
}
if(!opts.categories){
spacing=0
}
if (isInExactChartArea(currentPoints, opts, config)) {
xAxisPoints.forEach(function(item, index) {
if (currentPoints.x + offset + spacing > item) {
currentIndex = index;
}
});
}
}
return currentIndex;
}
function findLegendIndex(currentPoints, legendData, opts) {
let currentIndex = -1;
if (isInExactLegendArea(currentPoints, legendData.area)) {
let points = legendData.points;
let index = -1;
for (let i = 0, len = points.length; i < len; i++) {
let item = points[i];
for (let j = 0; j < item.length; j++) {
index += 1;
let area = item[j]['area'];
if (currentPoints.x > area[0] && currentPoints.x < area[2] && currentPoints.y > area[1] && currentPoints.y < area[3]) {
currentIndex = index;
break;
}
}
}
return currentIndex;
}
return currentIndex;
}
function isInExactLegendArea(currentPoints, area) {
return currentPoints.x > area.start.x && currentPoints.x < area.end.x && currentPoints.y > area.start.y &&
currentPoints.y < area.end.y;
}
function isInExactChartArea(currentPoints, opts, config) {
return currentPoints.x <= opts.width - opts.area[1] + 10 && currentPoints.x >= opts.area[3] -10 && currentPoints.y >= opts.area[0] && currentPoints.y <= opts.height - opts.area[2];
}
function findRadarChartCurrentIndex(currentPoints, radarData, count) {
var eachAngleArea = 2 * Math.PI / count;
var currentIndex = -1;
if (isInExactPieChartArea(currentPoints, radarData.center, radarData.radius)) {
var fixAngle = function fixAngle(angle) {
if (angle < 0) {
angle += 2 * Math.PI;
}
if (angle > 2 * Math.PI) {
angle -= 2 * Math.PI;
}
return angle;
};
var angle = Math.atan2(radarData.center.y - currentPoints.y, currentPoints.x - radarData.center.x);
angle = -1 * angle;
if (angle < 0) {
angle += 2 * Math.PI;
}
var angleList = radarData.angleList.map(function(item) {
item = fixAngle(-1 * item);
return item;
});
angleList.forEach(function(item, index) {
var rangeStart = fixAngle(item - eachAngleArea / 2);
var rangeEnd = fixAngle(item + eachAngleArea / 2);
if (rangeEnd < rangeStart) {
rangeEnd += 2 * Math.PI;
}
if (angle >= rangeStart && angle <= rangeEnd || angle + 2 * Math.PI >= rangeStart && angle + 2 * Math.PI <=
rangeEnd) {
currentIndex = index;
}
});
}
return currentIndex;
}
function findFunnelChartCurrentIndex(currentPoints, funnelData) {
var currentIndex = -1;
for (var i = 0, len = funnelData.series.length; i < len; i++) {
var item = funnelData.series[i];
if (currentPoints.x > item.funnelArea[0] && currentPoints.x < item.funnelArea[2] && currentPoints.y > item.funnelArea[1] && currentPoints.y < item.funnelArea[3]) {
currentIndex = i;
break;
}
}
return currentIndex;
}
function findWordChartCurrentIndex(currentPoints, wordData) {
var currentIndex = -1;
for (var i = 0, len = wordData.length; i < len; i++) {
var item = wordData[i];
if (currentPoints.x > item.area[0] && currentPoints.x < item.area[2] && currentPoints.y > item.area[1] && currentPoints.y < item.area[3]) {
currentIndex = i;
break;
}
}
return currentIndex;
}
function findMapChartCurrentIndex(currentPoints, opts) {
var currentIndex = -1;
var cData=opts.chartData.mapData;
var data=opts.series;
var tmp=pointToCoordinate(currentPoints.y, currentPoints.x,cData.bounds,cData.scale,cData.xoffset,cData.yoffset);
var poi=[tmp.x, tmp.y];
for (var i = 0, len = data.length; i < len; i++) {
var item = data[i].geometry.coordinates;
if(isPoiWithinPoly(poi,item)){
currentIndex = i;
break;
}
}
return currentIndex;
}
function findPieChartCurrentIndex(currentPoints, pieData) {
var currentIndex = -1;
if (isInExactPieChartArea(currentPoints, pieData.center, pieData.radius)) {
var angle = Math.atan2(pieData.center.y - currentPoints.y, currentPoints.x - pieData.center.x);
angle = -angle;
for (var i = 0, len = pieData.series.length; i < len; i++) {
var item = pieData.series[i];
if (isInAngleRange(angle, item._start_, item._start_ + item._proportion_ * 2 * Math.PI)) {
currentIndex = i;
break;
}
}
}
return currentIndex;
}
function isInExactPieChartArea(currentPoints, center, radius) {
return Math.pow(currentPoints.x - center.x, 2) + Math.pow(currentPoints.y - center.y, 2) <= Math.pow(radius, 2);
}
function splitPoints(points) {
var newPoints = [];
var items = [];
points.forEach(function(item, index) {
if (item !== null) {
items.push(item);
} else {
if (items.length) {
newPoints.push(items);
}
items = [];
}
});
if (items.length) {
newPoints.push(items);
}
return newPoints;
}
function calLegendData(series, opts, config, chartData) {
let legendData = {
area: {
start: {
x: 0,
y: 0
},
end: {
x: 0,
y: 0
},
width: 0,
height: 0,
wholeWidth: 0,
wholeHeight: 0
},
points: [],
widthArr: [],
heightArr: []
};
if (opts.legend.show === false) {
chartData.legendData = legendData;
return legendData;
}
let padding = opts.legend.padding;
let margin = opts.legend.margin;
let fontSize = opts.legend.fontSize;
let shapeWidth = 15 * opts.pixelRatio;
let shapeRight = 5 * opts.pixelRatio;
let lineHeight = Math.max(opts.legend.lineHeight * opts.pixelRatio, fontSize);
if (opts.legend.position == 'top' || opts.legend.position == 'bottom') {
let legendList = [];
let widthCount = 0;
let widthCountArr = [];
let currentRow = [];
for (let i = 0; i < series.length; i++) {
let item = series[i];
let itemWidth = shapeWidth + shapeRight + measureText(item.name || 'undefined', fontSize) + opts.legend.itemGap;
if (widthCount + itemWidth > opts.width - opts.padding[1] - opts.padding[3]) {
legendList.push(currentRow);
widthCountArr.push(widthCount - opts.legend.itemGap);
widthCount = itemWidth;
currentRow = [item];
} else {
widthCount += itemWidth;
currentRow.push(item);
}
}
if (currentRow.length) {
legendList.push(currentRow);
widthCountArr.push(widthCount - opts.legend.itemGap);
legendData.widthArr = widthCountArr;
let legendWidth = Math.max.apply(null, widthCountArr);
switch (opts.legend.float) {
case 'left':
legendData.area.start.x = opts.padding[3];
legendData.area.end.x = opts.padding[3] + 2 * padding;
break;
case 'right':
legendData.area.start.x = opts.width - opts.padding[1] - legendWidth - 2 * padding;
legendData.area.end.x = opts.width - opts.padding[1];
break;
default:
legendData.area.start.x = (opts.width - legendWidth) / 2 - padding;
legendData.area.end.x = (opts.width + legendWidth) / 2 + padding;
}
legendData.area.width = legendWidth + 2 * padding;
legendData.area.wholeWidth = legendWidth + 2 * padding;
legendData.area.height = legendList.length * lineHeight + 2 * padding;
legendData.area.wholeHeight = legendList.length * lineHeight + 2 * padding + 2 * margin;
legendData.points = legendList;
}
} else {
let len = series.length;
let maxHeight = opts.height - opts.padding[0] - opts.padding[2] - 2 * margin - 2 * padding;
let maxLength = Math.min(Math.floor(maxHeight / lineHeight), len);
legendData.area.height = maxLength * lineHeight + padding * 2;
legendData.area.wholeHeight = maxLength * lineHeight + padding * 2;
switch (opts.legend.float) {
case 'top':
legendData.area.start.y = opts.padding[0] + margin;
legendData.area.end.y = opts.padding[0] + margin + legendData.area.height;
break;
case 'bottom':
legendData.area.start.y = opts.height - opts.padding[2] - margin - legendData.area.height;
legendData.area.end.y = opts.height - opts.padding[2] - margin;
break;
default:
legendData.area.start.y = (opts.height - legendData.area.height) / 2;
legendData.area.end.y = (opts.height + legendData.area.height) / 2;
}
let lineNum = len % maxLength === 0 ? len / maxLength : Math.floor((len / maxLength) + 1);
let currentRow = [];
for (let i = 0; i < lineNum; i++) {
let temp = series.slice(i * maxLength, i * maxLength + maxLength);
currentRow.push(temp);
}
legendData.points = currentRow;
if (currentRow.length) {
for (let i = 0; i < currentRow.length; i++) {
let item = currentRow[i];
let maxWidth = 0;
for (let j = 0; j < item.length; j++) {
let itemWidth = shapeWidth + shapeRight + measureText(item[j].name || 'undefined', fontSize) + opts.legend.itemGap;
if (itemWidth > maxWidth) {
maxWidth = itemWidth;
}
}
legendData.widthArr.push(maxWidth);
legendData.heightArr.push(item.length * lineHeight + padding * 2);
}
let legendWidth = 0
for (let i = 0; i < legendData.widthArr.length; i++) {
legendWidth += legendData.widthArr[i];
}
legendData.area.width = legendWidth - opts.legend.itemGap + 2 * padding;
legendData.area.wholeWidth = legendData.area.width + padding;
}
}
switch (opts.legend.position) {
case 'top':
legendData.area.start.y = opts.padding[0] + margin;
legendData.area.end.y = opts.padding[0] + margin + legendData.area.height;
break;
case 'bottom':
legendData.area.start.y = opts.height - opts.padding[2] - legendData.area.height - margin;
legendData.area.end.y = opts.height - opts.padding[2] - margin;
break;
case 'left':
legendData.area.start.x = opts.padding[3];
legendData.area.end.x = opts.padding[3] + legendData.area.width;
break;
case 'right':
legendData.area.start.x = opts.width - opts.padding[1] - legendData.area.width;
legendData.area.end.x = opts.width - opts.padding[1];
break;
}
chartData.legendData = legendData;
return legendData;
}
function calCategoriesData(categories, opts, config, eachSpacing) {
var result = {
angle: 0,
xAxisHeight: config.xAxisHeight
};
var categoriesTextLenth = categories.map(function(item) {
return measureText(item,opts.xAxis.fontSize||config.fontSize);
});
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);
}
return result;
}
function getXAxisTextList(series, opts, config) {
var index = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : -1;
var data = dataCombine(series);
var sorted = [];
// remove null from data
data = data.filter(function(item) {
//return item !== null;
if (typeof item === 'object' && item !== null) {
if (item.constructor.toString().indexOf('Array')>-1) {
return item !== null;
} else {
return item.value !== null;
}
} else {
return item !== null;
}
});
data.map(function(item) {
if (typeof item === 'object') {
if (item.constructor.toString().indexOf('Array')>-1) {
if(opts.type=='candle'){
item.map(function(subitem) {
sorted.push(subitem);
})
}else{
sorted.push(item[0]);
}
} else {
sorted.push(item.value);
}
} else {
sorted.push(item);
}
})
var minData = 0;
var maxData = 0;
if (sorted.length > 0) {
minData = Math.min.apply(this, sorted);
maxData = Math.max.apply(this, sorted);
}
//为了兼容v1.9.0之前的项目
if(index>-1){
if (typeof opts.xAxis.data[index].min === 'number') {
minData = Math.min(opts.xAxis.data[index].min, minData);
}
if (typeof opts.xAxis.data[index].max === 'number') {
maxData = Math.max(opts.xAxis.data[index].max, maxData);
}
}else{
if (typeof opts.xAxis.min === 'number') {
minData = Math.min(opts.xAxis.min, minData);
}
if (typeof opts.xAxis.max === 'number') {
maxData = Math.max(opts.xAxis.max, maxData);
}
}
if (minData === maxData) {
var rangeSpan = maxData || 10;
maxData += rangeSpan;
}
//var dataRange = getDataRange(minData, maxData);
var minRange = minData;
var maxRange = maxData;
var range = [];
var eachRange = (maxRange - minRange) / opts.xAxis.splitNumber;
for (var i = 0; i <= opts.xAxis.splitNumber; i++) {
range.push(minRange + eachRange * i);
}
return range;
}
function calXAxisData(series, opts, config){
var result = {
angle: 0,
xAxisHeight: config.xAxisHeight
};
result.ranges = getXAxisTextList(series, opts, config);
result.rangesFormat = result.ranges.map(function(item){
item = opts.xAxis.format? opts.xAxis.format(item):util.toFixed(item, 2);
return item;
});
var xAxisScaleValues = result.ranges.map(function (item) {
// 如果刻度值是浮点数,则保留两位小数
item = util.toFixed(item, 2);
// 若有自定义格式则调用自定义的格式化函数
item = opts.xAxis.format ? opts.xAxis.format(Number(item)) : item;
return item;
});
result = Object.assign(result,getXAxisPoints(xAxisScaleValues, opts, config));
// 计算X轴刻度的属性譬如每个刻度的间隔,刻度的起始点\结束点以及总长
var eachSpacing = result.eachSpacing;
var textLength = xAxisScaleValues.map(function (item) {
return measureText(item);
});
// 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;
}
return result;
}
function getRadarDataPoints(angleList, center, radius, series, opts) {
var process = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 1;
var radarOption = opts.extra.radar || {
};
radarOption.max = radarOption.max || 0;
var maxData = Math.max(radarOption.max, Math.max.apply(null, dataCombine(series)));
var data = [];
for (let i = 0; i < series.length; i++) {
let each = series[i];
let listItem = {
};
listItem.color = each.color;
listItem.legendShape = each.legendShape;
listItem.pointShape = each.pointShape;
listItem.data = [];
each.data.forEach(function(item, index) {
let tmp = {
};
tmp.angle = angleList[index];
tmp.proportion = item / maxData;
tmp.position = convertCoordinateOrigin(radius * tmp.proportion * process * Math.cos(tmp.angle), radius * tmp.proportion *
process * Math.sin(tmp.angle), center);
listItem.data.push(tmp);
});
data.push(listItem);
}
return data;
}
function getPieDataPoints(series, radius) {
var process = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
var count = 0;
var _start_ = 0;
for (let i = 0; i < series.length; i++) {
let item = series[i];
item.data = item.data === null ? 0 : item.data;
count += item.data;
}
for (let i = 0; i < series.length; i++) {
let item = series[i];
item.data = item.data === null ? 0 : item.data;
if (count === 0) {
item._proportion_ = 1 / series.length * process;
} else {
item._proportion_ = item.data / count * process;
}
item._radius_ = radius;
}
for (let i = 0; i < series.length; i++) {
let item = series[i];
item._start_ = _start_;
_start_ += 2 * item._proportion_ * Math.PI;
}
return series;
}
function getFunnelDataPoints(series, radius) {
var process = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
series = series.sort(function(a,b){
return parseInt(b.data)-parseInt(a.data);});
for (let i = 0; i < series.length; i++) {
series[i].radius = series[i].data/series[0].data*radius*process;
series[i]._proportion_ = series[i].data/series[0].data;

本文介绍如何在uni-app中集成uCharts库,实现包括成交量在内的多条折线图展示。通过配置项详细说明,展示了设置图表类型、颜色、字体等样式,并演示了触摸交互下提示框的实现。
最低0.47元/天 解锁文章
1796

被折叠的 条评论
为什么被折叠?



