victory icon indicating copy to clipboard operation
victory copied to clipboard

How to chart date ranges with bars

Open andy-root opened this issue 1 year ago • 7 comments

Is there an existing issue for this?

  • [X] I have searched the existing issues

Code of Conduct

  • [X] I agree to follow this project's Code of Conduct

Question

I would like to chart date ranges using bar widths where y is a constant and x are dates, the width of the bar represents the date range of an event. I'm not sure what the best way to do this is.

I tried using a VictoryBar where I would set the y to a constant like 500 and the x would be the date.

https://codesandbox.io/p/sandbox/bar-chart-date-ranges-3v86cm

import { VictoryBar, VictoryChart, VictoryLine } from "victory";

const data = [
  { date: "1/1/24", event: false },
  { date: "1/2/24", event: false },
  { date: "1/3/24", event: true },
  { date: "1/4/24", event: true },
  { date: "1/5/24", event: true },
  { date: "1/6/24", event: false },
  { date: "1/7/24", event: false },
  { date: "1/8/24", event: true },
  { date: "1/9/24", event: true },
];

export default function App() {
  return (
    <VictoryChart>
      <VictoryBar
        data={data}
        x={"date"}
        y={(d) => (d.event ? 500 : 0)}
        style={{ data: { fill: "#CDCDCD", borderRadius: 0 } }}
        cornerRadius={0}
        barWidth={45}
        events={[
          {
            target: "data",
            eventHandlers: {
              onMouseOut: () => [
                {
                  target: "data",
                  mutation: () => ({ style: { fill: "#CDCDCD" } }),
                },
              ],
              onMouseOver: () => [
                {
                  target: "data",
                  mutation: () => ({ style: { fill: "#DAF0FF" } }),
                },
              ],
            },
          },
        ]}
      />
    </VictoryChart>
  );
}

Its not the best solution because it renders multiple bars for each date range and I would have to set a width constant so the bars overlap to give the impression of a single wide bar. The same issue with mouseover events, there are multiple bars instead of one for a range. Is there a chart where the width of the bar can be set based on the X values? like spanning 3 ticks for an event that spans 3 dates or set a start tick and an end tick per bar based on event start and end? I now I can set the bar width using a function but that would require knowing how wide to make it to match the ticks.

andy-root avatar Mar 22 '24 01:03 andy-root

I'm having trouble visualizing what type of chart you are looking for, could you mock something in a graphics drawing program? Are you looking for something like a stacked horizontal chart?

carbonrobot avatar Mar 23 '24 12:03 carbonrobot

The stacked horizontal chart may work, I only want bars for date ranges that are true, if false I don't want to show a bar. The bar height must be adjusted to a static height. Below is maybe a clearing description.

The codesandbox link in the description is what I'm trying to create with exception that it renders multiple bars per event date range. If you open the link you will see a grey bar spanning 1/3/24 to 1/5/24 and 1/8/24-1/9/24. These two events are actually represented by multiple bars per event, not one. If you mouse over the grey bar for event 1/3/24 to 1/5/24, you will see that there are 3 bars actually being rendered, 1 per day. I would like it to be 1 bar per event date range where a single bar's width spans those 3 days or ticks, mousing over 1/3/24 would highlight a single bar that spans to 1/5/24.

Here are some screen shots too

This shows a bar graph where the width represents a event date range. Two events in this example, 1/3/24-1/5/24 and 1/8/24-1/9/24. There are no events for 1/1/24-1/2/24 or 1/6/24-1/7/24. date range

With annotations date range labels

The event date ranges should be made up of a bar per event day, 1/3/24-1/5/24 is actually 3 bars, this is not ideal, I would like 1 bar to represent the entire event date range. date range mouse over 3 bars

This screen shows 1 bar to represent an event date range of 1/3/24-1/5/24, the bar's width represents the date range of 3 days or ticks, this is what I want, I'm not sure of the best way to do this. date range mouse over 1 bar

andy-root avatar Mar 25 '24 19:03 andy-root

Here is an example of using events and state to achieve that effect.

carbonrobot avatar Mar 25 '24 21:03 carbonrobot

Cool, do you think the VictoryBar is the best option for this?

There is one remaining issue which is the static barWidth, right now it is hard coded to 45 and that value works for the current number of data points and chart size but if the number of data points changes or the chart size changes then the bars may not be overlapping or overlapping too much. Maybe there is a formula that I could apply, by comparing the number of data points and chart width, but is there something simpler to make sure the barWidth is always wide enough to butt up to the next bar and not go over?

I tried barRatio but it does not produce consistent results when the number of data points change.

Bar width, too small Screenshot 2024-03-25 at 3 18 17 PM

Bar width, too large Screenshot 2024-03-25 at 3 20 16 PM

andy-root avatar Mar 25 '24 22:03 andy-root

I don't think there is a useful way to get the dimensions from the axis to predetermine the offsets correctly.

It may be that another chart type is a better fit. I like to reference [this site for data visualizations] when I'm looking for the right fit. (https://datavizcatalogue.com/blog/chart-combinations-timelines/). Take a look here and see if something fits better for your use case.

carbonrobot avatar Mar 26 '24 15:03 carbonrobot

Thanks, I'll take a look. I also looked into the stack horizontal chart suggestion, I think it might be possible, I post back if I can get it to work.

andy-root avatar Mar 26 '24 18:03 andy-root

This issue is stale because it has been open for 90 days with no activity. If there is no activity in the next 7 days, the issue will be closed.

github-actions[bot] avatar Jun 25 '24 00:06 github-actions[bot]

This issue was closed because it has been inactive for 7 days since being marked as stale. Please open a new issue if you believe you are encountering a related problem.

github-actions[bot] avatar Jul 02 '24 00:07 github-actions[bot]