JesperLekland / react-native-svg-charts

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

Label are not showing properly/overlapping #107

Closed burhanahmed92 closed 6 years ago

burhanahmed92 commented 6 years ago

http://prntscr.com/j45qov

Lables are not showing properly, My Code

import React from 'react'
import { BarChart, XAxis } from 'react-native-svg-charts'
import { View } from 'react-native'
import * as scale from 'd3-scale'

class ChartExample extends Component {

    render() {

        const data = [ 14, 80, 100, 55 ]

        return (
            <View style={{ height: 200, padding: 20 }}>
                <BarChart
                    style={{ flex: 1 }}
                    data={data}
                    gridMin={0}
                    svg={{ fill: 'rgb(134, 65, 244)' }}
                />
                <XAxis
                    style={{ marginTop: 10 }}
                    data={ data }
                    scale={scale.scaleBand}
                    formatLabel={ (value, index) => index }
                    labelStyle={ { color: 'black' } }
                />
            </View>
        )
    }

}

I tried all barcharts example its the same issue with labels, anyone knows whats the issue.

gertvdkolk commented 6 years ago

duplicate issue: refer to -> Axis labels are rendered overlapping #58

burhanahmed92 commented 6 years ago

I used this example , same issue

https://github.com/JesperLekland/react-native-svg-charts-examples/blob/master/storybook/stories/bar-chart/vertical-with-labels.js

JesperLekland commented 6 years ago

@burhanahmed92 Are you using expo? I can confirm the problem exists in an expo snack but not when running a normal local RN app

burhanahmed92 commented 6 years ago

no i am not using expo, Simple RN App

JesperLekland commented 6 years ago

Could you show your package.json? I have a feeling it's a dependency problem. It works fine for me

burhanahmed92 commented 6 years ago

I{ "name": "chartTest", "version": "0.0.1", "private": true, "scripts": { "start": "node node_modules/react-native/local-cli/cli.js start", "test": "jest" }, "dependencies": { "art": "^0.10.2", "d3": "^5.0.0", "d3-array": "^1.2.1", "d3-interpolate-path": "^2.0.1", "d3-scale": "^2.0.0", "d3-shape": "^1.2.0", "date-fns": "^1.29.0", "moment": "^2.22.0", "moment-timezone": "^0.5.14", "native-base": "^2.3.10", "prop-types": "^15.6.1", "react": "16.3.1", "react-dom": "^16.3.1", "react-moment": "^0.7.0", "react-native": "0.55.2", "react-native-camera": "^1.0.2", "react-native-chart-kit": "^0.1.5", "react-native-checkbox": "^2.0.0", "react-native-easy-grid": "^0.1.17", "react-native-fetch-blob": "^0.10.8", "react-native-permissions": "^1.1.1", "react-native-save-asset-library": "^1.0.5", "react-native-sqlite-storage": "^3.3.4", "react-native-svg": "^6.3.1", "react-native-svg-animations": "^0.1.6", "react-native-svg-charts": "^4.2.0", "react-navigation": "^1.5.8", "util": "*", "victory-native": "^0.17.4" }, "devDependencies": { "babel-jest": "22.4.3", "babel-preset-react-native": "4.0.0", "jest": "22.4.3", "react-test-renderer": "16.3.1" }, "jest": { "preset": "react-native" } }

burhanahmed92 commented 6 years ago

any solution?

JesperLekland commented 6 years ago

Could you try react-native-svg on version 6.2.1?

burhanahmed92 commented 6 years ago

same result buddy!

JesperLekland commented 6 years ago

React Native 0.55 has been known to break a few things, might be that one. It's really hard to do anything about this when it works in the examples repo. Could you try a lower version of RN?

burhanahmed92 commented 6 years ago

I tried with lower version too 0.53-0.54 but same result. I updated my project couple of days ago, I think its not RN version problem.

JesperLekland commented 6 years ago

try checking out the repo and run that. If that doesn't work then something really weird is going on

burhanahmed92 commented 6 years ago

