bizcharts之分組箱形圖

一、所謂前言

   公司某個項目後期優化,分組區間柱狀圖改成分組箱形圖,因爲這兩天剛好用到箱形圖,就想着分組箱形圖與箱型圖之間應該和柱狀圖與分組柱狀圖一樣,想着,就去查找官網,結果,就4個橫座標、3個圖例,源數據居然有150條,3(圖例)、4(橫座標)、5(單個箱形圖數據)怎麼也湊不到150,好吧,瞬間放棄了,換個思路。

   輸出了官網轉換後的數據,12個,這才符合我的認知嘛。可是每個卻又有4個字段,其中“value是什麼意思?不得而知了。琢磨半天,也沒想明白,於是在羣裏問,邊問邊自己不斷研究,試着自己將value字段去掉,發現並沒有什麼影響,好吧……是我想多了,正常思路就行,誰讓我一開始就慫了。

二、代碼

import React from 'react';
import { Chart, Geom, Axis, Tooltip, Legend, G2 } from 'bizcharts';

interface IGropuedBoxChartProps {
  height?: number;
  data: any[];
  xAxis: string; // x軸座標
  // yAxis: string; // y軸座標
  boxValue: string; // 代表值的字段
  xNickName?: string;
  yNickName?: string;
  xUnitName?: string;
  yUnitName?: string;
  legendName: string; // 圖例名稱
  xUnitPosition?: string[];
  yUnitPosition?: string[];
  colors?: string[];
}

/**
 * 分組箱形圖
 * @param props
 * @constructor
 */
const GropuedBoxChart: React.FC<IGropuedBoxChartProps> = props => {
  const {
    height = 400,
    data = [],
    xAxis,
    xNickName,
    yNickName,
    legendName = [],
    boxValue = '',
    colors,
  } = props;

  const cols: {
    [key: string]: { [key: string]: string | number | string[] | number[] | any };
  } = {};
  cols[xAxis] = {
    alias: xNickName || '',
  };
  cols[boxValue] = {
    alias: yNickName || '',
  };
  const toolTipItemTpl =
    '<li data-index={index} style="margin-bottom:4px;">' +
    '<span style="color:#242424;font-size:13px;">{name}</span><br />' +
    '<span style="color:##999999;font-size:12px;">最高分:{high}分</span>, ' +
    '<span>上四分位分:{q3}分</span>, ' +
    '<span>平均分:{median}分</span>, ' +
    '<span>下四分位分:{q1}分</span>, ' +
    '<span>最低分:{low}分</span>' +
    '</li>';

  function getCurrentColor(key: string): string {
    // 獲取所有的圖例信息
    const lend: string[] = [];
    data.forEach((item: any) => {
      lend.push(item[`${legendName}`]);
    });
    const lendData = [...new Set(lend)];
    const resultMap = [];
    let result: string = '';
    if (colors && colors.length > 0) {
      // 傳入顏色
      for (let i = 0; i < colors.length && i < lendData.length; i += 1) {
        const obj: any = {};
        obj[`${lendData[i]}`] = colors[i];
        resultMap.push(obj);
      }
    } else {
      // 未傳入顏色
      for (let i = 0; i < lendData.length; i += 1) {
        const obj = {};
        obj[`${lendData[i]}`] = G2.Global.colors[i];
        resultMap.push(obj);
      }
    }

    if (resultMap && resultMap.length > 0) {
      const rr = resultMap.filter((item: any) => item[`${key}`]);
      if (rr && rr.length > 0) {
        result = rr[0][`${key}`];
      }
    }
    return result;
  }
  return (
      <Chart height={height} data={data} padding="auto" forceFit scale={cols}>
        <Axis
        />
        <Tooltip
          showTitle={false}
          crosshairs={{
            type: 'rect',
            style: {
              fill: '#E4E8F1',
              fillOpacity: 0.43,
            },
          }}
          itemTpl={toolTipItemTpl}
        />
        <Legend
          position="top-right"
          textStyle={{
            textAlign: 'start', // 文本對齊方向,可取值爲: start middle end
            fill: '#FFF', // 文本的顏色
          }}
        />
        <Geom
          type="schema"
          position={`${xAxis}*${boxValue}`}
          shape="box"
          color={[`${legendName}`, val => getCurrentColor(val)]}
          style={[
            `${legendName}`,
            {
              stroke: 'rgba(0, 0, 0, 0.45)',
              fill: (val: any) => getCurrentColor(val),
              fillOpacity: 0.3,
            },
          ]}
          adjust="dodge"
          tooltip={
            [
              `${xAxis}*${legendName}*${boxValue}`,
              (x: string, legend: string, values: string[]) => ({
                name: `${legend}-${x}`,
                low: values[0],
                q1: values[1],
                median: values[2],
                q3: values[3],
                high: values[4],
              }),
            ] as any
          }
        />
      </Chart>
  );
};

export default GropuedBoxChart;

三、小結

      分組箱形圖的難點在於數據結構,於我而言,主要是被官網的源數據嚇到了,還有就是單個箱型圖掌握的不好。

      箱型圖與其他圖標我覺得最大的不同在於color需要明確的設置出來,單個箱形圖好辦,寫死就行,而多個就比較麻煩了,需要根據數據自己處理下,而這裏又涉及到顏色使用自帶顏色還是自定義顏色的問題,代碼中均有考慮到。

     箱型圖的tooltip也需要自定義,同樣的,單個的好處理,官網demo有,而多個的情況下,官網demo的tooltip給人的感覺就有些敷衍了。按照單個的思路,寫出了多個分組箱形圖的tooltip,發現如果超過三四個,就會太長,最終索性,一個箱型圖佔一行,勉強能看得過去了。

    很多事情在自己認輸的那一刻就徹底輸了,後面再怎麼讓努力都是垂死掙扎了。消極的心理暗示真的是害死人。做人也是,敲代碼更是如此。

  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章