Finance Viz

Hello. I’m trying to use an input to update a chart via the d3 .join mechanism. I believe I have most things correct but I can only make the axes populate and adjust. It seems like the .drawData function is being called, but something about my code won’t append the rectangles.

Like most semi-able d3 users, I’m cannibalizing existing examples, in this case:

and

Any advice appreciated!

Can I ask why you chose to use D3 directly? Observable’s Plot library sits on top of D3 and makes it quite a bit easier to create this type of chart.

Using Plot, you’d first normalize your data so that you have one row per date and account:

data = vizinput.flatMap(({ event_date, ...accounts }) => {
  const date = d3.utcParse("%m/%d/%Y")(event_date);
  return Object.entries(accounts).map(
    ([ account, amount ]) => ({ date, account, amount })
  );
})

Then you’d create the chart with

Plot.plot({
  marks: [
    Plot.barY(data2, {x: "date", y: "amount", fill: "account"}),
    Plot.ruleY([0])
  ],
  color: { legend: true },
  marginBottom: 70,
  marginRight: 50,
  x: { type: "band", tickRotate: 40 },
  color: { legend: true }
})

giving you this output:

Thanks! I guess I didn’t look outside d3 bc I figured additional customizations might get me into the same dead ends I’d encountered with other potential solutions. d3 has a steep learning curve (for me at least) but there’s nothing it can’t do. I’ll look at adopting your above solution with Plot, but, for my education, do you know what I’m doing wrong with my .join error above?

A couple of things, I’m afraid. For starters, d3.stack() gives you an entry for each stack, but you attempt to process series as if it were a flat array of entries, creating one rect per stack (instead of per value). I recommend to take a another look at the gist that you linked (you can also view it here) and pay close attention to the second enter().