我有一个如下所示的数组:
[
{
"name": "Omayeli Arenyeka",
"positions":[
{
"start": 1993,
"end": 2002,
"title":"Senator of Abia"
},
{
"start": 1993,
"end": 2002,
"title":"President"
}
]
},
{
"name": "John Cena",
"positions":[
{
"start": 1993,
"end": 2002,
"title":"Senator of Abia"
},
{
"start": 2004,
"end": 2007,
"title":"President"
}
]
}
];
对于y轴上的每个名称,我想为位置数组中的每个项目绘制,横跨x轴的水平线(因此对于Omayeli Arenyeka,从1993年开始然后在2002年结束,然后是另一个从2003-2007开始的行)我不希望连接线。
这就是我目前所拥有的:
var parseDate = d3.time.format("%Y").parse;
var maxyear = new Date("2017");
var minyear = new Date("1980");
var xScale = d3.time.scale()
.domain([minyear, maxyear])
.range([padding, width - padding]);
var yScale = d3.scale.ordinal()
.range([height - padding, padding]); // map these to the chart height, less padding.
//REMEMBER: y axis range has the bigger number first because the y value of zero is at the top of chart and increases as you go down.
// define the y axis
var yAxis = d3.svg.axis()
.orient("left")
.scale(yScale);
// define the y axis
var xAxis = d3.svg.axis()
.orient("bottom")
.scale(xScale)
.tickFormat(d3.time.format("%Y")); // <-- format
d3.json("data/politicians.json", function(error, data) {
if (error) throw error;
yScale.domain(data.map(function(d) {
console.log(d.name);
return d.name;
})).rangeRoundBands([0, height - padding]);
// draw x axis with labels and move to the bottom of the chart area
vis.append("g")
.attr("class", "xaxis") // give it a class so it can be used to select only xaxis labels below
.attr("transform", "translate(0," + (height - padding) + ")")
.call(xAxis);
// draw y axis with labels and move in from the size by the amount of padding
vis.append("g")
.attr("class", "yaxis")
.attr("transform", "translate(" + padding + ",0)")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", -36)
.attr("x", -36)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Politicians");
var line = {
'x1':(function(d) {
return xScale();
}),
'y1':(function(d) { return yScale(d.name); }),
'x2':(function(d) {
return xScale();
}),
'y2':(function(d) { return yScale(d.name); }),
}
});
答案 0 :(得分:0)
D3中最重要的是将数据绑定到元素。关于这一点,你有很多参考资料。
简而言之,您需要输入&#34;输入&#34;选择。
在这里,我将设置两个输入选择:一个为每个政治家创建<g>
个元素,另一个为每个政治家为每个位置创建<line>
元素:
var groups = vis.selectAll("foo")
.data(data)
.enter()
.append("g")
.attr("transform", function(d) {
return "translate(0," + (padding[2] + yScale(d.name)) + ")";
});
var people = groups.selectAll("foo")
.data(d => d.positions)
.enter()
.append("line");
因此,我们使用d.name
,d.start
和d.end
附加行。这是演示:
var data = [{
"name": "Omayeli Arenyeka",
"positions": [{
"start": 1993,
"end": 2002,
"title": "Senator of Abia"
}, {
"start": 1993,
"end": 2002,
"title": "President"
}]
}, {
"name": "John Cena",
"positions": [{
"start": 1993,
"end": 2002,
"title": "Senator of Abia"
}, {
"start": 2004,
"end": 2007,
"title": "President"
}]
}];
var width = 500,
height = 200,
padding = [10, 10, 30, 130];
var color = d3.scale.category10();
var vis = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);
var parseDate = d3.time.format("%Y").parse;
var maxyear = new Date("2017");
var minyear = new Date("1980");
var xScale = d3.time.scale()
.domain([minyear, maxyear])
.range([padding[3], width - padding[1]]);
var yScale = d3.scale.ordinal()
.rangePoints([height - padding[2], padding[0]], 1.5)
.domain(data.map(function(d) {
return d.name;
})); // map these to the chart height, less padding.
//REMEMBER: y axis range has the bigger number first because the y value of zero is at the top of chart and increases as you go down.
// define the y axis
var yAxis = d3.svg.axis()
.orient("left")
.scale(yScale);
// define the y axis
var xAxis = d3.svg.axis()
.orient("bottom")
.scale(xScale)
.tickFormat(d3.time.format("%Y")); // <-- format
// draw x axis with labels and move to the bottom of the chart area
vis.append("g")
.attr("class", "xaxis") // give it a class so it can be used to select only xaxis labels below
.attr("transform", "translate(0," + (height - padding[2]) + ")")
.call(xAxis);
// draw y axis with labels and move in from the size by the amount of padding
vis.append("g")
.attr("class", "yaxis")
.attr("transform", "translate(" + padding[3] + ",0)")
.call(yAxis);
var groups = vis.selectAll("foo")
.data(data)
.enter()
.append("g")
.attr("transform", function(d) {
return "translate(0," + (yScale(d.name)) + ")";
})
.style("stroke", (d, i) => color(i));
var people = groups.selectAll("foo")
.data(d => d.positions)
.enter()
.append("line");
var line = people.attr({
'x1': function(d) {
return xScale(parseDate(d.start.toString()));
},
'x2': function(d) {
return xScale(parseDate(d.end.toString()));
}
}).attr("stroke-width", 2);
&#13;
.xaxis line, .yaxis line,
.xaxis path, .yaxis path {
fill: none;
stroke: black;
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
&#13;