как добавить разброс в форме перевернутого треугольника в повторной диаграмме

#reactjs #recharts

#reactjs #перезаряжается

Вопрос:

Я использую точечную диаграмму с использованием повторной диаграммы и использую форму разброса как «треугольник», мое требование — перевернутый треугольник. Я пытался использовать angle, но он не работает. кто-нибудь может мне помочь в этом, как нарисовать перевернутый трейнгл.Может быть, мы можем написать пользовательскую форму, используя rect или path, но я новичок в этом, пожалуйста, кто-нибудь, помогите мне.

код:

  const {ScatterChart, Scatter, XAxis, YAxis, ZAxis, CartesianGrid, Tooltip, Legend} = Recharts;
const data01 = [{x: 100, y: 200}, {x: 120, y: 0},
                ];


const ThreeDimScatterChart = React.createClass({
    render () {
    return (
        <ScatterChart width={400} height={400} margin={{top: 20, right: 20, bottom: 20, left: 20}}>
        <XAxis type="number" dataKey={'x'} name='stature' unit='cm'/>
        <YAxis type="number" dataKey={'y'} name='weight' unit='kg'/>
     
        <CartesianGrid />
        <Tooltip cursor={{strokeDasharray: '3 3'}}/>
        <Legend />
        <Scatter name='A school' data={data01} fill='#8884d8' shape="triangle"/>

      </ScatterChart>
    );
  }
})

ReactDOM.render(
  <ThreeDimScatterChart />,
  document.getElementById('container')
);
 

Спасибо

Ответ №1:

Вы должны создать пользовательскую форму для разброса, используя полигон или свой собственный SVG.

Пример с полигоном:

 <Scatter name="A school" data={data01} fill="#8884d8" shape="<TriangleShape angle={180} />" />;

const TriangleShape = (props: any): JSX.Element => {
  return <polygon {...props} points={calcTrianglePoints(props.cx, props.cy, props.r * 2, props.angle || 0)} />;
};
/** *
 * Calc points of the triangle
 *
 * @param xCenter The X-coordinate of the center of triangle
 * @param yCenter The Y-coordinate of the center of triangle
 * @param sideLength The length of the side
 * @param angle The angle in degrees
 */
const calcTrianglePoints = (xCenter: number, yCenter: number, sideLength: number, angle: number = 0): string => {
  const r = (Math.sqrt(3) / 3) * sideLength; // The radius of the circumscribed circle
  const h = (Math.sqrt(3) / 2) * sideLength; // The height of median

  const angleInRadian = (Math.PI * angle) / 180;

  const pointCenter: [number, number] = [xCenter, yCenter];
  const pointCenterNew: [number, number] = rotatePoint(pointCenter, angleInRadian);

  // 1st point
  const point1 = movePointToNewCoordinates(
    rotatePoint([xCenter, yCenter - r], angleInRadian),
    pointCenterNew,
    pointCenter
  );
  const x1 = point1[0];
  const y1 = point1[1];

  // 2nd point
  const point2 = movePointToNewCoordinates(
    rotatePoint([xCenter - sideLength / 2, yCenter   (h - r)], angleInRadian),
    pointCenterNew,
    pointCenter
  );
  const x2 = point2[0];
  const y2 = point2[1];

  // 3rd point
  const point3 = movePointToNewCoordinates(
    rotatePoint([xCenter   sideLength / 2, yCenter   (h - r)], angleInRadian),
    pointCenterNew,
    pointCenter
  );
  const x3 = point3[0];
  const y3 = point3[1];

  return `${x1},${y1},${x2},${y2},${x3},${y3}`;
};

/** *
 * Move point to the new coordinate regarding center
 *
 * @param point The coordinate of point
 * @param center The new center
 * @param centerOld The old center
 */
const movePointToNewCoordinates = (
  point: [number, number],
  center: [number, number],
  centerOld: [number, number]
): [number, number] => {
  const x = point[0];
  const y = point[1];
  const xCenter = center[0];
  const yCenter = center[1];
  const xCenterOld = centerOld[0];
  const yCenterOld = centerOld[1];
  return [x - xCenter   xCenterOld, y - yCenter   yCenterOld];
};

/** *
 * Rotate point
 *
 * @param point The coordinate of point
 * @param center The angle in radians
 */
const rotatePoint = (point: [number, number], angle: number): [number, number] => {
  const x = point[0];
  const y = point[1];

  const xNew = x * Math.cos(angle) - y * Math.sin(angle);
  const yNew = x * Math.sin(angle)   y * Math.cos(angle);

  return [xNew, yNew];
};