gpt4 book ai didi

javascript - 在甘特图 d3.js 顶部绘制多条线

转载 作者:行者123 更新时间:2023-11-28 15:31:06 25 4
gpt4 key购买 nike

我正在构建这个甘特图,我在 block 上找到了一个示例:

https://bl.ocks.org/arpitnarechania/4b4aa79b04d2e79f30765674b4c24ace

效果很好。我只想在“任务”顶部添加一条垂直线,以指示在任务进行时发生的其他一些事件。这个想法是在矩形上画一条垂直线: enter image description here

我唯一不确定的是如何处理从时间戳数组中绘制多条线。我知道目前我正在使用 d.synched[0] 因此只有一行,但我如何更改它以绘制与时间戳一样多的行。

这是我的 JSBIN:https://jsbin.com/layecehidu/edit?js,console,output

我们将不胜感激任何帮助!

最佳答案

无需过多更改代码的最简单解决方案是为 data 中的每个对象创建一个组:

var lineGroup = svg.selectAll(null)
.data(data)
.enter()
.append("g");

然后根据这些组的数据创建线条:

var lines = lineGroup.selectAll(null)
.data(function(d) {
return d.synched
})
.enter()
.append("line")
.style("stroke", "red")
.attr("x1", function(d) {
console.log(d);
return x(parseDate(d));
})
.attr("y1", function(d) {
var parentDatum = d3.select(this.parentNode).datum();
return y(parentDatum.category) - 5;
})
.attr("x2", function(d) {
return x(parseDate(d));
})
.attr("y2", function(d) {
var parentDatum = d3.select(this.parentNode).datum();
return y(parentDatum.category) + y.rangeBand() + 5;
});

这是更新后的代码:

var parseDate = d3.time.format("%d-%b-%y").parse;

var data = [{
"category": "Task 1",
"from": "1-Jan-17",
"to": "15-Jan-17",
"progress": 100,
"synched": ["5-Jan-17", "7-Jan-17"]
}, {
"category": "Task 2",
"from": "13-Jan-17",
"to": "1-Feb-17",
"progress": 60,
"synched": ["15-Jan-17"]
}, {
"category": "Task 1",
"from": "1-Feb-17",
"to": "11-Mar-17",
"progress": 90,
"synched": ["2-Feb-17", "4-Feb-17"]
}]

var types_of_statuses = ["Completed", "Remaining"];
var statuses_color = ["#2ecc71", "#e74c3c"];

data.forEach(function(d) {
d.from = parseDate(d.from);
d.to = parseDate(d.to);
});
var margin = {
top: 50,
right: 50,
bottom: 50,
left: 100
},
width = 900 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;

var y = d3.scale.ordinal()
.rangeRoundBands([0, height], 0.2);

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

y.domain(data.map(function(d) {
return d.category;
}));
x.domain([d3.min(data, function(d) {
return d.from;
}), d3.max(data, function(d) {
return d.to;
})]);

var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(15)
.tickFormat(d3.time.format("%d%b"));

var yAxis = d3.svg.axis()
.scale(y)
.orient("left");

var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

svg.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("y", function(d) {
return y(d.category);
})
.attr("height", y.rangeBand())
.attr("x", function(d) {
return x(d.from);
})
.attr("width", function(d) {
return x(d.to) - x(d.from);
});

var lineGroup = svg.selectAll(null)
.data(data)
.enter()
.append("g");

var lines = lineGroup.selectAll(null)
.data(function(d) {
return d.synched
})
.enter()
.append("line")
.style("stroke", "red")
.attr("x1", function(d) {
return x(parseDate(d));
})
.attr("y1", function(d) {
var parentDatum = d3.select(this.parentNode).datum();
return y(parentDatum.category) - 5;
})
.attr("x2", function(d) {
return x(parseDate(d));
})
.attr("y2", function(d) {
var parentDatum = d3.select(this.parentNode).datum();
return y(parentDatum.category) + y.rangeBand() + 5;
});


svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.append("text")
.attr("x", width - margin.right)
.attr("dx", ".71em")
.attr("dy", "-0.2em")
.text("Date");

svg.append("g")
.attr("class", "y axis")
.call(yAxis);
.pending {
fill: #e74c3c;
}

.bar {
fill: #2ecc71;
}

/* .bar:hover, .pending:hover {
fill: #3498db;
} */

.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}

.legend {
padding: 5px;
font: 16px sans-serif;
background: yellow;
box-shadow: 2px 2px 1px #888;
}

.tooltip {
background: #eee;
box-shadow: 0 0 5px #999999;
color: #333;
font-size: 12px;
left: 130px;
padding: 10px;
position: absolute;
text-align: center;
top: 95px;
z-index: 10;
display: block;
opacity: 0;
}
.axis,
.frame {
shape-rendering: crispEdges;
}

.axis path {
fill: none;
stroke: grey;
shape-rendering: crispEdges;
}

.axis text {
font-family: Arial;
font-size: 10px;
}

.axis line {
fill: none;
stroke: grey;
stroke-width: 1;
shape-rendering: crispEdges;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

请注意,为了获取每一行的类别,我们必须在行选择中访问父级的数据(即组)。

如果需要,另一种选择是用父级(组)的数据填充行的数据,如下所示:

var lines = lineGroup.selectAll(null)
.data(function(d) {
return d.synched.map(function(e) {
return {
syn: e,
cat: d.category
};
})
})
.enter()
.append("line")
.style("stroke", "red")
.attr("x1", function(d) {
return x(parseDate(d.syn));
})
.attr("y1", function(d) {
return y(d.cat) - 5;
})
.attr("x2", function(d) {
return x(parseDate(d.syn));
})
.attr("y2", function(d) {
return y(d.cat) + y.rangeBand() + 5;
});

关于javascript - 在甘特图 d3.js 顶部绘制多条线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44681239/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com