2

I'm following this example 3 and it depends on gantt-chart lib, but apparently it's not compatible with version d3v4 and there are errors with the axis. So I found this ported to d3v4 and manually download the js to my project. The axis work now, but the button doesn't work fine anymore.

I would love to look into a document for this great Gantt chart lib, but I can't find an official gantt-chart that is d3v4 compatible.

I can't find more update about it except for this:

Will paste the codepen in comment

Any help is much appreciated as it's off to me that there's little info about this library.

Elly
  • 145
  • 7

1 Answers1

2

D3 is currently on version 7. Rather than using updating version 3 code to version 4, I recommend that you use more up to date tools. The creator and maintainers of D3 have created Observable Plot, which makes it pretty easy to generate your Gantt chart:

enter image description here

That image was generated with the following Observable notebook:

https://observablehq.com/d/c0b0c36900635680

Alternatively, you can generate it in vanilla JS in a webpage:

function make_gantt_chart(task_data) {
  let p = Plot.plot({
      width: 900,
      height: 500,
      y: { domain: ["D Job", "P Job", "E Job", "A Job", "N Job"] },
      marks: [
        Plot.barX(task_data, {
          x1: "startDate",
          x2: "endDate",
          y: "taskName",
          rx: 5,
          fill: function (d) {
            if (d.status == "RUNNING") {
              return "#669900";
            } else if (d.status == "FAILED") {
              return "#CC0000";
            } else if (d.status == "KILLED") {
              return "#ffbb33";
            } else if (d.status == "SUCCEEDED") {
              return "#33b5e5";
            } else {
              return "#33b5e5";
            }
          }
        }),
        Plot.ruleY(["N Job"]),
        Plot.ruleX([d3.min(tasks.map((t) => t.startDate))])
      ]
    });

    d3.select(p)
      .select('g[aria-label="rule"]')
      .attr("transform", `translate(0,${p.scale("y").bandwidth})`);    
   d3.select('#container').append(() => p)
}

