如何使胜利的本机光标容器x和y轴线仅与图形上的点相交而不是接触点上

时间:2019-07-23 14:04:25

标签: reactjs react-native expo formidable victory-charts

如何使胜利本机光标容器x和y轴线仅与图形上的点相交而不是在触摸点上。由于default,可拖动光标与触摸点相交,但是我希望可拖动光标只要在我触摸图形的任何地方都必须相交,它只会显示图形上与我的触摸点相对应的最近点。

请告诉我如何做

2 个答案:

答案 0 :(得分:0)

这是解决方案:

import React, { Component } from 'react'
import { Text, StyleSheet, View } from 'react-native'
import {VictoryArea,VictoryChart,createContainer,VictoryTooltip,VictoryScatter,VictoryLine } from 'victory-native';
import {range, first, last,maxBy } from 'lodash';
import Svg,{Line} from 'react-native-svg';

const VictoryZoomVoronoiContainer = createContainer( "cursor","voronoi");

const data = range(20,81).map((x) => ({x, y: x*x}));

const findClosestPointSorted = (data, value) => {  
  if (value === null) return null;
    const start = first(data).x;
    const range = (last(data).x - start);
  const index = Math.round((value - start)/range * (data.length - 1));
  return data[index];
};

export default class Chart extends Component {
    componentWillMount()
    {
        this.setState({ymax:maxBy(data,function(o) { return o.y; }).y})
    }

    state = {
        activePoint:null,
        data:data,
        ymax :0
    }
    handleCursorChange(value) {           

    this.setState({
        activePoint: findClosestPointSorted(data, value)
    });
  }

    render() {
        const { activePoint } = this.state;
        const point = activePoint ?
            <VictoryScatter name = "scatter" data={[activePoint]} style={{data: {size: 200,fill:'#ffffff',stroke:'#1bad53',strokeWidth:2} }}/>
          : null;

        return (
            <View>
                <VictoryChart
                    height={300}
                    width={350}
                    containerComponent={
                        <VictoryZoomVoronoiContainer
                        voronoiDimension="x"
                        cursorDimension="x"
                        voronoiBlacklist={["scatter"]}
                        labelComponent={<VictoryTooltip style={{fill:'red'}}  flyoutStyle={{
                        fill:  'rgba(52, 52, 52, 0.8)',}}/>}
                        onCursorChange={(value)=>{this.handleCursorChange(value)}}
                        labels={cursor => {

                            try {

                                return(activePoint.x?`${activePoint.x}, ${Math.round(activePoint.y)}\ndjh`:null)
                            } catch (error) {
                                console.log(error)
                            }
                        }}
                        />
                    }
                 >

            <VictoryArea
            name = "area"
            data={data}
            interpolation="cardinal"
            style={{
            data: { 
                fill: '#1bad53',
                stroke: '#05a543',
                strokeWidth: 2
            }
            }}
            />
             {point}

          {activePoint?<Line  x1= {50} x2="300" y1={250-(200/this.state.ymax)*activePoint.y} y2={250-(200/this.state.ymax)*activePoint.y} stroke="black" strokeWidth="1"/>:null}

        </VictoryChart>
            </View>
        )
    }
}

答案 1 :(得分:0)

根据@Rajat Verma的回答,Victory允许您传递一个cursorComponent道具,您可以在其中使用自己的自定义svg Line组件(自定义颜色,strokeWidth等)

另外,值得注意的是,在还使用VictoryZoomContainer的zoomDomain道具的情况下,VictoryCursorContainer的行为不正常(缩放时光标与渲染线不匹配)。解决方案是取出VictoryZoomContainer并手动过滤原始数据集以模拟缩放。希望对您有帮助!

接受的答案中有错字,请使用:const VictoryCursorVoronoiContainer = createContainer('cursor', 'voronoi')。而且不要忘了使用voronoiBlacklist属性从voronoi图中排除项目!