Example #1
0
    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;
                        }
                    }
                }
            });
        }
    };
Example #2
0
    Parallel.prototype.generatePaths = function () {
        var conf = this.defaults;
        var axis = Axis()
            .orient("left")
            .tickAttr(conf.axisStyle.tickAttr)
            .tickTextAttr(conf.axisStyle.tickTextAttr)
            .domainAttr(conf.axisStyle.domainAttr);

        var m = conf.marginWidth;

        var paper = this.canvas;

        this.bg = paper.set();
        var i, l;
        for (i = 0, l = this.source.length; i<l; i++) {
            var line = this.source[i];
            this.bg.push(paper.path(this.path(line)));
        }
        this.bg.attr(conf.backgroundAttr).attr({transform: "t" + m[3] + ',0'});
        
        this.fg = paper.set();
        for (i = 0, l = this.source.length; i<l; i++) {
            var line = this.source[i];
            this.fg.push(paper.path(this.path(line)));
        }
        this.fg.attr(conf.foregroundAttr).attr({transform: "t" + m[3] + ',0'});

        var dimensions = this.dimensions;
        
        for(i = 0, l = dimensions.length; i<l; i++){
            var ax=axis.scale(this.y[dimensions[i]])(paper);
            ax.push(paper.text(0, m[0] - 12, dimensions[i]).attr({"text-anchor": "middle"}));
            ax.attr({transform: "t" + (m[3] + this.x.range()[i] ) + ',0'});
        }

        var xInterval = Math.min(this.x.range()[1] - this.x.range()[0] - 20, 16);
        var brushs = [];

        this.statistic = {};
        this.statistic["selected"] = 0;
        this.statistic["all"] = this.source.length;
        this.statistic["items"] = {};
        var that = this;
        this.brush = function() {
                var statistic = that.statistic;
                var dimensionExtents = that.dimensionExtent;
                var actives = that.dimensions.filter(function(p) {
                        var empty = that.y[p].brush.empty();
                        if (empty) {
                            statistic.items[p] = -1;
                            dimensionExtents[p] = undefined;
                        } else {
                            statistic.items[p] = 0;
                        }
                        return !empty;
                    }),
                    extents = actives.map(function(p) {
                            var extent = that.y[p].brush.extent();
                            if (that.dimensionType[p] === "quantitative") {
                                that.dimensionExtent[p] = extent;
                            } else {
                                that.dimensionExtent[p] = [
                                    that.dimensionDomain[p][Math.ceil(extent[0] - 0.5)],
                                    that.dimensionDomain[p][Math.floor(extent[1] - 0.5)]
                                ];
                            }
                            return extent;
                        });
                var i, j, l, ll, p;
                var d, value, inExtent, selected;
                //var brush, dimen;

                statistic["selected"] = 0;
                
                for (j=0, l=that.fg.length; j<l; j++) {
                    d = that.source[j];
                    selected = true;
                    for (i = 0, ll = actives.length; i < ll; i++) {
                        p = actives[i];
                        value = that.dimensionType[p] === "quantitative" ?
                                d[p] : that.dimensionDomain[p].itemIndex[d[p]] + 0.5;
                        inExtent = extents[i][0] <= value && value <= extents[i][1];
                        if (inExtent) { statistic.items[p] += 1;}
                        if (!inExtent) {selected = false;}
                    }
                    if (selected) {
                        statistic["selected"] += 1;
                        that.fg[j].attr({"stroke": "steelblue"});
                    } else {
                        that.fg[j].attr({"stroke": "none"});
                    }
                }

                that.defaults.customEvent["brush"].call(that);
            },
            brushstart = function () {
                that.defaults.customEvent["brushstart"].call(that);
            },
            brushend = function () {
                that.defaults.customEvent["brushend"].call(that);
            };

        var b, start, end, temp;

        for (var i = 0, l = dimensions.length; i<l; i++) {
            dimen = dimensions[i];
            b = Brush().y(this.y2[dimen])
                .left(m[3] + this.x.range()[i] - xInterval/2)
                .width(xInterval)
                .backgroundAttr({"opacity": 0, "fill": "white"})
                .foregroundAttr({"opacity": 0.5, "fill": "gray"})
                .on("brushstart", brushstart)
                .on("brush", this.brush)
                .on("brushend", brushend);
            if (typeof this.dimensionExtent[dimen] !== 'undefined') {
                if (this.dimensionType[dimen] === "quantitative") {
                    b.extent(this.dimensionExtent[dimen]);
                } else {
                    b.extent(this._getOrdinalExtent(dimen, this.dimensionExtent[dimen]));
                }
            }

            this.y[dimen].brush = b(paper);
            //this.y[dimensions[i]].brush.dimension = dimensions[i];
        }
        if (!$.isEmptyObject(this.dimensionExtent)) {
            this.brush();
        }
    };