I followed the guide given over npm site: https://www.npmjs.com/package/react-native-svg-charts I installed dependencies step by step: npm i react-native-svg-charts npm i react-native-svg d3 & other other dependencies like that but still not working. You can see lot of people having issue implementing this library, kindly update your installation guide.

JesperLekland commented 6 years ago

@burhanahmed92 Kindly respect that this is an open source project, if you find something lacking you are more than welcome to contribute. This is something I work on on my spare time, for free. I have had very little feedback on people having problems with this library seeing how many people use it and I try to help out as much as possible with those who do. Please show respect to people working on open source.

burhanahmed92 commented 6 years ago

Sorry if u find my language offensive, i have no intentions of doing that. I was just saying that the guide to implement this library is not telling users all steps of implementation. May be you will have a clear picture if u make new RN project and try to install this library via npm cli.....

JesperLekland commented 6 years ago

The entire examples repo uses this as an external dependency and it works just fine. Instead of telling my that it doesn't work would you telling me what doesn't work and/or what is missing?

burhanahmed92 commented 6 years ago

Ok we are taking this conversation somewhere else. Lets focus on the issue

burhanahmed92 commented 6 years ago

I updated my application to version 5.0.0 still same...

burhanahmed92 commented 6 years ago

found the issue buddy. Issue was with svg dependency. Your charts library supports <= 5.5.1 react-native-svg. Mine was 6.3.1 so i downgraded to 5.5.1 and it works. Anyway thanks

JesperLekland commented 6 years ago

Glad you solved it! Interesting that you had to downgrade that far, the project as well as the examples repo uses 6.2.1

dhcmega commented 6 years ago

Hi, tried downgrading, but:

warning " > react-native-svg-charts@5.2.0" has incorrect peer dependency "react-native-svg@^6.2.1".

Any way, chart was generated, but labels are still overlapping.

Is there an official solution? I guess this should be a common problem.

Thanks!

JesperLekland commented 6 years ago

@dhcmega Please provide a reproducible example in a new issue. So far I haven't been able to reproduce a single issue of overlapping labels that has been reported

acomito commented 6 years ago
screen shot 2018-06-26 at 9 25 16 am

I'm getting a similar issue... will try to create a reproduction.

let paid = [ { x:"2018-06-01", y: 2185 }, { x:"2018-07-01", y: 3410 }, { x:"2018-08-01", y: 1110 }, { x:"2018-09-01", y: 200 } ]
        let due = [ { x:"2018-06-01", y: 8421 }, { x:"2018-07-01", y: 4410 }, { x:"2018-08-01", y: 2210 }, { x:"2018-09-01", y: 1200 } ]
class LayeredChartsExample extends React.PureComponent {

