联合/交叉数据可视化- javascript优先



我正在构建一个web应用程序的过程中,并被要求构建一个相当棘手的视觉需求。

我需要一种方法来显示圆形实体的视觉表示。就像在数学101中一样,我也需要直观地表示它们的并集和相交。

喜欢这个图像…http://www.k12math.com/math-concepts/sets/A_and_B_and_C_un_int.png

例如,假设我在画布上有三个圆圈,分别代表三种编程语言,如java, c++和perl。

如果我想看看我的画布上有哪些面向对象的语言,我需要java和c++的圆圈相交。

我更喜欢某种Jquery插件,而不是从头开始。

同样,表示数据实体的圆圈不应限于3。可以有n个数字或圆

如果我不得不从头开始,我希望你能给我一些建议。

同时,圆圈应该是可拖动的。如果我想从画布中删除perl,我应该能够将它拖到垃圾桶中。如果有问题和/或澄清,请随时发表评论。

最后一点,圆圈的每个部分都应该是可点击的。换句话说,如果我点击面向对象的交叉点,我应该触发一个事件来获取面向对象的语言。

如果你想要拖动,那么Google Chart API是不够的,因为它提供了一个静态图像。相反,您可以使用<canvas>和它的globalCompositeOperation组合来设置当它们相交时应该发生什么("lighter"添加值):http://jsfiddle.net/eGjak/226/.

为了方便,这个解决方案确实使用了jQuery。当您单击时,它不会显示语言,但这段代码可能是您尝试实现的一个开始。

var ctx = $('#cv').get(0).getContext('2d');
var pi2 = Math.PI * 2;
ctx.globalCompositeOperation = "lighter";
ctx.fillStyle = "rgba(255, 0, 0, 0.25)"; // semi-transparent color
var Circle = function(x, y, r) {
    this.x = x;
    this.y = y;
    this.r = r;
};
var circles = [
    new Circle(100, 100, 50),
    new Circle(200, 200, 75),
    new Circle(200, 100, 25)
];
function iterate(f) { // convenience function
    for(var i = 0; i < circles.length; i++) {
        f.call(circles[i], i, circles[i]);
    }
}
function draw() {
    ctx.clearRect(0, 0, 400, 400);
    iterate(function() {
        ctx.beginPath();
        ctx.arc(this.x, this.y, this.r, 0, pi2);
        ctx.fill();
        ctx.stroke();
    });
}
var sqrt = Math.sqrt;
var selected;
function coords(e) {
    var o = $('#cv').offset(),
        x = e.pageX - o.left,
        y = e.pageY - o.top;
    return {x: x, y: y};
}
var grab; // to save grab offset from middle of selected circle
$("#cv").mousedown(function(e) {
    var c = coords(e);
    grab = c;
    iterate(function() {
        var dx = this.x - c.x,
            dy = this.y - c.y;
        if(sqrt(dx * dx + dy * dy) < this.r) { // mouse within this circle
            selected = this;
            grab.x -= this.x;
            grab.y -= this.y;
        }
    });
}).mousemove(function(e) {
    var c = coords(e);
    if(selected) {
        selected.x = c.x - grab.x;
        selected.y = c.y - grab.y;
        draw();
    }
}).mouseup(function() {
    selected = null;
});
draw();

最新更新