Визуализация данных объединения / пересечения - предпочтителен JavaScript - PullRequest
1 голос
/ 20 декабря 2011

Я нахожусь в процессе создания веб-приложения, и мне было поручено создать довольно хитрое визуальное требование.

Мне нужен способ отображения визуальных представлений сущностей в кругах. Как и в математике 101, мне также нужно визуально представить их объединение и пересечения.

Как это изображение .. http://www.k12math.com/math-concepts/sets/A_and_B_and_C_un_int.png

Например, предположим, у меня на холсте три круга, которые представляют 3 языка программирования, таких как java, c ++ и perl.

Если я хочу посмотреть, какие объектно-ориентированные языки существуют на моем холсте, мне понадобятся круги java и c ++ для пересечения.

Я бы предпочел какой-нибудь плагин Jquery, а не делать это с нуля.

Кроме того, круги, представляющие объекты данных, не должны быть ограничены 3. Может быть n чисел или кругов.

Если бы я был вынужден сделать это с нуля, некоторые предложения о том, как подойти к нему, были бы оценены.

Кроме того, круги должны быть перетаскиваемыми. Если бы я хотел удалить perl из своего холста, я бы мог просто перетащить его в мусорное ведро. Не стесняйтесь комментировать вопросы и / или разъяснения.

И последнее: каждый раздел кругов должен быть кликабельным. Другими словами, если я нажимаю на объектно-ориентированное пересечение, я должен запустить событие, которое выбирает языки, которые являются объектно-ориентированными.

1 Ответ

1 голос
/ 20 декабря 2011

Если вы хотите перетащить, то API Google Chart недостаточно, поскольку он предоставляет статическое изображение. Вместо этого вы можете использовать <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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...