mirror of
https://github.com/TBEDP/datavjs.git
synced 2025-12-08 19:45:52 +00:00
615 lines
23 KiB
JavaScript
615 lines
23 KiB
JavaScript
/*global Raphael, d3, $, define */
|
||
/*!
|
||
* ScatterplotMatrix的兼容性定义
|
||
*/
|
||
;(function (name, definition) {
|
||
if (typeof define === 'function') { // Module
|
||
define(definition);
|
||
} else { // Assign to common namespaces or simply the global object (window)
|
||
this[name] = definition(function (id) { return this[id];});
|
||
}
|
||
})('ScatterplotMatrix', function (require) {
|
||
var DataV = require('DataV');
|
||
var Brush = require('Brush');
|
||
|
||
var ScatterplotMatrix = DataV.extend(DataV.Chart, {
|
||
initialize: function (node, options) {
|
||
this.type = "ScatterplotMatrix";
|
||
this.node = this.checkContainer(node);
|
||
this.defaults = {};
|
||
|
||
// Properties
|
||
this.defaults.allDimensions = [];
|
||
this.defaults.dimensionsX = []; //dimension of X axis(horizonal). array type
|
||
this.defaults.demensionsY = []; //dimension of Y axis(vertical). array type
|
||
this.defaults.dimensionDomain = {};
|
||
this.defaults.typeNames = [];
|
||
|
||
// canvas parameters
|
||
this.defaults.width = 522;
|
||
this.defaults.height = 522;
|
||
this.defaults.margin = 50;
|
||
this.defaults.gap = 15;
|
||
this.defaults.squareWidth = 150;
|
||
this.defaults.circleR = 3;
|
||
|
||
//图例区域的左上顶点坐标x,y,宽,高
|
||
this.defaults.legendArea = [20, (this.defaults.height - 20 - 220), 200, 220];
|
||
//简介区域的左上角顶点坐标x,y,宽,高
|
||
this.defaults.introArea = [20, 20, 200, 200];
|
||
//散点矩阵区域的左上顶点坐标x,y,宽,高
|
||
this.defaults.diagramArea = [240, 20, (this.defaults.width - 260), (this.defaults.height - 40)];
|
||
|
||
this.defaults.typeName = "NoTypeDefinition"; //默认情况是没有分类
|
||
this.defaults.legendDimen = "NoTagDimen";
|
||
|
||
|
||
this.setOptions(options);
|
||
this.createCanvas();
|
||
}
|
||
});
|
||
|
||
/**
|
||
* 设置X轴的维度
|
||
*/
|
||
ScatterplotMatrix.prototype.setDimensionsX = function (dimen) {
|
||
if (!dimen) {
|
||
throw new Error("Please specify the dimensions.");
|
||
}
|
||
var conf = this.defaults;
|
||
conf.dimensionsX = [];
|
||
var i = 0,
|
||
l = 0;
|
||
for (i = 0, l = dimen.length; i < l; i++) {
|
||
if (_.indexOf(conf.allDimensions, dimen[i]) !== -1) {
|
||
conf.dimensionsX.push(dimen[i]);
|
||
}
|
||
}
|
||
};
|
||
|
||
/**
|
||
* 设置Y轴的维度
|
||
*/
|
||
ScatterplotMatrix.prototype.setDimensionsY = function (dimen) {
|
||
if (!dimen) {
|
||
throw new Error("Please specify the dimensions.");
|
||
}
|
||
var conf = this.defaults;
|
||
conf.dimensionsY = [];
|
||
var i = 0,
|
||
l = 0;
|
||
for (i = 0, l = dimen.length; i < l; i++) {
|
||
if (_.indexOf(conf.allDimensions, dimen[i]) !== -1) {
|
||
conf.dimensionsY.push(dimen[i]);
|
||
}
|
||
}
|
||
};
|
||
|
||
//设置类型的名字
|
||
ScatterplotMatrix.prototype.setTypeName = function (types) {
|
||
this.defaults.typeNames = types;
|
||
};
|
||
|
||
//设置源数据
|
||
ScatterplotMatrix.prototype.setSource = function (source) {
|
||
var i, j, l, ll;
|
||
var conf = this.defaults;
|
||
|
||
var xTemp = [],
|
||
yTemp = [];
|
||
for (i = 1; i < source[0].length; i++) {
|
||
xTemp[i - 1] = source[0][i];
|
||
yTemp[i - 1] = source[0][i];
|
||
}
|
||
conf.allDimensions = source[0];
|
||
// 默认情况下,所有维度都显示
|
||
conf.dimensionsX = xTemp;
|
||
conf.dimensionsY = yTemp;
|
||
|
||
// this.source is array of line; key is dimension, value is line's value in that dimension
|
||
this.source = [];
|
||
|
||
for (i = 1, l = source.length; i < l; i++) {
|
||
var line = {}, dimenT = conf.allDimensions;
|
||
for (j = 0, ll = dimenT.length; j < ll; j++) {
|
||
line[dimenT[j]] = source[i][j]; //each line is an array, contains value for each dimension
|
||
}
|
||
this.source.push(line);
|
||
}
|
||
|
||
// 设置默认的定义域
|
||
var getExtent = function (s, dimen) {
|
||
return d3.extent(s, function (p) {
|
||
return +p[dimen];
|
||
});
|
||
};
|
||
var dimen;
|
||
for (i = 0, l = conf.allDimensions.length; i < l; i++) {
|
||
dimen = conf.allDimensions[i];
|
||
conf.dimensionDomain[dimen] = getExtent(this.source, dimen);
|
||
}
|
||
};
|
||
|
||
/**
|
||
* 设置X轴和Y轴
|
||
*/
|
||
ScatterplotMatrix.prototype.setAxis = function () {
|
||
var conf = this.defaults;
|
||
|
||
conf.legendArea = [20, (conf.height - 20 - 220), 200, 220];
|
||
conf.introArea = [20, 20, 200, 200];
|
||
conf.diagramArea = [240, 20, (conf.width - 260), (conf.height - 40)];
|
||
|
||
var w = conf.diagramArea[2] - 2 * conf.margin,
|
||
h = conf.diagramArea[3] - conf.margin,
|
||
g = conf.gap,
|
||
nX = conf.dimensionsX.length,
|
||
nY = conf.dimensionsY.length,
|
||
wX = d3.round((w - (nX - 1) * g) / nX),
|
||
wY = d3.round((h - (nY - 1) * g) / nY),
|
||
sw = d3.min([wX, wY]);
|
||
|
||
this.defaults.squareWidth = sw;
|
||
this.defaults.dX = conf.dimensionsX[0];
|
||
this.defaults.dY = conf.dimensionsY[0];
|
||
|
||
this.x = {};
|
||
this.y = {};
|
||
var x = this.x,
|
||
y = this.y;
|
||
var tickAr = [5];
|
||
|
||
//设置X轴
|
||
var i, l, dimen, begin, end;
|
||
for (i = 0, l = conf.dimensionsX.length; i < l; i++) {
|
||
dimen = conf.dimensionsX[i];
|
||
begin = i * (sw + g) + conf.diagramArea[0] + 30;
|
||
end = begin + sw;
|
||
x[dimen] = d3.scale.linear().domain(conf.dimensionDomain[dimen]).range([begin, end]);
|
||
x[dimen].ticks = x[dimen].ticks.apply(x[dimen], tickAr);
|
||
}
|
||
//设置Y轴
|
||
for (i = 0, l = conf.dimensionsY.length; i < l; i++) {
|
||
dimen = conf.dimensionsY[i];
|
||
end = i * (sw + g) + conf.diagramArea[1] + 30;
|
||
begin = end + sw;
|
||
y[dimen] = d3.scale.linear().domain(conf.dimensionDomain[dimen]).range([begin, end]);
|
||
y[dimen].ticks = y[dimen].ticks.apply(y[dimen], tickAr);
|
||
}
|
||
};
|
||
|
||
//画散点矩阵
|
||
ScatterplotMatrix.prototype.drawDiagram = function () {
|
||
var i, j, k, z, ticks;
|
||
var conf = this.defaults,
|
||
x = this.x,
|
||
y = this.y,
|
||
sw = conf.squareWidth,
|
||
g = conf.gap,
|
||
cR = conf.circleR;
|
||
|
||
var paper = this.canvas;
|
||
var sourceData = this.source;
|
||
|
||
var dimensionsX = conf.dimensionsX,
|
||
dimensionsY = conf.dimensionsY,
|
||
lx = dimensionsX.length,
|
||
ly = dimensionsY.length;
|
||
|
||
var browserName = navigator.appName;
|
||
var that = this;
|
||
|
||
$(this.node).append(this.floatTag);
|
||
|
||
//画背景点
|
||
var circlesBg = paper.set(); //背景点
|
||
var centerPos;
|
||
|
||
if (browserName !== "Microsoft Internet Explorer") {
|
||
for (k = 0; k < sourceData.length; k++) {
|
||
for (i = 0; i < lx; i++) {
|
||
for (j = 0; j < ly; j++) {
|
||
centerPos = this.circleCenter(k, dimensionsX[i], dimensionsY[j]);
|
||
circlesBg.push(paper.circle(centerPos[0], centerPos[1], cR).attr({
|
||
"fill": "gray",
|
||
"stroke": "none",
|
||
"opacity": 0.2
|
||
}));
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 画矩形框
|
||
var squares = paper.set();
|
||
var x1, y1;
|
||
for (i = 0; i < lx; i++) {
|
||
for (j = 0; j < ly; j++) {
|
||
x1 = x[dimensionsX[i]].range()[0];
|
||
y1 = y[dimensionsY[j]].range()[1];
|
||
squares.push(paper.rect(x1 - 1, y1 - 1, sw + 2, sw + 2));
|
||
}
|
||
}
|
||
squares.attr({
|
||
"fill": "white",
|
||
"fill-opacity": 0.5, //背景点的蒙版
|
||
"stroke": "#d6d6d6",
|
||
"stroke-width": '1px'
|
||
});
|
||
|
||
//画虚线
|
||
var reLines = paper.set(),
|
||
tickText = paper.set();
|
||
var tickAr = [10], //set the number of ticks
|
||
leftPos = x[dimensionsX[0]].range()[0],
|
||
rightPos = x[dimensionsX[lx - 1]].range()[1],
|
||
upPos = y[dimensionsY[0]].range()[1],
|
||
downPos = y[dimensionsY[ly - 1]].range()[0];
|
||
|
||
var reLineGap = sw / 7; //每个矩形框中画6条虚线
|
||
var reLinePos;
|
||
|
||
//画纵向的虚线
|
||
for (i = 0; i < lx; i++) {
|
||
ticks = x[dimensionsX[i]].ticks;
|
||
for (j = 0; j < ticks.length; j++) {
|
||
tickText.push(paper.text((x[dimensionsX[i]](ticks[j])), downPos + 6, ticks[j]).attr({
|
||
"fill": "#aaaaaa",
|
||
"fill-opacity": 0.7,
|
||
"font-family": "雅黑",
|
||
"font-size": 12
|
||
}).attr({
|
||
"text-anchor": "end"
|
||
}).rotate(-45, x[dimensionsX[i]](ticks[j]), downPos + 6));
|
||
}
|
||
for (z = 1; z < 7; z++) {
|
||
reLinePos = x[dimensionsX[i]].range()[0] + z * reLineGap;
|
||
reLines.push(paper.path("M" + (reLinePos) + "," + (upPos) + "L" + (reLinePos) + "," + (downPos)).attr({
|
||
"stroke": "#ebebeb",
|
||
"stroke-dasharray": "-"
|
||
}));
|
||
}
|
||
}
|
||
//画横向的虚线
|
||
for (i = 0; i < ly; i++) {
|
||
//draw reference lines
|
||
ticks = y[dimensionsY[i]].ticks;
|
||
for (j = 0; j < ticks.length; j++) {
|
||
tickText.push(paper.text(rightPos + 6, y[dimensionsY[i]](ticks[j]), ticks[j]).attr({
|
||
"fill": "#aaaaaa",
|
||
"fill-opacity": 0.7,
|
||
"font-family": "雅黑",
|
||
"font-size": 12
|
||
}).attr({
|
||
"text-anchor": "start"
|
||
}).rotate(315, rightPos + 6, y[dimensionsY[i]](ticks[j])));
|
||
}
|
||
for (z = 1; z < 7; z++) {
|
||
reLinePos = y[dimensionsY[i]].range()[1] + z * reLineGap;
|
||
reLines.push(paper.path("M" + (leftPos) + "," + (reLinePos) + "L" + (rightPos) + "," + (reLinePos)).attr({
|
||
"stroke": "#ebebeb",
|
||
"stroke-dasharray": "-"
|
||
}));
|
||
}
|
||
}
|
||
|
||
//坐标轴名称
|
||
var axText = paper.set();
|
||
var xPos, yPos;
|
||
var pos = y[dimensionsY[0]].range()[1] - 10;
|
||
for (i = 0; i < lx; i++) {
|
||
xPos = x[dimensionsX[i]].range()[0] + sw / 2;
|
||
axText.push(paper.text(xPos, pos, dimensionsX[i]).attr({
|
||
"fill": "#000000",
|
||
"fill-opacity": 0.7,
|
||
"font-family": "Verdana",
|
||
//"font-weight": "bold",
|
||
"font-size": 12
|
||
}).attr({
|
||
"text-anchor": "middle"
|
||
}));
|
||
}
|
||
|
||
pos = x[dimensionsX[0]].range()[0] - 10;
|
||
for (i = 0; i < ly; i++) {
|
||
yPos = y[dimensionsY[i]].range()[1] + sw / 2;
|
||
axText.push(paper.text(pos, yPos, dimensionsY[i]).attr({
|
||
"fill": "#000000",
|
||
"fill-opacity": 0.7,
|
||
"font-family": "Verdana",
|
||
//"font-weight": "bold",
|
||
"font-size": 12
|
||
}).attr({
|
||
"text-anchor": "middle"
|
||
}).rotate(-90, pos, yPos));
|
||
}
|
||
|
||
// 画前景点
|
||
var circlesFg = []; //circles in foreground
|
||
var circleType = -1;
|
||
var typeMax = -1;
|
||
|
||
this.preIndex = "start";
|
||
this.linePosition = [0,0];
|
||
//水平虚线
|
||
that.lineH = paper.path("M" + (leftPos) + "," + (0) + "L" + (rightPos) + "," + (0)).attr({
|
||
"stroke-dasharray": "- ",
|
||
'stroke': '#000000'
|
||
}).hide();
|
||
//垂直虚线
|
||
that.lineV = paper.path("M" + (0) + "," + (upPos) + "L" + (0) + "," + (downPos)).attr({
|
||
"stroke-dasharray": "- ",
|
||
'stroke': '#000000'
|
||
}).hide();
|
||
var hoverTag;
|
||
var circle;
|
||
for (k = 0; k < sourceData.length; k++) {
|
||
if (conf.typeName !== "NoTypeDefinition") { //classify the circles according to their types
|
||
circleType = sourceData[k][conf.typeName] - 1;
|
||
typeMax = Math.max(typeMax, circleType);
|
||
} else {
|
||
circleType = 0;
|
||
}
|
||
for (i = 0; i < lx; i++) {
|
||
for (j = 0; j < ly; j++) {
|
||
centerPos = this.circleCenter(k, dimensionsX[i], dimensionsY[j]);
|
||
//前景点
|
||
circle = paper.circle(centerPos[0], centerPos[1], cR)
|
||
.data("type", circleType)
|
||
.data("canHover", 0)
|
||
.data("position", centerPos)
|
||
.data('colorType', circleType)
|
||
.attr({
|
||
"fill": "#800",
|
||
"stroke": "none",
|
||
"opacity": 0.5
|
||
}).attr({
|
||
"fill": this.getColor(circleType)
|
||
});
|
||
//如果制定了hover要显示的文字,则hover显示的文字
|
||
if (conf.legendDimen !== "NoTagDimen") {
|
||
hoverTag = conf.legendDimen + ": " + sourceData[k][conf.legendDimen];
|
||
circle.data("legend", hoverTag);
|
||
}
|
||
circlesFg.push(circle);
|
||
}
|
||
}
|
||
}
|
||
|
||
//图例
|
||
var legendArea = this.defaults.legendArea;
|
||
var rectBn = paper.set();
|
||
var underBn = [];
|
||
for (i = 0; i <= typeMax; i++) {
|
||
//底框
|
||
underBn.push(paper.rect(legendArea[0] + 10, legendArea[1] + 10 + (20 + 3) * i, 180, 20).attr({
|
||
"fill": "#ebebeb",
|
||
"stroke": "none"
|
||
}).hide());
|
||
//色框
|
||
paper.rect(legendArea[0] + 10 + 3, legendArea[1] + 10 + (20 + 3) * i + 6, 16, 8).attr({
|
||
"fill": this.getColor(i),
|
||
"stroke": "none"
|
||
});
|
||
//文字
|
||
paper.text(legendArea[0] + 10 + 3 + 16 + 8, legendArea[1] + 10 + (20 + 3) * i + 10, conf.typeNames[i]).attr({
|
||
"fill": "black",
|
||
"fill-opacity": 1,
|
||
"font-family": "Verdana",
|
||
"font-size": 12
|
||
}).attr({
|
||
"text-anchor": "start"
|
||
});
|
||
//选框
|
||
rectBn.push(paper.rect(legendArea[0] + 10, legendArea[1] + 10 + (20 + 3) * i, 180, 20).attr({
|
||
"fill": "white",
|
||
"fill-opacity": 0,
|
||
"stroke": "none"
|
||
//"r": 3
|
||
}).data("type", i)).data("clicked", 0);
|
||
}
|
||
|
||
if (browserName !== "Microsoft Internet Explorer") {
|
||
rectBn.forEach(function (d, i) {
|
||
underBn[i].data('legendclicked', false);
|
||
d.mouseover(function () {
|
||
if (underBn[i].data('legendclicked') === false) {
|
||
underBn[i].attr('opacity', 0.5).show();
|
||
}
|
||
}).mouseout(function () {
|
||
if (underBn[i].data('legendclicked') === false) {
|
||
underBn[i].hide();
|
||
}
|
||
});
|
||
d.click(function () {
|
||
for (j = 0; j < underBn.length; j++) {
|
||
if (j === i) {
|
||
underBn[j].show();
|
||
} else {
|
||
underBn[j].hide();
|
||
}
|
||
}
|
||
rectBn.forEach(function (eachBn) {
|
||
if (eachBn !== d) {
|
||
eachBn.data("clicked", 0);
|
||
}
|
||
|
||
});
|
||
if (d.data("clicked") === 0) {
|
||
underBn[i].attr('opacity', 1).show();
|
||
underBn[i].data('legendclicked', true);
|
||
circlesFg.forEach(function (ec) {
|
||
if (ec.data("type") !== d.data("type")) {
|
||
ec.hide();
|
||
ec.data("canHover", 0);
|
||
} else {
|
||
ec.show();
|
||
ec.data("canHover", 1);
|
||
}
|
||
});
|
||
d.data("clicked", 1);
|
||
} else if (d.data("clicked") === 1) {
|
||
underBn[i].hide();
|
||
underBn[i].data('legendclicked', false);
|
||
d.data("clicked", 0);
|
||
circlesFg.forEach(function (ec) {
|
||
ec.show();
|
||
ec.data("canHover", 0);
|
||
});
|
||
}
|
||
});
|
||
});
|
||
|
||
//Bursh函数定义
|
||
var curBrush;
|
||
|
||
function brushstart() {
|
||
if (curBrush !== undefined && curBrush !== d3.event.target) {
|
||
curBrush.clear();
|
||
}
|
||
var i;
|
||
for (i = 0; i < circlesFg.length; i++) {
|
||
circlesFg[i].hide();
|
||
circlesFg[i].data("canHover", 0);
|
||
}
|
||
underBn.forEach(function (ub) {
|
||
ub.hide();
|
||
});
|
||
rectBn.forEach(function (rb) {
|
||
rb.data("clicked", 0);
|
||
});
|
||
}
|
||
|
||
function brush() {
|
||
curBrush = d3.event.target;
|
||
|
||
var e = curBrush.extent(),
|
||
dimX = d3.event.target.dimX,
|
||
dimY = d3.event.target.dimY,
|
||
tempX,
|
||
tempY,
|
||
count = lx * ly,
|
||
i,
|
||
z;
|
||
|
||
for (i = 0; i < sourceData.length; i++) {
|
||
tempX = sourceData[i][dimX];
|
||
tempY = sourceData[i][dimY];
|
||
if (e[0][0] - 1 <= tempX && tempX <= e[1][0] + 1 && e[0][1] - 1 <= tempY && tempY <= e[1][1] + 1) {
|
||
for (z = 0; z < count; z++) {
|
||
circlesFg[i * count + z].show();
|
||
}
|
||
} else {
|
||
for (z = 0; z < count; z++) {
|
||
circlesFg[i * count + z].hide();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
function brushend() {
|
||
if (d3.event.target.empty()) {
|
||
circlesFg.forEach(function (d) {
|
||
d.show();
|
||
});
|
||
}
|
||
}
|
||
|
||
//Brush交互
|
||
var brushes = [];
|
||
var b;
|
||
for (i = 0; i < lx; i++) {
|
||
for (j = 0; j < ly; j++) {
|
||
b = Brush().x(x[dimensionsX[i]]).y(y[dimensionsY[j]]).backgroundAttr({
|
||
"opacity": 0, //背景颜色:白色、全透明
|
||
"fill": "white"
|
||
}).foregroundAttr({ //选框颜色
|
||
"opacity": 0.2,
|
||
"fill": "#fff700"
|
||
}).on("brushstart", brushstart).on("brush", brush).on("brushend", brushend);
|
||
b(paper);
|
||
b.dimX = dimensionsX[i];
|
||
b.dimY = dimensionsY[j];
|
||
brushes.push(b);
|
||
}
|
||
}
|
||
//hover交互
|
||
//var preIndex = "start";
|
||
var floatTag = this.floatTag;
|
||
$(paper.canvas).bind("mousemove", function (e) {
|
||
var bgOffset = $(this).parent().offset();
|
||
var mouse = [e.pageX - bgOffset.left, e.pageY - bgOffset.top];
|
||
var location = [Math.floor((mouse[0] - leftPos) / (sw + g)), Math.floor((mouse[1] - upPos) / (sw + g))];
|
||
if (that.preIndex !== "start") {
|
||
that.lineV.hide();
|
||
that.lineH.hide();
|
||
if (conf.legendDimen !== "NoTagDimen") {
|
||
floatTag.css({"visibility" : "hidden"});
|
||
}
|
||
}
|
||
if (location[0] >= 0 && location[0] <= lx && location[1] >= 0 && location[1] <= ly) {
|
||
for (i = location[0] * ly + location[1]; i < circlesFg.length; i = i + lx * ly) {
|
||
var center = circlesFg[i].data("position");
|
||
var canHover = circlesFg[i].data("canHover");
|
||
if ((canHover === 1) && (Math.abs(mouse[0] - center[0]) <= cR) && (Math.abs(mouse[1] - center[1]) <= cR)) {
|
||
that.lineV.translate(center[0] - that.linePosition[0], 0).attr('stroke', that.getColor(circlesFg[i].data('colorType'))).show();
|
||
that.lineH.translate(0, center[1] - that.linePosition[1]).attr('stroke', that.getColor(circlesFg[i].data('colorType'))).show();
|
||
that.linePosition = center;
|
||
if (conf.legendDimen !== "NoTagDimen") {
|
||
floatTag.html('<div style="text-align: center;margin:auto;color:#ffffff">' + circlesFg[i].data("legend") + '</div>');
|
||
floatTag.css({"visibility" : "visible"});
|
||
}
|
||
that.preIndex = i;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
});
|
||
}
|
||
};
|
||
|
||
/**
|
||
* 创建canvas
|
||
*/
|
||
ScatterplotMatrix.prototype.createCanvas = function () {
|
||
var conf = this.defaults;
|
||
this.node.style.position = "relative";
|
||
this.canvas = new Raphael(this.node, conf.width, conf.height);
|
||
this.floatTag = DataV.FloatTag()(this.node);
|
||
this.floatTag.css({"visibility": "hidden"});
|
||
};
|
||
|
||
//根据不同类别得到颜色值
|
||
ScatterplotMatrix.prototype.getColor = function (circleType) {
|
||
var color = DataV.getColor();
|
||
return color[circleType % color.length][0];
|
||
};
|
||
|
||
//绘制函数
|
||
ScatterplotMatrix.prototype.render = function (options) {
|
||
this.setOptions(options);
|
||
this.canvas.clear();
|
||
this.setAxis();
|
||
this.drawDiagram();
|
||
//var dEnd = new Date();
|
||
//alert(dEnd.getTime() - dBegin.getTime());
|
||
};
|
||
|
||
//计算每个circle的圆心位置
|
||
ScatterplotMatrix.prototype.circleCenter = function (index, xDimen, yDimen) {
|
||
var conf = this.defaults,
|
||
source = this.source,
|
||
y = this.y,
|
||
x = this.x,
|
||
dimensionsX = conf.dimensionsX,
|
||
dimensionsY = conf.dimensionsY,
|
||
dimensionType = conf.dimensionType;
|
||
|
||
var xPos = x[xDimen](source[index][xDimen]),
|
||
yPos = y[yDimen](source[index][yDimen]);
|
||
|
||
return [xPos, yPos];
|
||
};
|
||
|
||
return ScatterplotMatrix;
|
||
}); |