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

y-Axis labels are cut off if the top label is not the widest label #274

Open
owattenmaker opened this issue May 16, 2024 · 3 comments · May be fixed by #291
Open

y-Axis labels are cut off if the top label is not the widest label #274

owattenmaker opened this issue May 16, 2024 · 3 comments · May be fixed by #291
Labels
bug Something isn't working issue-accepted The issue is confirmed and accepted by the maintainers

Comments

@owattenmaker
Copy link
Contributor

owattenmaker commented May 16, 2024

Describe Your Environment

What version of victory-native-xl are you using?
v40.2.0
What version of React and React Native are you using?
v18.3.0, v74.1
What version of Reanimated and React Native Skia are you using?
3.11.0, 1.2.3
Are you using Expo or React Native CLI?
no
What platform are you on? (e.g., iOS, Android)
ios, but happens on both

Describe the Problem

Labels are cut off if your top level y label is not the widest label. The most common case I have for this is when the Y domain is small and the ticks may contain decimal values.
For example, if my domain is 0 - 2, the automatically generated tick values are 0, 0.5, 1, 1.5, 2. This is great, however in the transformInputData function (specifically line 176) only looks at the top value assuming it will be the largest.

I think this may have been done as a speed hack to not calculate the width of the labels a few different times, but I don't think the outcome is worth the potential speed increase, or at least add an option to force the calculation of all labels.

Here's an example showing this behavior
image
As you can see, this is problematic since not only is the preceding 0 cut off, but the . as well, leading to some confusing domains.

Sample code to reproduce:

const d = []
for (let i = 0; i < 400; i++) {
  d.push({ x: i, y1: Math.random() * 2, y2:  Math.random() * 2 - 0.2 })
}

const Chart = () => {
  return (
    <View style={{ height: 300, width: 400, backgroundColor: "black" }}>
      <CartesianChart
        data={d}
        xKey="x"
        yKeys={["y1","y2"]}
        axisOptions={{ font }}
      >
        {({ points }) => (
          <>
            <Scatter radius={1} points={points.y1} color="purple" />    
            <Line strokeWidth={1} points={points.y1} color="white" />
          </>
      </CartesianChart>
    </View>
  )
}

Expected behavior: [What you expect to happen]
Label padding is calculated using the widest width label.

Actual behavior: [What actually happens]
Label padding is only calculated using the top most label, which isn't necessarily the widest label.

@zibs
Copy link
Contributor

zibs commented May 16, 2024

Thanks for the detailed write-up and investigation. It does look like we aren't correctly grabbing the widest possible value there, especially if we start to consider negative numbers support that is on its way, etc.

I'll try to find a fix for this, thanks.

@zibs zibs added bug Something isn't working issue-accepted The issue is confirmed and accepted by the maintainers labels May 16, 2024
@daniel-ricado
Copy link

daniel-ricado commented May 21, 2024

any workarounds?
I've come up with padding the front with spaces

formatYLabel: (label) => {
    return ' ' + label.toString()
}

ps: negative numbers seem to work ok

@owattenmaker
Copy link
Contributor Author

While trying to get the alignment right, I've also noticed that if you provide tick values, it doesn't base the label off of those, which leads to further alignment bugs.

line 177 should at least look like the following if we're only measuring the top label:

  // Measure our top-most y-label if we have grid options so we can
  //  compensate for it in our x-scale.
  const topYLabel =
    axisOptions?.formatYLabel?.((tickDomainsY?.[0] ?? yScale.domain().at(0)) as RawData[YK]) ||
    String(yScale.domain().at(0));

using user provided tickDomainsY if available.

@owattenmaker owattenmaker linked a pull request Jun 4, 2024 that will close this issue
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working issue-accepted The issue is confirmed and accepted by the maintainers
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants