これがあなたのJSフィドル、デモの増強です:http://jsfiddle.net/robschmuecker/c8txLxo9/
あなたが持っているデータを取得し、それを解析して年のコレクションを取得するため、年に複数ではなく 1 つの 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;
});
});
}
});