How to chart date ranges with bars
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.
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?
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.
With annotations
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.
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.
Here is an example of using events and state to achieve that effect.
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
Bar width, too large
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.
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.
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.
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.