Untitled

mail@pastecode.io avatarunknown
plain_text
2 months ago
4.6 kB
2
Indexable
Never
import React from 'react';
import { Dimensions } from 'react-native';
import * as d3 from 'd3';
import * as SvgC from 'react-native-svg';
import { View } from 'react-native-ui-lib';
import { useColors } from '../../hooks/useColors';
const { Rect, G, Svg, Text } = SvgC;

export function TreeMap() {
  const { colors }: any = useColors();

  const data = {
    name: 'Root',
    children: [
      {
        name: 'A',
        children: [
          {
            category: 'A',
            name: 'KCHOL',
            value: 20.4,
            persentage: +1.07,
          },
          {
            category: 'A',
            name: 'FROTO',
            value: 18,
            persentage: -0.18,
          },
          {
            category: 'A',
            name: 'ENKAI',
            value: 13.3,
            persentage: +0.51,
          },
          {
            category: 'A',
            name: 'EREGL',
            value: 18.4,
            persentage: +1.0,
          },
        ],
      },
      {
        name: 'B',
        children: [
          {
            category: 'B',
            name: 'TCELL',
            value: 9.4,
            persentage: +2.72,
          },
          {
            category: 'B',
            name: 'TOASO',
            value: 7.9,
            persentage: +1.04,
          },
          {
            category: 'B',
            name: 'AEFES',
            value: 6.9,
            persentage: 3.85,
          },
          {
            category: 'B',
            name: 'ENJSA',
            value: 6.6,
            persentage: +1.47,
          },
          {
            category: 'B',
            name: 'OTKAR',
            value: 3.3,
            persentage: +0.12,
          },
          {
            category: 'B',
            name: 'ECILC',
            value: 10.5,
            persentage: +2.46,
          },
          {
            category: 'B',
            name: 'NUHCM',
            value: 5.2,
            persentage: -2.33,
          },
          {
            category: 'B',
            name: 'CCOLA',
            value: 3.1,
            persentage: +1.66,
          },
          {
            category: 'B',
            name: 'ISMEN',
            value: 5.2,
            persentage: -0.31,
          },
          {
            category: 'B',
            name: 'EGEEN',
            value: 6.3,
            persentage: -3,
          },
          {
            category: 'B',
            name: 'RANDOM',
            value: 2.3,
            persentage: -1,
          },
          {
            category: 'B',
            name: 'RANDOM2',
            value: 2.3,
            persentage: -1.2,
          },
        ],
      },
    ],
  };

  const windowWidth = Dimensions.get('window').width;
  const windowHeight = 640;

  const root: any = d3
    .hierarchy(data)
    .sum((d: any) => d.value)
    .sort((a: any, b: any) => b.value - a.value);
  const treemapRoot = d3.treemap().size([windowWidth, windowHeight]).padding(1)(root);

  const colorScale = d3
    .scaleQuantize()
    .domain([-4, 4])
    .range([
      colors.treeMapRdBg70,
      colors.treeMapRdBg55,
      colors.treeMapRdBg30,
      colors.treeMapWh30,
      colors.treeMapGrBg30,
      colors.treeMapGrBg50,
      colors.treeMapGrBg70,
    ]);

  return data ? (
    <View center>
      <Svg height={windowHeight} width={windowWidth} viewBox={`0 0 ${windowWidth} ${windowHeight}`}>
        {treemapRoot.leaves().map((leave: any) => {
          const percentage = leave.data.persentage;
          const color = colorScale(percentage);
          return (
            <G key={`${leave.data.name}_${leave.x0}_${leave.y0}`} transform={`translate(${leave.x0},${leave.y0})`}>
              <Rect width={leave.x1 - leave.x0} height={leave.y1 - leave.y0} fill={color} />
              <Text
                x={(leave.x1 - leave.x0) / 2}
                y={(leave.y1 - leave.y0) / 2}
                fontSize="18"
                fontWeight={600}
                textAnchor="middle"
                alignmentBaseline="middle"
                fill={colors.primaryText}>
                {leave.data.name}
              </Text>
              <Text
                x={(leave.x1 - leave.x0) / 2}
                y={(leave.y1 - leave.y0) / 2 + 16}
                fontSize="18"
                fontWeight={600}
                textAnchor="middle"
                alignmentBaseline="middle"
                fill={colors.primaryText}>
                {`${leave.data.persentage > 0 ? '+' : ''}${leave.data.persentage}%`}
              </Text>
            </G>
          );
        })}
      </Svg>
    </View>
  ) : null;
}

export default TreeMap;