Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to chart date ranges with bars #2838

Open
2 tasks done
andy-root opened this issue Mar 22, 2024 · 6 comments
Open
2 tasks done

How to chart date ranges with bars #2838

andy-root opened this issue Mar 22, 2024 · 6 comments
Labels
Type: Question ❔ Asking a question or asking for help

Comments

@andy-root
Copy link

andy-root commented Mar 22, 2024

Is there an existing issue for this?

  • I have searched the existing issues

Code of Conduct

  • 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 andy-root added the Type: Question ❔ Asking a question or asking for help label Mar 22, 2024
@andy-root andy-root changed the title How chart data ranges with bars How to chart data ranges with bars Mar 22, 2024
@carbonrobot
Copy link
Contributor

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?

@andy-root
Copy link
Author

andy-root commented Mar 25, 2024

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

@carbonrobot
Copy link
Contributor

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

@andy-root
Copy link
Author

andy-root commented Mar 25, 2024

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 andy-root changed the title How to chart data ranges with bars How to chart date ranges with bars Mar 26, 2024
@carbonrobot
Copy link
Contributor

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.

@andy-root
Copy link
Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Question ❔ Asking a question or asking for help
Projects
None yet
Development

No branches or pull requests

2 participants