JesperLekland / react-native-svg-charts

πŸ“ˆ One library to rule all charts for React Native πŸ“Š
MIT License
2.35k stars 403 forks source link

[Help] xAxis values not aligned with BarChart #182

Open gagso opened 6 years ago

gagso commented 6 years ago

What is the problem?

xAxis doesn't render the values inline with BarChart

screen shot 2018-06-28 at 11 04 13 pm

When does it happen?

just trying to render it onLoad using the following code

xAxis

<XAxis
   scale={scale.scaleBand}
   data={data}
   xAccessor={({ item }) => item.title}
   formatLabel={value => value}
   svg={{
     fill: 'grey',
     fontSize: 10,
   }}
/>

What platform?

React Native version: 0.55.4

Code to reproduce

<View style={{ padding: 10 }}>
    <View style={{ flexDirection: 'row', height: 150 }}>
      <YAxis
        data={data}
        yAccessor={({ item }) => item.value}
        formatLabel={value => value}
        numberOfTicks={5}
        min={0}
        svg={{
          fill: 'grey',
          fontSize: 10,
        }}
      />
      <BarChart
        style={{ flex: 1, marginLeft: 5 }}
        data={data}
        scale={scale.scaleBand}
        yAccessor={({ item }) => item.value}
        gridMin={0}
        svg={{
          fill: '#A6B4F3',
        }}
      >
        <Grid />
      </BarChart>
    </View>
    <XAxis
      scale={scale.scaleBand}
      data={data}
      xAccessor={({ item }) => item.title}
      formatLabel={value => value}
      svg={{
        fill: 'grey',
        fontSize: 10,
      }}
    />
  </View>
JesperLekland commented 6 years ago

Don't know what item.title is but I'm pretty sure it's not something the XAxis can layout.

Have a look over at the examples repo.

