legg / react-native-svg-d3-example-bar-chart

Example use of react-native-svg and d3 working on react-native ios/android
8 stars 1 forks source link

how to put horizional scrollView on bar chart #3

Open shahabvshahabi1996 opened 7 years ago

shahabvshahabi1996 commented 7 years ago

this is my code


import React, {Component} from 'react'
import {View, Dimensions, TouchableWithoutFeedback,ScrollView,ListView } from 'react-native'

import Svg, {
    G,
    Line,
    Path,
    Rect,
    Text
} from 'react-native-svg'

// d3 lib
import {
    scaleBand,
    scaleLinear
} from 'd3-scale'

import {
    max,
    ticks
} from 'd3-array'

import {
    line
} from 'd3-shape'

import {
    path
} from 'd3-path'

const colours = {
    black: 'black',
    blue: 'steelblue',
    brown: 'brown'
}

// create the barchart (http://bl.ocks.org/mbostock/3885304)
const data = [
    {frequency: 2, letter: 'saturday'},
    {frequency: 5, letter: 'sunday'},
    {frequency: 4, letter: 'monday'},
    {frequency: 1, letter: 'tuesday'},
    {frequency: 2, letter: 'wensday'},
    {frequency: 3, letter: 'thursday'},
    {frequency: 8, letter: 'friday'},
    {frequency: 2, letter: 'saturday'},
    {frequency: 5, letter: 'sunday'},
    {frequency: 4, letter: 'monday'},
    {frequency: 1, letter: 'tuesday'},
    {frequency: 2, letter: 'wensday'},
    {frequency: 3, letter: 'thursday'},
    {frequency: 8, letter: 'friday'},
]

class Chart extends Component {
    render() {
        return (
            <ScrollView horizontal> 
                <BarChart />
            </ScrollView>
        )
    }
}

class BarChart extends Component {
    state = {
        barColour: data.map(()=>colours.blue)
    }

    toggleHighlight(i) {
        this.setState({
            barColour: [
                ...this.state.barColour.slice(0, i),
                this.state.barColour[i] === colours.blue ? colours.brown : colours.blue,
                ...this.state.barColour.slice(i+1)
            ]
        })
    }

    render() {
        const screen = Dimensions.get('window')
        const margin = {top: 50, right: 40, bottom: 200, left: 40}
        const width = screen.width - margin.left - margin.right
        const height = screen.height - margin.top - margin.bottom
        const x = scaleBand()
            .rangeRound([0, width*2])
            .padding(0.1)
            .domain(data.map(d => d.letter))
        const maxFrequency = max(data, d => d.frequency)
        const y = scaleLinear()
            .rangeRound([height, 0])
            .domain([0, maxFrequency])

        const firstLetterX = x(data[0].letter)
        const secondLetterX = x(data[1].letter)
        const lastLetterX = x(data[data.length - 1].letter)
        const labelDx = (secondLetterX - firstLetterX) / 2

        const bottomAxis = [firstLetterX - labelDx, lastLetterX + labelDx]
        const bottomAxisD = line()
            .x(d => d + labelDx)
            .y(() => 0)
            (bottomAxis)

        const leftAxis = ticks(0, maxFrequency, 5)
        const leftAxisD = line()
            .x(() => bottomAxis[0] + labelDx)
            .y(d => y(d) - height)
            (leftAxis)

        const notch = 5
        const labelDistance = 9

        const svg = (
            <ScrollView horizontal>
            <Svg width={screen.width} height={screen.height}>
                <G translate={margin.left + "," + margin.top}>
                    <G translate={"0," + height}>
                        <G key={-1}>
                            <Path stroke={colours.black} d={bottomAxisD} key="-1"/>
                            {
                                data.map((d, i) => (
                                    <G key={i + 1} translate={x(d.letter) + labelDx + ",0"}>
                                        <Line stroke={colours.black} y2={notch}/>
                                        <Text style={{textAlign : 'center',justifyContent : 'center'}} fill={colours.black} y={labelDistance}>{d.letter}</Text>
                                    </G>
                                ))
                            }
                        </G>
                        <G key={-2}>
                            <Path stroke={colours.black} d={leftAxisD} key="-1"/>
                            {
                                leftAxis.map((d, i) => (
                                    <G key={i + 1} translate={"0," + (y(d) - height)}>
                                        <Line stroke={colours.black} x1={notch} x2={labelDistance}/>
                                        <Text fill={colours.black} x={-labelDistance} y={-notch}>{d}</Text>
                                    </G>
                                ))
                            }
                        </G>
                        {
                            data.map((d, i) => (
                                <TouchableWithoutFeedback key={i} onPress={()=>this.toggleHighlight(i)}>
                                    <Rect x={x(d.letter)}
                                          y={y(d.frequency) - height}
                                          width={x.bandwidth()}
                                          height={height - y(d.frequency)}
                                          fill={this.state.barColour[i]}>
                                    </Rect>
                                </TouchableWithoutFeedback>
                            ))
                        }
                    </G>
                </G>
            </Svg>
            </ScrollView>
        )

        return svg;
    }
}
export default Chart
``` `
but it dosen't scroll 
praveens96 commented 5 years ago

got any solution? were able to solve this? i am also looking for a horizontal scrollable bar chart with SVG and d3 in react native. if you can share your solutions, it would be helpful.