可視化工具--D3--案例分析--Scatterplot Matrix

可視化工具–D3–案例分析

Scatterplot Matrix

實例鏈接 http://mbostock.github.io/d3/talk/20111116/iris-splom.html

散點矩陣圖是通過繪製多變量間的散點圖展現各變量間的相關關係,通常用在統計學研究中。
在多變量相關關係的大數據分析中也可以應用。

部分接口:

d3.svg.brush():定義刷子,可以選擇一個二維區域

brush.x().y():方向變換,用於拖拽

brush.extent():設置刷子選取範圍

brush.clear():清除刷子以選取的範圍

brush.empty():判斷選取範圍是否爲空,通常用在brushend中

brush.on():事件監聽(類似鼠標事件),有brushstart, brush, brushend三種

brush.event():通過程序觸發監聽事件

一些基本參數設置:

var size = 140,
    padding = 10,
    n = 4,
    traits = ["sepal length", "sepal width", "petal length", "petal width"];

定義比例尺:

var x = {}, y = {};
traits.forEach(function(trait) {
    //數值轉換的操作
    flowers.forEach(function(d) { d[trait] = +d[trait]; });
    //因爲散點矩陣的比例尺唯一,因此使用比例尺字典,這裏定義多個比例尺
    var value = function(d) { return d[trait]; },
        domain = [d3.min(flowers, value), d3.max(flowers, value)],
        range = [padding / 2, size - padding / 2];

    x[trait]=d3.scale.linear().domain(domain).range(range);
    y[trait]=d3.scale.linear().domain(domain).range(range.reverse());
});

定義座標軸:

var axis = d3.svg.axis()
                .ticks(5)
                .tickSize(size * n);

定義刷子:

 var brush = d3.svg.brush()
                .on("brushstart", brushstart)
                .on("brush", brush)
                .on("brushend", brushend);

定義畫布:

var svg = d3.select("body").append("svg:svg")
                .attr("width", 1280)
                .attr("height", 800)
                .append("svg:g")
                .attr("transform", "translate(359.5,69.5)");

定義與繪製圖例:

 var legend = svg.selectAll("g.legend")
                .data(["setosa", "versicolor", "virginica"])
                .enter().append("svg:g")
                .attr("class", "legend")
                .attr("transform", function(d, i) { return "translate(-179," + (i * 20 + 594) + ")"; });
legend.append("svg:circle")
                .attr("class", String)
                .attr("r", 3);
legend.append("svg:text")
                .attr("x", 12)
                .attr("dy", ".31em")
                .text(function(d) { return "Iris " + d; });

座標軸繪製:

svg.selectAll("g.x.axis")
                .data(traits)
                .enter().append("svg:g")
                .attr("class", "x axis")
                .attr("transform", function(d, i) { return "translate(" + i * size + ",0)"; })
                .each(function(d) { d3.select(this).call(axis.scale(x[d]).orient("bottom")); });
svg.selectAll("g.y.axis")
                .data(traits)
                .enter().append("svg:g")
                .attr("class", "y axis")
                .attr("transform", function(d, i) { return "translate(0," + i * size + ")"; })
                .each(function(d) { d3.select(this).call(axis.scale(y[d]).orient("right")); });

主體(繪製矩陣和散點):

var cell = svg.selectAll("g.cell")
                .data(cross(traits, traits))
                .enter().append("svg:g")
                .attr("class", "cell")
                .attr("transform", function(d) { return "translate(" + d.i * size + "," + d.j * size + ")"; })
                .each(plot);

矩陣小標題:

cell.filter(function(d) { return d.i == d.j; })
                .append("svg:text")
                .attr("x", padding)
                .attr("y", padding)
                .attr("dy", ".71em")
                .text(function(d) { return d.x; });

邊框和散點繪製(function):

var cell = d3.select(this);
cell.append("svg:rect")
                .attr("class", "frame")
                .attr("x", padding / 2)
                .attr("y", padding / 2)
                .attr("width", size - padding)
                .attr("height", size - padding);
cell.selectAll("circle")
                .data(flowers)
                .enter().append("svg:circle")
                .attr("class", function(d) { return d.species; })
                .attr("cx", function(d) {
                    return x[p.x](d[p.x]);
                })//因爲比例尺是一個字典,所以要先讀取對應的比例尺,然後在讀取數據
                .attr("cy", function(d) {
                    return y[p.y](d[p.y]);
                })
                .attr("r", 3);
cell.call(brush.x(x[p.x]).y(y[p.y]));

刷子(function):

function brush(p) {
            var e = brush.extent();//定義刷子選取範圍
            svg.selectAll(".cell circle")
               .attr("class", function(d) {
                   return e[0][0] <= d[p.x] && d[p.x] <= e[1][0]&& e[0][1] <= d[p.y] && d[p.y] <= e[1][1]? d.species : null;//判斷是夠超出範圍(限定選擇邊界)
            });
        }
function brushstart(p) {
            if (brush.data !== p) {
                cell.call(brush.clear());
                brush.x(x[p.x]).y(y[p.y]).data = p;
            }
        }
function brushend() {
            if (brush.empty())
            svg.selectAll(".cell circle")
               .attr("class", function(d) {
                   return d.species;
            });
        }

定義域分配矩陣編號(function):

function cross(a, b) {
            var c = [], n = a.length, m = b.length, i, j;
            for (i = -1; ++i < n;)
                for (j = -1; ++j < m;)
                    c.push({x: a[i], i: i, y: b[j], j: j});
            return c;
        }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章