Using scaleBand means you can almost always remove the xAccessor all together, it just looks at the index anyway (which just happens to be the default xAccessor for the XAxis

gagso commented 6 years ago

item.title is just a string.

I also observed i am getting this error in the packager console.

``11:49:41 PM: Warning: Failed prop type: Invalid propscaleof valuefunction band() { var scale = ordinal().unknown(undefined), domain = scale.domain, ordinalRange = scale.range, range$$1 = [0, 1], step, bandwidth, round = false, paddingInner = 0, paddingOuter = 0, align = 0.5; delete scale.unknown;

  function rescale() {
    var n = domain().length,
        reverse = range$$1[1] < range$$1[0],
        start = range$$1[reverse - 0],
        stop = range$$1[1 - reverse];
    step = (stop - start) / Math.max(1, n - paddingInner + paddingOuter * 2);
    if (round) step = Math.floor(step);
    start += (stop - start - step * (n - paddingInner)) * align;
    bandwidth = step * (1 - paddingInner);
    if (round) start = Math.round(start), bandwidth = Math.round(bandwidth);
    var values = d3Array.range(n).map(function (i) {
      return start + step * i;
    });
    return ordinalRange(reverse ? values.reverse() : values);
  }

  scale.domain = function (_) {
    return arguments.length ? (domain(_), rescale()) : domain();
  };

  scale.range = function (_) {
    return arguments.length ? (range$$1 = [+_[0], +_[1]], rescale()) : range$$1.slice();
  };

  scale.rangeRound = function (_) {
    return range$$1 = [+_[0], +_[1]], round = true, rescale();
  };

  scale.bandwidth = function () {
    return bandwidth;
  };

  scale.step = function () {
    return step;
  };

  scale.round = function (_) {
    return arguments.length ? (round = !!_, rescale()) : round;
  };

  scale.padding = function (_) {
    return arguments.length ? (paddingInner = paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingInner;
  };

  scale.paddingInner = function (_) {
    return arguments.length ? (paddingInner = Math.max(0, Math.min(1, _)), rescale()) : paddingInner;
  };

  scale.paddingOuter = function (_) {
    return arguments.length ? (paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingOuter;
  };

  scale.align = function (_) {
    return arguments.length ? (align = Math.max(0, Math.min(1, _)), rescale()) : align;
  };

  scale.copy = function () {
    return band().domain(domain()).range(range$$1).round(round).paddingInner(paddingInner).paddingOuter(paddingOuter).align(align);
  };

  return rescale();
}` supplied to `XAxis`, expected one of [null,null,null].
in XAxis (at BarChart.js:35)
``` 

I have tried it with both d3-scale@1.0.6 / d3-scale@1.0.7

gagso commented 6 years ago

Very Strange - I am directly using this example code

and i get this error -

screen shot 2018-06-29 at 12 14 25 am
gagso commented 6 years ago

@JesperLekland - looks like there is some other problem; probably with the scale ? The exact same code from the example shouldn't break

which version of d3-scale are we supposed to use ? I believe it should be d3-scale@1.0.6 or d3-scale@1.0.7 ?

acomito commented 6 years ago

@gagso did you make sure you have javascript data objects? Then use formatLabel to re-format before displaying?

gagso commented 6 years ago

@acomito - i am using javascript data objects and i do use formatLabel if you look at the code i shared above.

JesperLekland commented 6 years ago

I'm pretty sure this is a scale issue, I'll resolve this in the next release

JesperLekland commented 6 years ago

What you could try to do is to remove the dependency of d3-scale from your package.json. react-native-svg-charts already depends on it and therefore it should already be in your node_modules (this could depend on npm vs yarn, but it should work with `yarn).

flashimxd commented 6 years ago

Hi guys, I've facing the same problem with the d3-scale, is there anything I can do to resolve? Thank you so much! This is the best chart for react-native I tried!

acomito commented 6 years ago

@flashimxd do you have code or a snack?

flashimxd commented 6 years ago

HI @acomito , thank you to reply, When I put the 3d-scale, they don't stay in the same line.. when I remove, I can control using the contentInset, but, of course, it not working cause I don't know the lenght of my data object..

this is my code:

return (

Promoters Passives Detractors
            <View style={{ flexDirection: 'row', height: 230, paddingVertical: 20 }}>
                <YAxis
                    data={data}
                    yAccessor={({ index }) => index}
                   /scale={scale.scaleBand}
                    contentInset={{ top: 10, bottom: 10 }}
                    spacing={0.2}
                    formatLabel={(_, index) => (data[index] ? data[index].store : '')}
                />
                <StackedBarChart
                    style={{ flex: 1, marginLeft: 8 }}
                    colors={colors}
                    keys={keys}
                    data={data}
                    horizontal
                    contentInset={{ top: 20, bottom: 20 }}
                    spacing={0.2}
                    gridMin={0}
                    yAccessor={({ item }) => item.store}
                >
                    <Grid direction={Grid.Direction.VERTICAL} />
                </StackedBarChart>
            </View>
        </View>

These screen shots show how it is been displayed (with/without the 3d-scale) screen shot 2018-07-03 at 17 23 15

screen shot 2018-07-03 at 17 22 27

Thank you again!

flashimxd commented 6 years ago

Another strange thing.. when I inspect the scale.scaleBand I receive:

Ζ’ band() { var scale = ordinal().unknown(undefined), domain = scale.domain, ordinalRange = scale.range, range$$1 = [0, 1], step, bandwidth,

JesperLekland commented 6 years ago

@flashimxd What version of d3-scale are you using? Are you using the one bundled with the library or have you a dependency of your own?

flashimxd commented 6 years ago

@JesperLekland I'm using the one blunded: d3-scale@^2.0.0

JesperLekland commented 6 years ago

@flashimxd I highly doubt it. The one bundled is ^1.0.6 See package.json for yourself

gagso commented 6 years ago

Only way I could make it work is by choosing not to use scaleBand and adjust using offsets.

It's not the best solution as the lables are not exactly centred. But that's all I could do for now.

I tried using the exact version which is a dependency for the library 1.0.6 / 1.0.7.

On Wed, 4 Jul 2018 at 7:22 PM, Rangel Netto notifications@github.com wrote:

@JesperLekland https://github.com/JesperLekland I'm using the one blunded: d3-scale@^2.0.0

β€” You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/JesperLekland/react-native-svg-charts/issues/182#issuecomment-402485723, or mute the thread https://github.com/notifications/unsubscribe-auth/AIosq07ETDC0m1IXwWsJiVlRzmHwW_19ks5uDMitgaJpZM4U7zNN .

JesperLekland commented 6 years ago

@gagso you're not supposed to have in it your package.json at all, it comes bundled with the library. The upcoming version will export its own scale to remedy this confusion.

flashimxd commented 6 years ago

Ok, but I just tried with the version 1.0.6 and the result does not change, I'm afraid to been doing something wrong..

JesperLekland commented 6 years ago

You not supposed to try with any version. Remove it completely from your package.json. react-native-svg-charts will automatically install d3-scale into your node_modules It was obviously a mistake from my part to allow external dependencies...

flashimxd commented 6 years ago

@JesperLekland It worked! I just removed the 3d-scale from my node modules and reinstall the react-native-svg-charts and it solved my problem! I appreciate you spending your time to help us!

Thank you so much!

screen shot 2018-07-04 at 16 15 37

gagso commented 6 years ago

If I don't have my own dependency, can you tell me how can I pass 'scaleBand' to the BarChart component ?

What I know is scaleBand is imported from 'd3scale' and I cannot import without having it as a dependency.

I think it's a good idea to expose the scale like you mentioned. On Wed, 4 Jul 2018 at 8:47 PM, Rangel Netto notifications@github.com wrote:

@JesperLekland https://github.com/JesperLekland It worked! I just remove the 3d-scale from my node modules and reinstall the react-native-svg-charts and it solved my problem! I appreciate you spending your time to help us!

Thank you so much!

[image: screen shot 2018-07-04 at 16 15 27] https://user-images.githubusercontent.com/13886651/42284846-aa2727f2-7fa5-11e8-863c-f97ae7459c52.png

β€” You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/JesperLekland/react-native-svg-charts/issues/182#issuecomment-402507373, or mute the thread https://github.com/notifications/unsubscribe-auth/AIosq5ps2mtz6GbVikBhNjkxgz_JlS0Kks5uDNyNgaJpZM4U7zNN .

JesperLekland commented 6 years ago

@gagso not sure if you're using yarn or npm but yarn makes sure that a dependency of react-native-svg-charts, eg d3-scale is installed as a dependency of your project. You should be able to import it as usual

gagso commented 6 years ago

It won't work. As per my understanding of things, dependencies of a library we consume will be installed in 'node_modules' folder inside the library folder (which is inside the node_modules folder in root)

That's the reason I had to install 'd3-scale' in the root.. On Wed, 11 Jul 2018 at 9:35 PM, Pete Fairhurst notifications@github.com wrote:

@JesperLekland https://github.com/JesperLekland import * as scale from "d3-scale"; doesn't work for meβ€”is this the wrong way to include the bundled D3 Scale?

RN error is Unable to resolve 'd3-scale' … Module 'd3-scale' does not exist in the Haste module map

β€” You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/JesperLekland/react-native-svg-charts/issues/182#issuecomment-404224427, or mute the thread https://github.com/notifications/unsubscribe-auth/AIosq9FheZEHdOxJ6y5dq4Nysgybv3Cnks5uFiIsgaJpZM4U7zNN .

alburdette619 commented 6 years ago

The solution is not installing d3-scale as a dependency as @JesperLekland says. It entirely fixed the issue for me.

gagso commented 6 years ago

What fixed the issue for you ? @Adam On Mon, 30 Jul 2018 at 7:15 PM, Adam Burdette notifications@github.com wrote:

The solution is not installing d3-scale as a dependency as @JesperLekland https://github.com/JesperLekland says. It entirely fixed the issue for me.

β€” You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/JesperLekland/react-native-svg-charts/issues/182#issuecomment-408868738, or mute the thread https://github.com/notifications/unsubscribe-auth/AIosq2PtnWHGcQ35N-qIGaI-CZckrsPbks5uLw4VgaJpZM4U7zNN .

marciogurka commented 5 years ago

I had the same issue, then checked that the "correct" d3-scale lib is inside the react-native-svg-charts folder inside node_modules, like this: node_modules/react-native-svg-charts/node_modules/d3-scale, when I imported this lib with this path all worked fine! πŸ˜ƒ

Baskina commented 5 years ago

Thanks a lot, @JesperLekland , it's what I need. (had the same issue either) And thank you for the awesome charts :)

vinaygoyal20 commented 3 years ago

In 2020 i followed there example code https://github.com/JesperLekland/react-native-svg-charts-examples/blob/master/storybook/stories/x-axis/scale-band.js but it isn't working later i did i found that svg props is required for Xaxis to render which was missing and the bar chart has bydefault spacing inner prop with value=0.05 providing both to xaxis solved the issue for me. <XAxis style={{ marginTop: 10 }} data={ data } scale={scale.scaleBand} spacingInner={0.05}//this solved the issue of alignment with bar chart svg={{fontSize:10,fill:"grey"}}//this make the x axis visible on the screen formatLabel={ (value, index) => index } labelStyle={ { color: 'black' } } /> https://github.com/JesperLekland/react-native-svg-charts/issues/502#issuecomment-717188279