Guest User

Recharts bug reproduction active dot outside chart

a guest
Oct 6th, 2024
41
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
JavaScript 4.68 KB | Source Code | 0 0
  1. import React, { PureComponent } from 'react';
  2. import {
  3.   Label,
  4.   LineChart,
  5.   Line,
  6.   CartesianGrid,
  7.   XAxis,
  8.   YAxis,
  9.   Tooltip,
  10.   ReferenceArea,
  11.   ResponsiveContainer,
  12. } from 'recharts';
  13.  
  14. const initialData = [
  15.   { name: 1, cost: 4.11, impression: 100 },
  16.   { name: 2, cost: 2.39, impression: 120 },
  17.   { name: 3, cost: 1.37, impression: 150 },
  18.   { name: 4, cost: 1.16, impression: 180 },
  19.   { name: 5, cost: 2.29, impression: 200 },
  20.   { name: 6, cost: 3, impression: 499 },
  21.   { name: 7, cost: 0.53, impression: 50 },
  22.   { name: 8, cost: 2.52, impression: 100 },
  23.   { name: 9, cost: 1.79, impression: 200 },
  24.   { name: 10, cost: 2.94, impression: 222 },
  25.   { name: 11, cost: 4.3, impression: 210 },
  26.   { name: 12, cost: 4.41, impression: 300 },
  27.   { name: 13, cost: 2.1, impression: 50 },
  28.   { name: 14, cost: 8, impression: 190 },
  29.   { name: 15, cost: 0, impression: 300 },
  30.   { name: 16, cost: 9, impression: 400 },
  31.   { name: 17, cost: 3, impression: 200 },
  32.   { name: 18, cost: 2, impression: 50 },
  33.   { name: 19, cost: 3, impression: 100 },
  34.   { name: 20, cost: 7, impression: 100 },
  35. ];
  36.  
  37. const getAxisYDomain = (from, to, ref, offset) => {
  38.   const refData = initialData.slice(from - 1, to);
  39.   let [bottom, top] = [refData[0][ref], refData[0][ref]];
  40.   refData.forEach((d) => {
  41.     if (d[ref] > top) top = d[ref];
  42.     if (d[ref] < bottom) bottom = d[ref];
  43.   });
  44.  
  45.   return [(bottom | 0) - offset, (top | 0) + offset];
  46. };
  47.  
  48. const initialState = {
  49.   data: initialData,
  50.   left: 1.01,
  51.   right: 1.15,
  52.   refAreaLeft: '',
  53.   refAreaRight: '',
  54.   top: 'dataMax+1',
  55.   bottom: 'dataMin-1',
  56.   top2: 'dataMax+20',
  57.   bottom2: 'dataMin-20',
  58.   animation: true,
  59. };
  60.  
  61. export default class Example extends PureComponent {
  62.   static demoUrl = 'https://codesandbox.io/p/sandbox/highlight-zoom-line-chart-rrj8f4';
  63.  
  64.   constructor(props) {
  65.     super(props);
  66.     this.state = initialState;
  67.   }
  68.  
  69.   zoom() {
  70.     let { refAreaLeft, refAreaRight } = this.state;
  71.     const { data } = this.state;
  72.  
  73.     if (refAreaLeft === refAreaRight || refAreaRight === '') {
  74.       this.setState(() => ({
  75.         refAreaLeft: '',
  76.         refAreaRight: '',
  77.       }));
  78.       return;
  79.     }
  80.  
  81.     // xAxis domain
  82.     if (refAreaLeft > refAreaRight) [refAreaLeft, refAreaRight] = [refAreaRight, refAreaLeft];
  83.  
  84.     // yAxis domain
  85.     const [bottom, top] = getAxisYDomain(refAreaLeft, refAreaRight, 'cost', 1);
  86.     const [bottom2, top2] = getAxisYDomain(refAreaLeft, refAreaRight, 'impression', 50);
  87.  
  88.     this.setState(() => ({
  89.       refAreaLeft: '',
  90.       refAreaRight: '',
  91.       data: data.slice(),
  92.       left: refAreaLeft,
  93.       right: refAreaRight,
  94.       bottom,
  95.       top,
  96.       bottom2,
  97.       top2,
  98.     }));
  99.   }
  100.  
  101.   zoomOut() {
  102.     const { data } = this.state;
  103.     this.setState(() => ({
  104.       data: data.slice(),
  105.       refAreaLeft: '',
  106.       refAreaRight: '',
  107.       left: 'dataMin',
  108.       right: 'dataMax',
  109.       top: 'dataMax+1',
  110.       bottom: 'dataMin',
  111.       top2: 'dataMax+50',
  112.       bottom2: 'dataMin+50',
  113.     }));
  114.   }
  115.  
  116.   render() {
  117.     const { data, barIndex, left, right, refAreaLeft, refAreaRight, top, bottom, top2, bottom2 } = this.state;
  118.  
  119.     return (
  120.       <div className="highlight-bar-charts" style={{ userSelect: 'none', width: '100%' }}>
  121.         <button type="button" className="btn update" onClick={this.zoomOut.bind(this)}>
  122.           Zoom Out
  123.         </button>
  124.  
  125.         <ResponsiveContainer width="100%" height={400}>
  126.           <LineChart
  127.             width={800}
  128.             height={400}
  129.             data={data}
  130.             margin={{left: 80, right: 40}}
  131.             onMouseDown={(e) => this.setState({ refAreaLeft: e.activeLabel })}
  132.             onMouseMove={(e) => this.state.refAreaLeft && this.setState({ refAreaRight: e.activeLabel })}
  133.             // eslint-disable-next-line react/jsx-no-bind
  134.             onMouseUp={this.zoom.bind(this)}
  135.           >
  136.             <CartesianGrid strokeDasharray="3 3" />
  137.             <XAxis allowDataOverflow dataKey="name" domain={[left, right]} type="number" />
  138.             <YAxis allowDataOverflow domain={[bottom, top]} type="number" yAxisId="1" />
  139.             <YAxis orientation="right" allowDataOverflow domain={[bottom2, top2]} type="number" yAxisId="2" />
  140.             <Tooltip />
  141.             <Line yAxisId="1" type="natural" dataKey="cost" stroke="#8884d8" animationDuration={300} />
  142.             <Line yAxisId="2" type="natural" dataKey="impression" stroke="#82ca9d" animationDuration={300} />
  143.  
  144.             {refAreaLeft && refAreaRight ? (
  145.               <ReferenceArea yAxisId="1" x1={refAreaLeft} x2={refAreaRight} strokeOpacity={0.3} />
  146.             ) : null}
  147.           </LineChart>
  148.         </ResponsiveContainer>
  149.       </div>
  150.     );
  151.   }
  152. }
  153.  
Advertisement
Add Comment
Please, Sign In to add comment