function snapToSharp(number) {
|
|
return (number | 0) + 0.5;
|
|
}
|
|
|
|
var MarkDot = kity.createClass("MarkDot", {
|
|
base: kity.Group,
|
|
constructor: function(size, color) {
|
|
this.callBase();
|
|
this.addShape(new kity.Circle(size || 1).fill(color));
|
|
this.addShape(this.rect = new kity.Rect().fill('white').setOpacity(0.95).stroke(color, 2).setRadius(3));
|
|
this.addShape(this.text = new kity.Text().fill(color).setStyle('font-family', 'Arial'));
|
|
},
|
|
setText: function(content) {
|
|
this.text.setContent(content);
|
|
},
|
|
updatePosition: function(x, y, bx, by) {
|
|
this.setTranslate(x, y);
|
|
|
|
var rb = this.text.getRenderBox();
|
|
var tx, ty, margin = 15;
|
|
|
|
if (x + rb.width > bx) {
|
|
// 右边越界,放在左方
|
|
tx = -rb.width - margin;
|
|
} else {
|
|
// 默认放在右方
|
|
tx = margin;
|
|
}
|
|
ty = -rb.height / 2;
|
|
this.text.setTranslate(tx, ty + rb.height - 2);
|
|
var f = snapToSharp;
|
|
this.rect.setPosition(f(tx) - 5, f(ty) - 5);
|
|
this.rect.setSize((rb.width | 0) + 10, (rb.height | 0) + 10);
|
|
}
|
|
});
|
|
|
|
var KCLineChart = kity.createClass("lineChart", (function() {
|
|
var p = new kity.Palette();
|
|
p.add('alix-text', new kity.Color('black').inc('l', '50'));
|
|
return {
|
|
constructor: function(data, target) {
|
|
this.graphMargin = {
|
|
top: 9.5,
|
|
right: 19.5,
|
|
left: 20.5,
|
|
bottom: 49.5
|
|
};
|
|
this._paper = new kity.Paper(target);
|
|
this.renderData(data);
|
|
this.interact(data);
|
|
},
|
|
renderData: function(d) {
|
|
var me = this;
|
|
var _paper = this._paper;
|
|
var container = _paper.getContainer();
|
|
var margin = this.graphMargin;
|
|
this.paperWidth = container.clientWidth;
|
|
this.paperHeight = container.clientHeight;
|
|
_paper.setViewBox(0, 0, container.clientWidth, container.clientHeight).setWidth(container.clientWidth).setHeight(container.clientHeight);
|
|
_paper.setWidth(container.clientWidth).setHeight(container.clientHeight);
|
|
var drawArea = {
|
|
top: margin.top,
|
|
right: me.paperWidth - margin.right,
|
|
bottom: me.paperHeight - margin.bottom,
|
|
left: margin.left
|
|
};
|
|
var duraction = (drawArea.right - drawArea.left) / 18;
|
|
|
|
var renderAxis = function() {
|
|
var _paper = me._paper;
|
|
var labels = d.axis.cateX;
|
|
_paper.addShape(new kity.Path().pipe(function() {
|
|
var dr = this.getDrawer();
|
|
dr.moveTo(drawArea.left, drawArea.bottom).lineTo(drawArea.right, drawArea.bottom);
|
|
for (var i = 0; i < 18; i++) {
|
|
var vX = drawArea.left + i * duraction;
|
|
dr.moveTo(vX, drawArea.bottom).lineTo(vX, drawArea.bottom + 3);
|
|
}
|
|
this.stroke("#C0D0E0", 1);
|
|
}));
|
|
//绘制label
|
|
for (var j = 0; j < 17; j++) {
|
|
var vX = 15.5 + j * duraction;
|
|
var _label = new kity.Text(labels[j]);
|
|
_label
|
|
.setX(vX).setY(drawArea.bottom + 10).setSize(12).setStyle("font-family", "Arial").fill(p.get('alix-text'));
|
|
_paper.addShape(_label);
|
|
_label.translate(-_label.getX(), -_label.getY())
|
|
.rotate(60)
|
|
.translate(_label.getX(), _label.getY());
|
|
}
|
|
};
|
|
//根据设定的最大值和最小值绘制折线图
|
|
var renderPolyLine = function(d, base, top) {
|
|
//将传入的坐标转换成绘制坐标
|
|
var map = function(step, x, y) {
|
|
var areaY = top - base;
|
|
var mapped_y = drawArea.bottom - ((drawArea.bottom - drawArea.top) * (y - base) / areaY);
|
|
var mapped_x = drawArea.left + duraction * step + duraction * x / 10;
|
|
return [mapped_x, mapped_y];
|
|
};
|
|
var lineData = d.series;
|
|
var drawingSeries = me.drawingSeries = [];
|
|
for (var i = 0; i < lineData.length; i++) {
|
|
var ld = lineData[i].data;
|
|
drawingSeries.push([]);
|
|
for (var j = 0; j < 17; j++) {
|
|
var step = j;
|
|
for (var k = 0; k < 10; k++) {
|
|
var actualY = ld[j][k];
|
|
var actualX = k;
|
|
var drawingPos = map(step, actualX, actualY);
|
|
drawingSeries[i].push(new kity.Point(drawingPos[0], drawingPos[1]));
|
|
}
|
|
}
|
|
}
|
|
//绘制折线
|
|
for (var _line = 0; _line < drawingSeries.length; _line++) {
|
|
var line = new kity.Polyline(drawingSeries[_line]);
|
|
//(d.colors[_line] || "red"), 2).setLineJoin("round").setLinecap("round")
|
|
line.stroke(new kity.Pen().setColor(d.colors[_line] || "red").setWidth(2).setLineJoin("round").setLineCap("round"));
|
|
_paper.addShape(line);
|
|
}
|
|
};
|
|
renderAxis();
|
|
renderPolyLine(d, 10000, 20000);
|
|
},
|
|
interact: function(data) {
|
|
var me = this;
|
|
var margin = this.graphMargin;
|
|
var drawArea = {
|
|
top: margin.top,
|
|
right: me.paperWidth - margin.right,
|
|
bottom: me.paperHeight - margin.bottom,
|
|
left: margin.left
|
|
};
|
|
var xRuler = new kity.Line(0.5, drawArea.top, 0.5, drawArea.bottom).stroke("#C0D0E0").translate(-10);
|
|
this._paper.addShape(xRuler);
|
|
|
|
var pointIndex = (function(origin) {
|
|
var series = [];
|
|
for (var i = 0; i < origin.length; i++) {
|
|
for (var j = 0; j < origin[i].length; j++) {
|
|
var p = origin[i][j];
|
|
series[j] = series[j] || [p.x];
|
|
series[j].push(p.y);
|
|
}
|
|
}
|
|
return series;
|
|
})(this.drawingSeries);
|
|
|
|
function mid(i, j) {
|
|
return (i + j) >> 1;
|
|
}
|
|
|
|
function findNearestPoint(x) {
|
|
var i = 0,
|
|
j = pointIndex.length - 1,
|
|
m = mid(i, j);
|
|
while (i != m && j != m) {
|
|
if (x > pointIndex[m][0]) {
|
|
i = m;
|
|
} else {
|
|
j = m;
|
|
}
|
|
m = mid(i, j);
|
|
}
|
|
return Math.abs(pointIndex[i][0] - x) < Math.abs(pointIndex[j][0] - x) ? pointIndex[i] : pointIndex[j];
|
|
}
|
|
|
|
var iDots = [];
|
|
for (var i = 0; i < data.colors.length; i++) {
|
|
var dot = new MarkDot(3.5, new kity.Color(data.colors[i]).dec('l', 10));
|
|
dot.translate(-10);
|
|
iDots.push(dot);
|
|
this._paper.addShape(dot);
|
|
}
|
|
|
|
var lastUpdateTs = 0;
|
|
|
|
function updatePosition(e) {
|
|
if (+new Date() - lastUpdateTs < 16) {
|
|
return;
|
|
}
|
|
var x = e.getPosition().x;
|
|
var points = findNearestPoint(x);
|
|
x = Math.floor(points[0]);
|
|
xRuler.setTranslate(x, 0);
|
|
for (var i = 1; i < points.length; i++) {
|
|
iDots[i - 1].setText((points[0] | 0) + ', ' + (points[i] | 0));
|
|
iDots[i - 1].updatePosition(points[0], points[i], me.paperWidth - 100, me.paperHeight);
|
|
}
|
|
e.preventDefault();
|
|
lastUpdateTs = +new Date();
|
|
}
|
|
if (window.ontouchstart !== undefined) {
|
|
this._paper.on('touchstart touchmove', updatePosition);
|
|
} else {
|
|
this._paper.on('mousemove', updatePosition);
|
|
var on = true;
|
|
var paper = this._paper.on('click', function(e) {
|
|
if (on) {
|
|
paper.off('mousemove', updatePosition);
|
|
} else {
|
|
updatePosition(e);
|
|
paper.on('mousemove', updatePosition);
|
|
}
|
|
on = !on;
|
|
});
|
|
}
|
|
}
|
|
};
|
|
})());
|