0

我想使用只显示年份的时间线。我的数据的特别之处在于我只有几年。但是这些年是有序的。所以我知道确切的顺序,但不知道日期或月份之类的更多细节。

所以首先我想要这样的东西:

在此处输入图像描述

这是这些年来只有一个事件的时候。但是有很多事件应该看起来像这样:

在此处输入图像描述

那么什么是获得这个的好方法。我已经看过 d3 的时间线,但我从未见过只知道顺序的年份。

顺便说一句:稍后我将需要几个月和几天,因为几年来我实际上拥有它们。但是对于 99,9% 我没有。所以现在这些年更重要=)

Btw2:我还需要放大,范围是 0 到 2500 年左右。

一些链接:

小jsfiddle scetch

jsfiddle.net/kwoxer/z614xkgu/

几乎是我要找的

http://visjs.org/examples/timeline/29_hiding_times.html

只是项目也应被放大。

4

1 回答 1

1

这是您的 JS 小提琴的增强版,演示:http: //jsfiddle.net/robschmuecker/c8txLxo9/

它获取您拥有的数据,然后对其进行解析以获取年份集合,以便我们每年只插入一个 dom 元素而不是几个。然后我们可以有条件地添加具有多个年份的事件。它也有一个基于日期的轴,并且是可缩放的。

var dataset = [
    ["2006", 1],
    ["2009", 1],
    ["2004", 1],
    ["2004", 2],
    ["2004", 3],
    ["2012", 1],
    ["2008", 1],
    ["2004", 2],
    ["2000", 1],
    ["2006", 2],
    ["2007", 1],
    ["2001", 1]
];

//console.log(dataset, dataset.length);

var yearEvents = [];

// Firstly get all the events together for each year in the dataset
dataset.forEach(function (value) {
    var yearString = value[0] + "";
    if (typeof yearEvents[yearString] == 'undefined') yearEvents[yearString] = [];
    yearEvents[yearString].push(value[1]);
});

var newDataset = [];
yearEvents.forEach(function (year, key) {
    newDataset.push([key + "", year]);
});
//console.log('yearEvents', newDataset);

var w = 500;
var h = 300;
var padding = 20;
var circleRadius = 10;

var parseDate = d3.time.format("%Y").parse;
var mindate = parseDate("2000"),
    maxdate = parseDate("2015");

var xScale = d3.time.scale()
    .domain([mindate, maxdate])
    .range([padding, w - padding * 2]);

var yScale = d3.scale.linear()
    .domain([0, d3.max(dataset, function (d) {
    return d[1];
})])
    .range([5, 5]);

// Define the axis
var xAxis = d3.svg.axis().scale(xScale).tickSize(-h).tickSubdivide(true);


// Define the zoom function for the zoomable tree

function zoom() {
    svgGroup.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}
// define the zoomListener which calls the zoom function on the "zoom" event constrained within the scaleExtents
var zoomListener = d3.behavior.zoom().scaleExtent([0.1, 3]).on("zoom", zoom);



var svg = d3.select("body")
    .append("svg")
    .attr("width", w)
    .attr("height", h)
    .call(zoomListener);


// Append a group which holds all nodes and which the zoom Listener can act upon.
var svgGroup = svg.append("g");
svgGroup.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + (h - padding) + ")")
    .call(xAxis);

var circleGroups = svgGroup.selectAll('g.circle')
    .data(newDataset)
    .enter()
    .append('g')
    .attr("transform", function (d) {
    return "translate(" + xScale(parseDate(d[0])) + "," + (h - padding - (circleRadius * 3)) + ")";
});

var circles = circleGroups.append("circle").attr("r", circleRadius);


// Append the year value to the circles.  change `display` property to `block` in CSS to show them.
var circleTexts = circleGroups.append('text')
    .attr("class", "circle-year")
//make their horizontal position offest by half of their font-size.
.attr("dy", function () {
    return "0.25em"
})
    .attr("text-anchor", "middle")
    .text(function (d) {
    return d[0];
});

// Now add text to the ones with more than one event
circleGroups.each(function (d, i) {
    //console.log(this, d, i);
    var me = this;
    //see if it has more than one event and if so loop through them all and add the new text elements with their height separation based on their index
    if (d[1].length > 1) {
        d[1].forEach(function (event, index) {
            d3.select(me).append('text')
                .attr("dy", function () {
                return -((circleRadius * index) * 2 + padding);
            })
                .attr("text-anchor", "middle")
                .text(function (d) {
                return event;
            });
        });
    }
});
于 2015-03-04T12:23:47.313 回答