    render() {
        const paidNumbers = this.props.paid.map(item=> item.y); // array of money paid
        const dueNumbers = this.props.due.map(item=> item.y);  // array of money due
        const gridMax = Math.max(...paidNumbers, ...dueNumbers)
        const gridMin = Math.min(...paidNumbers, ...dueNumbers)

        console.log({
            gridMax: gridMax + gridMax*.1, // add buffer
            gridMin: gridMin > 0 ? 0 : gridMin // if less than zero, use that. if more, use 0
        });

        // create objects used for give the y axis a scale
        const maxObj = {
            y: gridMax + gridMax*.1,
            x: 1
        }
        const minObj = {
            y: gridMin > 0 ? 0 : gridMin,
            x: 1
        }

        const LEFT_MARGIN = 38
        const chartStyle = { ...StyleSheet.absoluteFillObject, marginLeft: LEFT_MARGIN }

        const contentInset = { top: 10, bottom: 20 }
        ;    

        return (
            <View style={{ height: 150, width: '100%'}}>
                <AreaChart
                    style={chartStyle}
                    data={ this.props.due.map(item=> item.y) }
                    gridMin={ gridMin > 0 ? 0 : gridMin }
                    gridMax={ gridMax + gridMax*.1 }
                    svg={{ fill: 'rgba(134, 65, 244, 0.45)' }}
                    contentInset={contentInset}
                    curve={ shape.curveNatural }
                >
                    <Grid/>
                </AreaChart>
                <AreaChart
                    style={chartStyle}
                    data={ this.props.paid.map(item=> item.y)  }
                    gridMin={ gridMin > 0 ? 0 : gridMin }
                    gridMax={ gridMax + gridMax*.1 }
                    animate
                    svg={{ fill: 'rgba(134, 65, 244, .9)' }}
                    contentInset={contentInset}
                    curve={ shape.curveNatural }
                />
                <YAxis
                    data={[maxObj, minObj]}
                    yAccessor={({ item }, index) => item.y}
                    svg={{
                        fill: 'grey',
                        fontSize: 7,
                    }}
                    numberOfTicks={8}
                    style={{height: 150, minWidth: LEFT_MARGIN, left: 1, position: 'absolute'}}
                    contentInset={{ top: 10, bottom: 23 }}
                />
                <XAxis
                    data={[...this.props.due, ...this.props.paid]}
                    xAccessor={ ({ item }) => item.x }
                    scale={ scale.scaleTime }
                    style={{ 
                        height: 20,
                        borderWidth: 1,
                        borderColor: 'red',
                        right: 0,
                        left: 0,
                        bottom: 0,  
                        left: LEFT_MARGIN, 
                        position: 'absolute'
                    }}
                    contentInset={{ bottom: 2, left: LEFT_MARGIN }}
                />
            </View>
        )
    }

}
  "dependencies": {
    "accounting-js": "^1.1.1",
    "d3-scale": "^2.1.0",
    "d3-shape": "^1.2.0",
    "enzyme-to-json": "^3.3.4",
    "fuse.js": "^3.2.1",
    "moment": "^2.22.2",
    "phone-formatter": "^0.0.2",
    "prop-types": "^15.6.1",
    "rc-form": "^2.2.0",
    "react": "16.3.1",
    "react-native": "0.55.4",
    "react-native-autogrow-textinput": "^5.1.1",
    "react-native-calendars": "^1.19.3",
    "react-native-circular-progress": "^0.2.0",
    "react-native-elements": "^0.19.1",
    "react-native-keyboard-aware-scroll-view": "^0.5.0",
    "react-native-masked-text": "^1.7.2",
    "react-native-material-textfield": "^0.12.0",
    "react-native-modal": "^6.1.0",
    "react-native-offline": "^3.10.0",
    "react-native-popup-dialog": "^0.14.48",
    "react-native-splash-screen": "^3.0.9",
    "react-native-svg": "^6.3.1",
    "react-native-svg-charts": "^5.2.0",
    "react-native-vector-icons": "^4.6.0",
    "react-navigation": "^2.3.1",
    "react-redux": "^5.0.7",
    "redux": "^4.0.0",
    "redux-saga": "^0.16.0"
  },
  "devDependencies": {
    "babel-jest": "23.0.1",
    "babel-plugin-transform-remove-console": "^6.8.5",
    "babel-preset-react-native": "4.0.0",
    "eslint": "^4.6.1",
    "eslint-plugin-react": "^7.7.0",
    "jest": "23.1.0",
    "prettier": "^1.6.1",
    "react-devtools": "^3.2.3",
    "react-native-debugger-open": "^0.3.17",
    "react-test-renderer": "16.3.1",
    "redux-devtools-extension": "^2.13.2",
    "redux-logger": "^3.0.6",
    "remote-redux-devtools": "^0.5.12"
  },
Environment:
  OS: macOS Sierra 10.12.6
  Node: 9.7.1
  Yarn: 1.5.1
  npm: 5.6.0
  Watchman: 4.9.0
  Xcode: Xcode 9.2 Build version 9C40b
  Android Studio: 3.1 AI-173.4819257

Packages: (wanted => installed)
  react: 16.3.1 => 16.3.1
  react-native: 0.55.4 => 0.55.4
