[英]Create grouped items within swimlane on D3.js timeline chart
我在这篇文章中使用了来自@cezar 的一个示例,该示例非常出色为 D3.js 中不同宽度的波段创建比例。 我添加了一个画笔来移动时间线,并将 svg 更改为响应式,但代码几乎相同。
问题
我想让某些活动出现在同一行,如果它们是相同的活动名称,那么在每个泳道中,活动都会被分组。
我假设我需要首先在偏移处进行分组以获得正确的行数,但完全可以让它工作。
const offset = [0]
data.forEach(function (d) {
const act = d3.group(d, (a) => a.activity);
console.log([...act].length);
this.push([...act].length);
}, offset);
这是我用所做的更改创建的小提琴。 我也在小提琴中做了解释,并附上了一张图片来解释所需的结果。
小提琴:时间线小提琴
希望这一切都有意义。
您应该修改您的数据 model :
到现在为止,您已经有了“项目”(或“活动”)和“组”,并使用scaleBand (将项目分组到组中)渲染它们。 那 model 是错误的。
您需要做的是,它首先将您的项目(通过group
属性)聚合到另一个对象数组中(我们称它们为groupedActivities )。 现在,您具有以下数据层次结构:
组(数据库、前端)->分组活动(mySql、Postgres)->活动(mySql.1、mySql.2)etc
现在您以类似的方式呈现它们,除了活动(它们的 Y position 由父 object 定义,X 由开始/结束时间定义)
好的,我已经让它工作了,尽管我很确定我已经把它弄得太复杂了。 感觉就像我有太多的.each迭代和太多的代码。
我也没有使用 d3.js 来按多个字段分组,但是我在其他地方找到了 javascript。 这里是按多个字段排序。
Array.prototype.groupBy = function (props) {
var arr = this;
var partialResult = {};
arr.forEach((el) => {
var grpObj = {};
props.forEach((prop) => {
grpObj[prop] = el[prop];
});
var key = JSON.stringify(grpObj);
if (!partialResult[key]) partialResult[key] = [];
partialResult[key].push(el);
});
var finalResult = Object.keys(partialResult).map((key) => {
var keyObj = JSON.parse(key);
keyObj.values = partialResult[key];
return keyObj;
});
return finalResult;
};
let data = projects.groupBy(["group", "activity"]);
data = d3.group(data, (d) => d.group);
然而,它正在工作,尽管我提到了重叠的问题,这是我所期待的。 这不是什么大问题,因为我可以管理这是数据。
如果有人能够弄清楚如何处理重叠,那就太好了。 例如,这似乎只是使用上面的分组部分并将活动重命名为mySql_2的一种情况。
再次感谢让我开始使用此功能的代码示例以及有关如何解决问题的建议。
这是更新的小提琴。 我已将填充不透明度设为 0.5,以便您可以清楚地看到重叠。
小提琴: D3.js 时间线 Gantt_v2
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.