FormidableLabs / victory

A collection of composable React components for building interactive data visualizations
http://commerce.nearform.com/open-source/victory/
Other
11.02k stars 524 forks source link

Victory Bar ignores domainPadding on x near 0 #2872

Closed kmzeitgleich closed 6 months ago

kmzeitgleich commented 6 months ago

Is there an existing issue for this?

Code of Conduct

Victory version

37.0.2

Code Sandbox link

No response

Bug report

When you have VictoryBar components with x value 0, the domain padding left is ignored, making the 0 bar at the y axis and therefore unreadable

Simple example:

<VictoryChart
  //domain={{x: [-1, 5]}} // also does not work with [0, 5]
  domainPadding={{ x: 15 }} // for positioning bars
>
  <VictoryBar data={[

  //{x: -1, y: 2}, // this works
  {x: 0, y: 3}, // this one is in a bad position due to ignored domainPadding
  //{x: 0.2, y: 3}, // just for testing
  {x: 1, y: 4},
  {x: 2, y: 2},
  {x: 3, y: 1},
  {x: 4, y: 1},
  ]}
  //barWidth={15}
  />

</VictoryChart>

I would only expect this to happen when my x domain is < 0. And even then it would be nice if the 0 bar would be readable

Steps to reproduce

Paste the Code in the "Editable Source" on the website
the first bar is over the x axis, ignoring domainPadding
comment out the value where x: 0
the first bar is now on the right side of the axis, thanks to domainPadding

Expected behavior

No response

Actual behavior

No response

Environment

irrelevant
carbonrobot commented 6 months ago

A Victory axis supplied with numerical data will assign the point [0,0] to the origin. However, charts like VictoryBar can also accommodate categories on the X axis, which do not start at the origin. You can do this by providing the x values as a string, or by coercing them with a data accessor in the below the example.

<VictoryChart domainPadding={20}>
  <VictoryBar 
    data={[
      {x: 0, y: 3},
      {x: 1, y: 4},
      {x: 2, y: 2},
      {x: 3, y: 1},
      {x: 4, y: 1},
    ]}
    x={(datum) => datum.x.toString()}
  />  
</VictoryChart>

image

kmzeitgleich commented 6 months ago

I could do that, but then I lose the linear scale. I will not have gaps in my x values, like if you add x: 8, y: 2 and have not data between that

carbonrobot commented 6 months ago

It's important to understand that a Bar chart is a type of visualization that displays qualitative data across discrete values. Discrete values are non-linear and are typically called "categorical" data. You may want to consider a different type of visualization in your use case.

Here is a good reference for visualization types: https://www.data-to-viz.com/

However, you can still achieve this using the categories property and specifying the linear range of your data.

<VictoryChart domainPadding={20}>
  <VictoryBar 
    data={[
      {x: 0, y: 3},
      {x: 1, y: 4},
      {x: 2, y: 2},
      {x: 3, y: 1},
      {x: 4, y: 1},
      {x: 8, y: 4},
    ]}
    categories={{
      x: Array.from(Array(10).keys().map(x => x.toString()))
    }}
  />  
</VictoryChart>
kmzeitgleich commented 6 months ago

Ok, that should be a good enough workaround