1

注意:我想要一个 react-native 的解决方案。我想在面积图上制作一个工具提示和一个可拖动的光标,其中有一条线通过可拖动的光标显示面积图的数据点。我只想标记来自数据集的数据点,而不是屏幕触摸点的和 y 值,只是在触摸屏幕时图表上的 x 和 y 值,它给出了数据集对应的最接近的值到屏幕。

我在互联网上搜索我发现了类似的东西,但它是用于反应并使用散点图,因为我对胜利原生库和反应原生库非常陌生,有人可以告诉如何用面积图制作一个反应原生的等效物. 这是我指的是看到的链接..

点我

我只是想用带有可拖动光标和工具提示的胜利本机中的面积图做一个类似的事情,它只在图表上标记数据点,而不是在屏幕坐标上。

任何人都可以根据我对胜利区域图的要求向我提供如何实现与上面提供的链接类似的 react-native 代码吗?还包括我想转换为 react-native 的反应代码。请有人帮帮我。

/* Victory requires `react@^15.5.0` and `prop-types@^15.5.0` */
const {
    VictoryLine, VictoryChart, VictoryCursorContainer, VictoryLabel, VictoryScatter
} = Victory;
const { range, first, last } = _; // lodash
const mountNode = document.getElementById('app');

const allData = range(750).map((x) => ({x, y: x + 30 * Math.random()}));

const findClosestPointSorted = (data, value) => {
    // assumes 3 things:
  // 1. data is sorted by x
  // 2. data points are equally spaced
  // 3. the search is 1-dimentional (x, not x and y)
  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];
};

class App extends React.Component {
    constructor() {
    super();
    this.state = {
        activePoint: null
    };
  }
    handleCursorChange(value) {
    this.setState({
        activePoint: findClosestPointSorted(allData, value)
    });
  }
  render() {
    const { activePoint } = this.state;
    const point = activePoint ?
        <VictoryScatter data={[activePoint]} style={{data: {size: 100} }}/>
      : null;
    return (
      <div>
        <VictoryChart
          containerComponent={
            <VictoryCursorContainer
              dimension="x"
              onChange={this.handleCursorChange.bind(this)}
              cursorLabel={cursor => `${activePoint.x}, ${Math.round(activePoint.y)}`}
            />
          }
        >
          <VictoryLine data={allData} style={{data: {stroke: '#999'} }}/>
          {point}
        </VictoryChart>
      </div>
    );
  }
}

ReactDOM.render(
    <App/>,
  mountNode
);
4

1 回答 1

1
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>
        )
    }
}
于 2019-07-24T16:24:08.700 回答