沿x轴布局时间节点

时间:2015-02-19 23:04:42

标签: d3.js

我写了一小段代码(Jsfiddle),其中每个点代表x轴上的数据点。 x轴的位置基于日期+时间计算。问题是点在x轴上的分布方式:大的空间仍未使用,并且点相互遮挡。虽然空间位置只是为了显示它们的相对时间,但是,确切的距离在这里并不重要。你能告诉我如何处理这个问题的任何解决方案或算法吗?

var graphData = [
    {
        session: 1,
        children: [
            {id: 11, time: "2015-12-18 15:00:00", adjList: [{id: 21, w: 0.5}, {id: 24, w: 0.8}]},
            {id: 12, time: "2015-12-18 15:01:32", adjList: []},
            {id: 13, time: "2015-12-18 15:03:40", adjList: [{id: 32, w: 0.4}]},
            {id: 14, time: "2015-12-18 15:05:04", adjList: []}]
    },
    {
        session: 2,
        children: [
            {id: 21, time: "2015-12-18 08:55:00", adjList: []},
            {id: 22, time: "2015-12-18 08:59:10", adjList: [{id: 14, w: 0.6}]},
            {id: 23, time: "2015-12-18 09:02:00", adjList: [{id: 11, w: 0.2}]},
            {id: 24, time: "2015-12-18 09:06:45", adjList: [{id: 32, w: 0.7}]}]
    },
    {
        session: 3,
        children: [
            {id: 31, time: "2015-12-18 08:40:50", adjList: []},
            {id: 32, time: "2015-12-18 08:43:00", adjList: [{id: 24, w: 0.1}, {id: 13, w: 0.3}]}]
    },
    {
        session: 4,
        children: [
            {id: 41, time: "2015-12-18 16:00:00", adjList: [{id: 31, w: 0.01}]},
            {id: 42, time: "2015-12-18 16:09:12", adjList: [{id: 31, w: 0.15}]},
            {id: 43, time: "2015-12-18 16:09:55", adjList: [{id: 22, w: 0.95}]}]
    },
];


/*
 * SVG
 */
var margin = {top: 50, right: 50, bottom: 50, left: 50},
    width = 1000 + margin.left + margin.right,
    height = 200 + margin.top + margin.bottom,
    xPos = 500, yPos = 100;

var svg = d3.select("#fcgraph")
    .append("svg")
    .attr("x", xPos)
    .attr("y", yPos)
    .attr("width", width)
    .attr("height", height);
var svgGroup = svg.append("g")
    .attr("transform", "translate(" + 10 + "," + height / 2 + ")");


/*
 * Scale
 */
var parseDate = d3.time.format("%Y-%m-%d %H:%M:%S").parse;
var times = [];

graphData.forEach(function (d, i) {
    d.children.forEach(function (c, i) {
        times.push(parseDate(c.time));
    })
})

var x = d3.time.scale()
    .range([0, width]);

x.domain(d3.extent(times, function(d) {
    return d;
}));

// calc pos in x axis
var nodes = [];
graphData.forEach(function (d, i) {
    var session = d.session;
    d.children.forEach(function (c, i) {
        nodes.push({id: c.id, 
                    session: session, 
                    pos: {x: x(parseDate(c.time)), y: 50}
                   });
    }) // foreach
}) // foreach


/*
 * Draw the nodes.
 */

var nodeColor = d3.scale.category10();

var circle = svgGroup.selectAll(".circle")
    .data(nodes)
    .enter()
    .append("g")
    .attr("class", "circle");

circle.append("circle")
    .attr("cx", function (d) {
        return d.pos.x;
    })
    .attr("cy", function (d) {
        return d.pos.y;
    })
    .attr("r", 10)
    .style("fill", function (d) {
        return nodeColor(d.session);
    })
    .append("title").text(function (d) {
        return d.id;
    });

// Label
circle.append("text")
    .attr("x", function (d) {
        return d.pos.x;
    })
    .attr("y", function (d) {
        return d.pos.y;
    })
    .attr("font-size", "10px")
    .attr("fill", "white")
    .text(function (d) {
        return d.id;
    });

1 个答案:

答案 0 :(得分:0)

你可以使用多线性(或多时间尺度)来玩。

只需构建一个新的多时间尺度:

var xMod = x.copy().range([0,width/4,width/2,width]);

xMod.domain([
    parseDate("2015-12-18 08:40:50"),
    parseDate("2015-12-18 10:00:00"),
    parseDate("2015-12-18 15:05:04"),
    parseDate("2015-12-18 16:09:55"),
     ]);

并且,使用它来映射值而不是x。

来源:

http://bl.ocks.org/herrstucki/5403383