let tasks = [
  {
    startDate: new Date("Sun Dec 09 01:36:45 EST 2012"),
    endDate: new Date("Sun Dec 09 02:36:45 EST 2012"),
    taskName: "E Job",
    status: "RUNNING"
  },
  {
    startDate: new Date("Sun Dec 09 04:56:32 EST 2012"),
    endDate: new Date("Sun Dec 09 06:35:47 EST 2012"),
    taskName: "A Job",
    status: "RUNNING"
  },
  {
    startDate: new Date("Sun Dec 09 06:29:53 EST 2012"),
    endDate: new Date("Sun Dec 09 06:34:04 EST 2012"),
    taskName: "D Job",
    status: "RUNNING"
  },
  {
    startDate: new Date("Sun Dec 09 05:35:21 EST 2012"),
    endDate: new Date("Sun Dec 09 06:21:22 EST 2012"),
    taskName: "P Job",
    status: "RUNNING"
  },
  {
    startDate: new Date("Sun Dec 09 05:00:06 EST 2012"),
    endDate: new Date("Sun Dec 09 05:05:07 EST 2012"),
    taskName: "D Job",
    status: "RUNNING"
  },
  {
    startDate: new Date("Sun Dec 09 03:46:59 EST 2012"),
    endDate: new Date("Sun Dec 09 04:54:19 EST 2012"),
    taskName: "P Job",
    status: "RUNNING"
  },
  {
    startDate: new Date("Sun Dec 09 04:02:45 EST 2012"),
    endDate: new Date("Sun Dec 09 04:48:56 EST 2012"),
    taskName: "N Job",
    status: "RUNNING"
  },
  {
    startDate: new Date("Sun Dec 09 03:27:35 EST 2012"),
    endDate: new Date("Sun Dec 09 03:58:43 EST 2012"),
    taskName: "E Job",
    status: "SUCCEEDED"
  },
  {
    startDate: new Date("Sun Dec 09 01:40:11 EST 2012"),
    endDate: new Date("Sun Dec 09 03:26:35 EST 2012"),
    taskName: "A Job",
    status: "SUCCEEDED"
  },
  {
    startDate: new Date("Sun Dec 09 03:00:03 EST 2012"),
    endDate: new Date("Sun Dec 09 03:09:51 EST 2012"),
    taskName: "D Job",
    status: "SUCCEEDED"
  },
  {
    startDate: new Date("Sun Dec 09 01:21:00 EST 2012"),
    endDate: new Date("Sun Dec 09 02:51:42 EST 2012"),
    taskName: "P Job",
    status: "SUCCEEDED"
  },
  {
    startDate: new Date("Sun Dec 09 01:08:42 EST 2012"),
    endDate: new Date("Sun Dec 09 01:33:42 EST 2012"),
    taskName: "N Job",
    status: "FAILED"
  },
  {
    startDate: new Date("Sun Dec 09 00:27:15 EST 2012"),
    endDate: new Date("Sun Dec 09 00:54:56 EST 2012"),
    taskName: "E Job",
    status: "SUCCEEDED"
  },
  {
    startDate: new Date("Sun Dec 09 00:29:48 EST 2012"),
    endDate: new Date("Sun Dec 09 00:44:50 EST 2012"),
    taskName: "D Job",
    status: "SUCCEEDED"
  },
  {
    startDate: new Date("Sun Dec 09 07:39:21 EST 2012"),
    endDate: new Date("Sun Dec 09 07:43:22 EST 2012"),
    taskName: "P Job",
    status: "RUNNING"
  },
  {
    startDate: new Date("Sun Dec 09 07:00:06 EST 2012"),
    endDate: new Date("Sun Dec 09 07:05:07 EST 2012"),
    taskName: "D Job",
    status: "RUNNING"
  },
  {
    startDate: new Date("Sun Dec 09 08:46:59 EST 2012"),
    endDate: new Date("Sun Dec 09 09:54:19 EST 2012"),
    taskName: "P Job",
    status: "RUNNING"
  },
  {
    startDate: new Date("Sun Dec 09 09:02:45 EST 2012"),
    endDate: new Date("Sun Dec 09 09:48:56 EST 2012"),
    taskName: "N Job",
    status: "RUNNING"
  },
  {
    startDate: new Date("Sun Dec 09 08:27:35 EST 2012"),
    endDate: new Date("Sun Dec 09 08:58:43 EST 2012"),
    taskName: "E Job",
    status: "SUCCEEDED"
  },
  {
    startDate: new Date("Sun Dec 09 08:40:11 EST 2012"),
    endDate: new Date("Sun Dec 09 08:46:35 EST 2012"),
    taskName: "A Job",
    status: "SUCCEEDED"
  },
  {
    startDate: new Date("Sun Dec 09 08:00:03 EST 2012"),
    endDate: new Date("Sun Dec 09 08:09:51 EST 2012"),
    taskName: "D Job",
    status: "SUCCEEDED"
  },
  {
    startDate: new Date("Sun Dec 09 10:21:00 EST 2012"),
    endDate: new Date("Sun Dec 09 10:51:42 EST 2012"),
    taskName: "P Job",
    status: "SUCCEEDED"
  },
  {
    startDate: new Date("Sun Dec 09 11:08:42 EST 2012"),
    endDate: new Date("Sun Dec 09 11:33:42 EST 2012"),
    taskName: "N Job",
    status: "FAILED"
  },
  {
    startDate: new Date("Sun Dec 09 12:27:15 EST 2012"),
    endDate: new Date("Sun Dec 09 12:54:56 EST 2012"),
    taskName: "E Job",
    status: "SUCCEEDED"
  },
  {
    startDate: new Date("Sat Dec 08 23:12:24 EST 2012"),
    endDate: new Date("Sun Dec 09 00:26:13 EST 2012"),
    taskName: "A Job",
    status: "KILLED"
  }
];

make_gantt_chart(tasks)
<script src="https://cdn.jsdelivr.net/npm/d3@7"></script>
<script src="https://cdn.jsdelivr.net/npm/@observablehq/plot@0.6"></script>

<div id="container"></div>
Mark McClure
  • 4,862
  • 21
  • 34
  • Thank you for the snippet. I notice it's using `observable plot` so we can't use d3's `join` for filtering (I need to filter date and task name). How do we do with `plot` so it works the same way as the d3 data join? – Elly Nov 28 '22 at 14:50
  • @Elly Simply filter the data with [standard array tools](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter), e.g. `tasks = tasks.filter(d => ...)`. – Mark McClure Nov 28 '22 at 15:18
  • It's a nice reproduction. I worked more on filtering (https://observablehq.com/d/5d2417c1ef6f939f) but I'll apply it in a web app project without Observable's automatic event handlers. Is it possible to put it in a method so that when onChange, I can call the method with new data (something like `onChange() { ... return Gantt(newData); }`? – Elly Nov 28 '22 at 21:25
  • @Elly Of course! I modified the snippet so you can see how to wrap it in a function. – Mark McClure Nov 28 '22 at 21:35