burhanahmed92 commented 6 years ago

There is a version compatibility issue with this library, i now switched to react-native-charts-wrapper , its stable and support is good

acomito commented 6 years ago

hmm... I don't really want to switch libraries over some overlapped labels but I'll check it out.

JesperLekland commented 6 years ago

@acomito There is a potential bug when using the scale prop as described here. Will hopefully have a fix out pretty soon. In the meanwhile it would be great if you could provide a reproducible example so that I can troubleshoot better.

acomito commented 6 years ago

@JesperLekland I just updated my post with more info, including a paid/due array of data you can feed in (I think those are the only props fed to LayeredChartsExample).

acomito commented 6 years ago

I wonder if it could be something to do with absolutely positioning. The labels all seem to be absolute left: 0, bottom: 0

JesperLekland commented 6 years ago

Looked quickly at the above example. None of the x-values are valid date objects! You have to do new Date("2018-01-01") in order for the scaleTime to work

acomito commented 6 years ago

I appreciate you taking the time to look. Unfortunately still not fixed after that change. I'll keep looking as well.

burhanahmed92 commented 6 years ago

Please share if you fixed the issue, i may try this again...

JesperLekland commented 6 years ago

@acomito could you try with the same version of d3-scale that this library uses?

burhanahmed92 commented 6 years ago

I try next time when i use this library again...

acomito commented 6 years ago

@burhanahmed92 @JesperLekland

This is my latest attempt:


// CONSTANTS & DESRUCURING
// ========================================
const paid = [ 
    { x:Date("2018-06-01"), y: 2185 }, 
    { x:Date("2018-07-01"), y: 3410 }, 
    { x:Date("2018-08-01"), y: 1110 }, 
    { x:Date("2018-09-01"), y: 200 } 
];

const due = [ 
    { x:Date("2018-06-01"), y: 8421 }, 
    { x:Date("2018-07-01"), y: 4410 }, 
    { x:Date("2018-08-01"), y: 2210 }, 
    { x:Date("2018-09-01"), y: 1200 } 
];

const LEFT_MARGIN = 38

const chartStyle = { ...StyleSheet.absoluteFillObject, marginLeft: LEFT_MARGIN }

// EXPORTED COMPONENT
// ========================================
class LayeredChartsExample extends React.PureComponent {

