/*
* charts for WeChat small app v1.0
*
* https://github.com/xiaolin3303/wx-charts
* 2016-11-28
*
* Designed and built with all the love of Web
*/
'use strict';
var config = {
yAxisWidth: 15,
yAxisSplit: 5,
xAxisHeight: 15,
xAxisLineHeight: 15,
legendHeight: 15,
yAxisTitleWidth: 15,
padding: 12,
columePadding: 3,
fontSize: 10,
dataPointShape: ['diamond', 'circle', 'triangle', 'rect'],
colors: ['#7cb5ec', '#f7a35c', '#434348', '#90ed7d', '#f15c80', '#8085e9'],
pieChartLinePadding: 25,
pieChartTextPadding: 15,
xAxisTextPadding: 3,
titleColor: '#333333',
titleFontSize: 20,
subtitleColor: '#999999',
subtitleFontSize: 15,
toolTipPadding: 3,
toolTipBackground: '#000000',
toolTipOpacity: 0.7,
toolTipLineHeight: 14,
radarGridCount: 3,
radarLabelTextMargin: 15
};
// Object.assign polyfill
// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
function assign(target, varArgs) {
if (target == null) {
// TypeError if undefined or null
throw new TypeError('Cannot convert undefined or null to object');
}
var to = Object(target);
for (var index = 1; index < arguments.length; index++) {
var nextSource = arguments[index];
if (nextSource != null) {
// Skip over if undefined or null
for (var nextKey in nextSource) {
// Avoid bugs when hasOwnProperty is shadowed
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
to[nextKey] = nextSource[nextKey];
}
}
}
}
return to;
}
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;
}
};
function findRange(num, type, limit) {
if (isNaN(num)) {
throw new Error('[wxCharts] 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 calValidDistance(distance, chartData, config, opts) {
var dataChartAreaWidth = opts.width - config.padding - chartData.xAxisPoints[0];
var dataChartWidth = chartData.eachSpacing * opts.categories.length;
var validDistance = distance;
if (distance >= 0) {
validDistance = 0;
} else if (Math.abs(distance) >= dataChartWidth - dataChartAreaWidth) {
validDistance = dataChartAreaWidth - dataChartWidth;
}
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;
}
}
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;
}
// fix issue https://github.com/xiaolin3303/wx-charts/issues/79
if (isNotMiddlePoint(points, i + 1)) {
pBy = points[i + 1].y;
}
if (isNotMiddlePoint(points, i)) {
pAy = points[i].y;
}
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 fillSeriesColor(series, config) {
var index = 0;
return series.map(function (item) {
if (!item.color) {
item.color = config.colors[index];
index = (index + 1) % config.colors.length;
}
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 {
limit = 0.01;
}
return {
minRange: findRange(minData, 'lower', limit),
maxRange: findRange(maxData, 'upper', limit)
};
}
function measureText(text) {
var fontSize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 10;
// wx canvas 未实现measureText方法, 此处自行实现
text = String(text);
var text = text.split('');
var width = 0;
text.forEach(function (item) {
if (/[a-zA-Z]/.test(item)) {