SVG水平滚动与React Native和D3

时间:2018-12-27 10:32:16

标签: react-native d3.js svg horizontal-scrolling react-native-svg

我正在尝试使用react native svg和d3绘制水平可滚动条形图。我能够画出条,而不是如何使其滚动。另外,要滚动浏览,我需要调用网络服务以获取一些详细信息。有人可以帮我吗这是我的代码:

数据

const data=[
  {label:"jan",value:200, credit:120, debit:20},
  {label:"feb", value:200.5, credit:10, debit:20.5},
  {label:"mar", value:200, credit:50, debit:60},
  {label:"apr", value:90, credit:50, debit:80},
  {label:"may", value:210, credit:150, debit:80},
  {label:"jun", value:120, credit:30, debit:1},
  {label:"jul",value:173, credit:40, debit:20},
  {label:"aug", value:129.5, credit:10, debit:20.5},
  {label:"sep", value:80, credit:8, debit:10},
  {label:"oct", value:22, credit:5, debit:10},
  {label:"nov", value:188, credit:20, debit:20},
  {label:"dec", value:50, credit:10, debit:5}
];

渲染功能

const graphMargin = 20;
const barWidth  = 5;
const colors = {
  axis: '#E4E4E4',
  bars: '#15AD13',
  debit:"red",
  credit:'#15AD13'
};
var graphHeight = height-2*graphMargin;
var graphWidth = width-2*graphMargin;
//using d3 generate scale to draw using our data
var xDomain = data.map(item=>item.label);
const xRange = [0, graphWidth+graphWidth/2];
var x = d3.scalePoint()
              .domain(xDomain)
              .range(xRange)

//using d3 generate a linear scale to fit values, max value+buffer. buffer is for looking better
const yDomain = [0, d3.max(data,d=>d.value)];
const yRange = [0, graphHeight - (0.4*graphHeight)];
var y= d3.scaleLinear()
          .domain(yDomain)
          .range(yRange)
return (

  <View style={styles.container}>

    <ScrollView horizontal={true}>
    {/* preserveAspectRatio="xMidYMid meet" width={width-20} height={height-20} 
      viewBox={{graphMargin, graphMargin, width,height}} */}
    <Svg width={width-20} height={height-20} 
        style={{overflow:"scroll"}} >
      {/* create axes */}

      {/* define x and y to height of viewport or leaving margins, so it will start drawing from
        there and as we need to give negitive y co-ordinates i.e. multiply with -1
      */}
      <G  y={graphHeight-60} x={graphMargin/2} style={{overflow:"scroll"}}>   
        {/* labels */}

        {data.map(item=>(

          <Rect 
            key={'bar1'+item.label}
            x={x(item.label)} //horizontal start position, if space needed do:  - (barWidth/2)
            y={y(item.credit)*-1} //position to start from top
            rx={2.5} //rounded corners
            height={y(item.credit)} //bar height: viewheight-bar hieght-bottom space
            width={barWidth} //bar width
            fill={colors.bars} //fill color
          />


        ))}
        {
          data.map(item=>(
            <Rect 
              key={'bar'+item.label}
              x={x(item.label)+barWidth}
              y={y(item.debit) * -1}
              rx={2.5}
              height={y(item.debit)}
              width={barWidth}
              fill="red"
            />
          ))
        }
        {data.map(item=>(
              <Text
              key={'label' + item.label}
              x={x(item.label)}
              y={20}
              textAnchor="middle"
              stroke="white">
                {item.label}
              </Text>
          ))}

      </G>

    </Svg>
    {/* <Text>test</Text> */}
    </ScrollView>
  </View>
);

}

尝试使用 scroll visible 溢出,并尝试将整个svg保留在滚动视图中。那没有用。任何帮助,将不胜感激。 编辑: 到目前为止,它的显示方式如下:需要滚动视图才能显示直到dec的值enter image description here

1 个答案:

答案 0 :(得分:1)

轻松滚动获取svg。给它大于视图/窗口宽度的宽度,并用水平true将其包装在ScrollView中。

下面是示例代码:

<ScrollView horizontal={true} onScroll={()=>this.onGraphScroll()} scrollEventThrottle={16}>
<Svg width={width+width+width} height={height-20} 
   ...
</Svg>
</ScrollView>