    render() {

        const paidNumbers = paid.map(item=> item.y); // array of money paid
        const dueNumbers = due.map(item=> item.y);  // array of money due
        const gridMax = Math.max(...paidNumbers, ...dueNumbers)
        const gridMin = Math.min(...paidNumbers, ...dueNumbers)

        // create objects used for give the y axis a scale
        const maxObj = {
            y: gridMax + gridMax*.1,
            x: 1
        }
        const minObj = {
            y: gridMin > 0 ? 0 : gridMin,
            x: 1
        }

        const contentInset = { top: 10, bottom: 20 };    

        return (
            <View style={{ height: 150, width: '100%'}}>
                <LineChart
                    style={chartStyle}
                    data={ due.map(item => item.y)  }
                    gridMin={ gridMin > 0 ? 0 : gridMin }
                    gridMax={ gridMax + gridMax*.1 }
                    svg={{ 
                        strokeWidth: 2,
                        stroke: 'rgba(134, 65, 244, 0.45)' 
                    }}
                    contentInset={contentInset}
                    curve={shape.curveBasis}
                >
                    <Grid/>
                </LineChart>
                <LineChart
                    style={chartStyle}
                    data={ paid.map(item => item.y)  }
                    gridMin={ gridMin > 0 ? 0 : gridMin }
                    gridMax={ gridMax + gridMax*.1 }
                    animate
                    svg={{ 
                        strokeWidth: 2,
                        stroke: 'rgba(134, 65, 244, .9)' 
                    }}
                    contentInset={contentInset}
                    curve={shape.curveBasis}
                />
                 <YAxis
                    data={[maxObj, minObj]}
                    yAccessor={({ item }, index) => item.y}
                    svg={{
                        fill: 'grey',
                        fontSize:   8,
                    }}
                    formatLabel={ value => AccountingHelpers.formatMoney(value, { precision: 0 }) }
                    numberOfTicks={8}
                    style={{height: 150, minWidth: LEFT_MARGIN, left: 1, position: 'absolute'}}
                    contentInset={{ top: 10, bottom: 23 }}
                />
                <XAxis
                    data={[...due, ...paid]}
                    xAccessor={ ({ item }) => item.x }
                    scale={ scale.scaleTime }
                    style={{ 
                        height: 20,
                        borderWidth: 1,
                        borderColor: 'red',
                        bottom: 0,
                        width: '100%',
                        left: LEFT_MARGIN, 
                        position: 'absolute'
                    }}
                    formatLabel={ value => moment(value).format('MMMM')}
                />
            </View>
        )
    }

}
  "dependencies": {
    "accounting-js": "^1.1.1",
    "appcenter": "^1.6.0",
    "appcenter-analytics": "^1.6.0",
    "appcenter-crashes": "^1.6.0",
    "d3-scale": "1.0.6",
    "d3-shape": "1.0.6",
    "enzyme-to-json": "^3.3.4",
    "fuse.js": "^3.2.1",
    "moment": "^2.22.2",
    "phone-formatter": "^0.0.2",
    "prop-types": "^15.6.1",
    "rc-form": "^2.2.0",
    "react": "16.3.1",
    "react-native": "0.55.4",
    "react-native-autogrow-textinput": "^5.1.1",
    "react-native-calendars": "^1.19.3",
    "react-native-circular-progress": "^0.2.0",
    "react-native-elements": "^0.19.1",
    "react-native-keyboard-aware-scroll-view": "^0.5.0",
    "react-native-masked-text": "^1.7.2",
    "react-native-material-textfield": "^0.12.0",
    "react-native-modal": "^6.1.0",
    "react-native-offline": "^3.10.0",
    "react-native-popup-dialog": "^0.14.48",
    "react-native-splash-screen": "^3.0.9",
    "react-native-svg": "^6.3.1",
    "react-native-svg-charts": "^5.2.0",
    "react-native-vector-icons": "^4.6.0",
    "react-navigation": "^2.3.1",
    "react-redux": "^5.0.7",
    "redux": "^4.0.0",
    "redux-saga": "^0.16.0"
  },
  "devDependencies": {
    "babel-jest": "23.0.1",
    "babel-plugin-transform-remove-console": "^6.8.5",
    "babel-preset-react-native": "4.0.0",
    "eslint": "^4.6.1",
    "eslint-plugin-react": "^7.7.0",
    "jest": "23.1.0",
    "prettier": "^1.6.1",
    "react-devtools": "^3.2.3",
    "react-native-debugger-open": "^0.3.17",
    "react-test-renderer": "16.3.1",
    "redux-devtools-extension": "^2.13.2",
    "redux-logger": "^3.0.6",
    "remote-redux-devtools": "^0.5.12"
  },
Environment:
  OS: macOS Sierra 10.12.6
  Node: 9.7.1
  Yarn: 1.5.1
  npm: 5.6.0
  Watchman: 4.9.0
  Xcode: Xcode 9.2 Build version 9C40b
  Android Studio: 3.1 AI-173.4819257

Packages: (wanted => installed)
  react: 16.3.1 => 16.3.1
  react-native: 0.55.4 => 0.55.4

outputs:

screen shot 2018-06-27 at 10 11 37 am
JesperLekland commented 6 years ago

You're supposed to do *new* Date('string'). Otherwise they all return the same value.

JesperLekland commented 6 years ago

Then you will have to use some negative margins and contentInset to align everything. Each label is centered on it's x-coordinate, i.e it will overflow on the first and last value if not corrected

acomito commented 6 years ago

@JesperLekland :blush:

JesperLekland commented 6 years ago

Glad it worked. Will lock this conversation now. Please create a new issue if you find anything new.