颜色编码平行坐标

时间:2014-07-17 19:23:59

标签: javascript d3.js parallel-coordinates

我已经有了绘制平行坐标的代码,效果很好。我可以为某些功能绘制平行坐标(label, feature1, feature2, ..., feature5:我的数据库的某些特定列)。

在我的测试输入文件中,label功能的值为1,2或3.现在,我想删除label轴,而是使用3种颜色对并行进行颜色编码坐标可视化。我不知道该怎么做。如果你能帮助我,我将感激不尽。

var m = [30, 10, 10, 10],
    w = 800 - m[1] - m[3],
    h = 500 - m[0] - m[2];

var x = d3.scale.ordinal().rangePoints([0, w], 1),
    y = {},
    dragging = {};

var line = d3.svg.line(),
    axis = d3.svg.axis().orient("left"),
    background,
    foreground;

var svg = d3.select("body").append("svg:svg")
    .attr("width", w + m[1] + m[3])
    .attr("height", h + m[0] + m[2])
    .append("svg:g")
    .attr("transform", "translate(" + m[3] + "," + m[0] + ")");

// Input data (test.csv) is in this link : http://pastebin.com/raw.php?i=8nTGRenj
d3.csv("test.csv").row(function (d) {
    return {
        // Features that are needed to be visualize
        label: d.label,

        feature1: d.feature1,
        feature2: d.feature2,
        feature3: d.feature3,
        feature4: d.feature4,
        feature5: d.feature5
    };
})
    .get(function (e, data) {
    x.domain(
    dimensions = d3.keys(data[0])
        .filter(function (d) {
        if (d == "label") {
            y[d] = d3.scale.linear()
                .domain(d3.extent(data, function (p) {
                return +p[d];
            }))
                .range([h, 0]);
        } else {
            y[d] = d3.scale.linear()
                .domain([0, 100])
                .range([h, 0]);
        }
        return true;
    }));

    // Add grey background lines for context.
    background = svg.append("svg:g")
        .attr("class", "background")
        .selectAll("path")
        .data(data)
        .enter().append("svg:path")
        .attr("d", path);

    // Add blue foreground lines for focus.
    foreground = svg.append("svg:g")
        .attr("class", "foreground")
        .selectAll("path")
        .data(data)
        .enter().append("svg:path")
        .attr("d", path);

    // Add a group element for each dimension.
    var g = svg.selectAll(".dimension")
        .data(dimensions)
        .enter().append("svg:g")
        .attr("class", "dimension")
        .attr("transform", function (d) {
        return "translate(" + x(d) + ")";
    })
        .call(d3.behavior.drag()
        .on("dragstart", function (d) {
        dragging[d] = this.__origin__ = x(d);
        background.attr("visibility", "hidden");
    })
        .on("drag", function (d) {
        dragging[d] = Math.min(w, Math.max(0, this.__origin__ += d3.event.dx));
        foreground.attr("d", path);
        dimensions.sort(function (a, b) {
            return position(a) - position(b);
        });
        x.domain(dimensions);
        g.attr("transform", function (d) {
            return "translate(" + position(d) + ")";
        });
    })
        .on("dragend", function (d) {
        delete this.__origin__;
        delete dragging[d];
        transition(d3.select(this)).attr("transform", "translate(" + x(d) + ")");
        transition(foreground)
            .attr("d", path);
        background.attr("d", path)
            .transition()
            .delay(500)
            .duration(0)
            .attr("visibility", null);
    }));

    // Add an axis and title.
    g.append("svg:g")
        .attr("class", "axis")
        .each(function (d) {
        d3.select(this).call(axis.scale(y[d]));
    })
        .append("svg:text")
        .attr("text-anchor", "middle")
        .attr("y", -9)
        .text(String);

    // Add and store a brush for each axis.
    g.append("svg:g")
        .attr("class", "brush")
        .each(function (d) {
        d3.select(this).call(y[d].brush = d3.svg.brush().y(y[d]).on("brush", brush));
    })
        .selectAll("rect")
        .attr("x", -8)
        .attr("width", 16);
});

function position(d) {
    var v = dragging[d];
    return v === null ? x(d) : v;
}

function transition(g) {
    return g.transition().duration(500);
}

// Returns the path for a given data point.
function path(d) {
    return line(dimensions.map(function (p) {
        return [position(p), y[p](d[p])];
    }));
}

// Handles a brush event, toggling the display of foreground lines.
function brush() {
    var actives = dimensions.filter(function (p) {
        return !y[p].brush.empty();
    }),
        extents = actives.map(function (p) {
            return y[p].brush.extent();
        });
    foreground.style("display", function (d) {
        return actives.every(function (p, i) {
            return extents[i][0] <= d[p] && d[p] <= extents[i][1];
        }) ? null : "none";
    });
}

这是我的一大块数据:

path,Ktype,label,CGX,CGY,C_1,C_2,C_3,C_4,total1,total2,totalI3,total4,feature1,feature2,feature3,feature4,feature5,A,B,C,D,feature6,feature7,
.\Mydata\Case1,k1,1,42,33,0,57.44534,0,52597,71,16,10,276,74,67,69,33,16,1,0,0,1,9.60E-05,3136.698,
.\Mydata\Case2,k1,3,163,29,0,43.28862,0,49050,71,16,10,248,21,89,8,56,21,1,0,0,1,0.00010854,2676.418,
.\Mydata\Case3,k1,2,774,19,0,45.26291,0,53455,71,16,10,212,35,19,79,45,94,1,1,0,0,9.54E-05,3221.289,
.\Mydata\Case4,k1,1,1116,25,0,80.76469,0,57542,71,16,10,284,73,34,17,48,44,0,1,1,0,0.000140592,2143.42,
.\Mydata\Case5,k1,2,1364,59,1,52.96776,0,49670,71,16,10,228,39,26,55,41,71,0,1,1,0,0.00012014,2439.636,
.\Mydata\Case6,k1,3,1364,59,1,52.96776,0,49670,71,16,10,228,27,38,55,52,71,0,1,1,0,0.00012014,2439.636,
.\Mydata\Case7,k1,1,1364,59,1,52.96776,0,49670,71,16,10,228,89,33,5,17,37,0,1,1,0,0.00012014,2439.636,
.\Mydata\Case8,k1,1,1364,59,1,52.96776,0,49670,71,16,10,228,12,22,10,7,12,0,1,1,0,0.00012014,2439.636

此外,您可以在此处找到我的代码:http://jsfiddle.net/SaraJS/ubBwY/10/

(另外,&#34; test.csv&#34;是here;我无法将其链接到我的代码。)

1 个答案:

答案 0 :(得分:1)

我无法让你的榜样上班,但我可以告诉你该怎么做。

首先,您需要创建一个颜色比例,这是一个序数比例。然后,您可以将域设置为输入值的数组(在您的情况下为1,2和3),范围应该是与这些输入对应的颜色。例如:

var color = d3.scale.ordinal()
  .domain([1,2,3])
  .range(['red','green','blue']);

然后,当您创建path元素时,您可以使用比例使笔触颜色成为标签数据的函数:

foreground = svg.append('svg:g')
  .attr('class', 'foreground')
  .selectAll('path')
  .data(data)
  .enter().append('svg:path')
  .attr('d', path)
  .attr('stroke', function(d) { return color(d.label); });

然后只需确保从css中删除前景的笔触样式,这样它就不会覆盖缩放提供的值。

Here's an example使用来自this example的汽车数据的子集。