antvis/G2

交互状态没有共享 #5393

xuanYU-L posted onGitHub

G2 Version: v5.0.18 Platform: mac Mini Showcase(like screenshots): CodePen Link:

这边使用g2 v5.0.18版本发现一些多个图例存在时的问题: image color图例、size图例、opacity图例

1、调整size图例和opacity图例时,color图例后两个圆点无法点击,并且例如点击绿色图例圆点消失的是橙色气泡图,或者其他颜色原本点成灰色还会显示出气泡图。

先是调整size图例数值区间调大时,color图例只剩下绿色圆点。 然后size图例往回调小时,color图例剩下绿色和橙色圆点,点击绿色圆点消失的是橙色气泡图。 然后size图例往回调到起点时,color图例三个圆点都出来后,后面两个圆点无法点击。 image image image image

先滑动滑块,在点击低风险图例圆点,气泡图卡外面了 image

image

代码: import React, { useEffect, useRef, useState } from '@alipay/bigfish/react'; import { Chart } from '@antv/g2'; import insertCss from 'insert-css'; import moment from 'moment'; import numeral from 'numeral';

insertCss(` .tooltip-content { width: 190px; font-family: PingFangSC-Regular; font-size: 12px; }

.tooltip-content-head { position: relative; padding-left: 16px; line-height: 12px; color: rgba(0, 0, 0, 0.45); margin-bottom: 12px; } .tooltip-content-bottom { line-height: 12px; margin-bottom: 12px; } .tooltip-content-source { color: rgba(0,0,0,0.65); } .tooltip-content-dot { position: absolute; top: 2px; left: 0; width: 8px; height: 8px; border-radius: 100%;

} .tooltip-content-title { margin-lfet: 8px; } `);

const dataChart = [{"orgCode":"YCBK","orgName":"邮储银行","totalScore":45,"avgBalChangeRate":"-0.8507559847707351","riskCostNomi":"169259767.63063708","riskCostDenomi":"1429916983.7782702","riskCost":"0.11837034565699187","orgBalWto":"615823140.4216129","avgPrice":0.16038153683018658,"avgPriceNomi":"93747809.49581838","avgPriceDenomi":"584529936.2300001","dt":"20230812","isHighRisk":true,"isVIP":true,"balScaleChange":-0.8507559847707351,"balScaleChangeRate":-0.8507559847707351,"balScale":"6.16亿","balScaleRate":6.16,"avgPriceRate":1603,"riskType":"高风险","continent":"高风险","riskTypeColor":"#FF4D4F","stroke":"rgba(255,77,79,0.85)"},{"orgCode":"GZBK","orgName":"广州银行","totalScore":49,"avgBalChangeRate":"-0.1516468109272116","riskCostNomi":"275063027.0821698","riskCostDenomi":"4968075820.883594","riskCost":"0.05536610893213958","orgBalWto":"5187851735.288063","avgPrice":0.12873358334440574,"avgPriceNomi":"705296411.9724076","avgPriceDenomi":"5478728966.05","dt":"20230812","isHighRisk":true,"isVIP":false,"balScaleChange":-0.1516468109272116,"balScaleChangeRate":-0.1516468109272116,"balScale":"51.88亿","balScaleRate":51.88,"avgPriceRate":1287,"riskType":"高风险","continent":"高风险","riskTypeColor":"#FF4D4F","stroke":"rgba(255,77,79,0.85)"},{"orgCode":"GLBK","orgName":"桂林银行","totalScore":66,"avgBalChangeRate":"0.003695447345263067","riskCostNomi":"600491166.6025687","riskCostDenomi":"9559295652.487629","riskCost":"0.06281751171136778","orgBalWto":"8097552564.695484","avgPrice":0.13263734492807341,"avgPriceNomi":"1040079491.752235","avgPriceDenomi":"7841528283.879999","dt":"20230812","isHighRisk":true,"isVIP":false,"balScaleChange":0.003695447345263067,"balScaleChangeRate":0.003695447345263067,"balScale":"80.98亿","balScaleRate":80.98,"avgPriceRate":1326,"riskType":"高风险","continent":"高风险","riskTypeColor":"#FF4D4F","stroke":"rgba(255,77,79,0.85)"},{"orgCode":"CDBK","orgName":"承德银行","totalScore":67,"avgBalChangeRate":"0.06587635968697722","riskCostNomi":"255994961.01590857","riskCostDenomi":"6160818680.615819","riskCost":"0.04155210115521854","orgBalWto":"6206814347.390323","avgPrice":0.13174827261834923,"avgPriceNomi":"826993526.4869103","avgPriceDenomi":"6277073012.43","dt":"20230812","isHighRisk":false,"isVIP":false,"balScaleChange":0.06587635968697722,"balScaleChangeRate":0.06587635968697722,"balScale":"62.07亿","balScaleRate":62.07,"avgPriceRate":1317,"riskType":"中风险","continent":"中风险","riskTypeColor":"#FAAD14","stroke":"rgba(250,173,20,0.85)"},{"orgCode":"FMBK","orgName":"富民银行","totalScore":55,"avgBalChangeRate":"-0.5609709555337137","riskCostNomi":"64090376.256756626","riskCostDenomi":"1434944376.9154685","riskCost":"0.04466401436028078","orgBalWto":"1324631505.269355","avgPrice":0.15369588471879986,"avgPriceNomi":"205689676.48041517","avgPriceDenomi":"1338290071.0499992","dt":"20230812","isHighRisk":false,"isVIP":false,"balScaleChange":-0.5609709555337137,"balScaleChangeRate":-0.5609709555337137,"balScale":"13.25亿","balScaleRate":13.25,"avgPriceRate":1536,"riskType":"中风险","continent":"中风险","riskTypeColor":"#FAAD14","stroke":"rgba(250,173,20,0.85)"},{"orgCode":"SXBK","orgName":"三湘银行","totalScore":55,"avgBalChangeRate":"0.27275891020381715","riskCostNomi":"271595400.3385015","riskCostDenomi":"6301785645.9534","riskCost":"0.04309816544028319","orgBalWto":"6479370215.694192","avgPrice":0.13156471905163372,"avgPriceNomi":"857849679.7804782","avgPriceDenomi":"6520362647.099999","dt":"20230812","isHighRisk":false,"isVIP":false,"balScaleChange":0.27275891020381715,"balScaleChangeRate":0.27275891020381715,"balScale":"64.79亿","balScaleRate":64.79,"avgPriceRate":1315,"riskType":"中风险","continent":"中风险","riskTypeColor":"#FAAD14","stroke":"rgba(250,173,20,0.85)"},{"orgCode":"HEBBK","orgName":"河北银行","totalScore":53,"avgBalChangeRate":"0.256671013019488","riskCostNomi":"115828746.7798586","riskCostDenomi":"2679584010.9058065","riskCost":"0.0432263912265635","orgBalWto":"2764237940.007743","avgPrice":0.13657539928189077,"avgPriceNomi":"378759892.6209841","avgPriceDenomi":"2773265863.489998","dt":"20230812","isHighRisk":false,"isVIP":false,"balScaleChange":0.256671013019488,"balScaleChangeRate":0.256671013019488,"balScale":"27.64亿","balScaleRate":27.64,"avgPriceRate":1365,"riskType":"中风险","continent":"中风险","riskTypeColor":"#FAAD14","stroke":"rgba(250,173,20,0.85)"},{"orgCode":"HYBK","orgName":"韩亚银行","totalScore":61,"avgBalChangeRate":"0.012207477968679025","riskCostNomi":"267466878.6445401","riskCostDenomi":"6312096256.088739","riskCost":"0.04237370087418069","orgBalWto":"6331511228.401936","avgPrice":0.1334921122863248,"avgPriceNomi":"846551006.8058629","avgPriceDenomi":"6341580729.429999","dt":"20230812","isHighRisk":false,"isVIP":false,"balScaleChange":0.012207477968679025,"balScaleChangeRate":0.012207477968679025,"balScale":"63.32亿","balScaleRate":63.32,"avgPriceRate":1334,"riskType":"中风险","continent":"中风险","riskTypeColor":"#FAAD14","stroke":"rgba(250,173,20,0.85)"},{"orgCode":"CABK","orgName":"长安银行","totalScore":58,"avgBalChangeRate":"0.10847247917297102","riskCostNomi":"65097704.79767686","riskCostDenomi":"2970635064.686625","riskCost":"0.02191373338702042","orgBalWto":"3223642968.8416123","avgPrice":0.12822458558680006,"avgPriceNomi":"430678566.5714824","avgPriceDenomi":"3358783064.89","dt":"20230812","isHighRisk":false,"isVIP":false,"balScaleChange":0.10847247917297102,"balScaleChangeRate":0.10847247917297102,"balScale":"32.24亿","balScaleRate":32.24,"avgPriceRate":1282,"riskType":"低风险","continent":"低风险","riskTypeColor":"#52C41A","stroke":"rgba(82,196,26,0.85)"},{"orgCode":"JJBK","orgName":"九江银行","totalScore":60,"avgBalChangeRate":"0.8022664549639222","riskCostNomi":"93924229.55018862","riskCostDenomi":"2595908110.185025","riskCost":"0.036181646484972886","orgBalWto":"2911954659.70129","avgPrice":0.13218372193032452,"avgPriceNomi":"394853594.695074","avgPriceDenomi":"2987157487.539999","dt":"20230812","isHighRisk":false,"isVIP":false,"balScaleChange":0.8022664549639222,"balScaleChangeRate":0.8022664549639222,"balScale":"29.12亿","balScaleRate":29.12,"avgPriceRate":1321,"riskType":"低风险","continent":"低风险","riskTypeColor":"#52C41A","stroke":"rgba(82,196,26,0.85)"},{"orgCode":"SZBK","orgName":"苏州银行","totalScore":43,"avgBalChangeRate":"0.14461715121015525","riskCostNomi":"112684527.39865576","riskCostDenomi":"4038474381.844931","riskCost":"0.02790274661769109","orgBalWto":"4005784656.6625805","avgPrice":0.13702523322787985,"avgPriceNomi":"560573799.39074","avgPriceDenomi":"4091026055.4600015","dt":"20230812","isHighRisk":false,"isVIP":false,"balScaleChange":0.14461715121015525,"balScaleChangeRate":0.14461715121015525,"balScale":"40.06亿","balScaleRate":40.06,"avgPriceRate":1370,"riskType":"低风险","continent":"低风险","riskTypeColor":"#52C41A","stroke":"rgba(82,196,26,0.85)"},{"orgCode":"XABK","orgName":"西安银行","totalScore":67,"avgBalChangeRate":"0.5519988697153078","riskCostNomi":"293047116.12518847","riskCostDenomi":"8561219404.553542","riskCost":"0.03422960004614793","orgBalWto":"9035606030.642258","avgPrice":0.13996514581500996,"avgPriceNomi":"1271255211.4049215","avgPriceDenomi":"9082655571.159996","dt":"20230812","isHighRisk":false,"isVIP":false,"balScaleChange":0.5519988697153078,"balScaleChangeRate":0.5519988697153078,"balScale":"90.36亿","balScaleRate":90.36,"avgPriceRate":1399,"riskType":"低风险","continent":"低风险","riskTypeColor":"#52C41A","stroke":"rgba(82,196,26,0.85)"},{"orgCode":"ZJGNSBK","orgName":"张家港农商行","totalScore":57,"avgBalChangeRate":"0.4854038603199739","riskCostNomi":"93070843.61587267","riskCostDenomi":"3555402888.955527","riskCost":"0.026177298754238833","orgBalWto":"3802429408.5125813","avgPrice":0.13276360264510398,"avgPriceNomi":"506348587.2303673","avgPriceDenomi":"3813911171.0000005","dt":"20230812","isHighRisk":false,"isVIP":false,"balScaleChange":0.4854038603199739,"balScaleChangeRate":0.4854038603199739,"balScale":"38.02亿","balScaleRate":38.02,"avgPriceRate":1327,"riskType":"低风险","continent":"低风险","riskTypeColor":"#52C41A","stroke":"rgba(82,196,26,0.85)"},{"orgCode":"ZJNSBK","orgName":"紫金农商行","totalScore":50,"avgBalChangeRate":"-0.028714607782728125","riskCostNomi":"15197770.258584877","riskCostDenomi":"718652400.0163983","riskCost":"0.021147595497125023","orgBalWto":"737720574.8938708","avgPrice":0.14024762929945567,"avgPriceNomi":"103870369.89733511","avgPriceDenomi":"740621217.0299997","dt":"20230812","isHighRisk":false,"isVIP":false,"balScaleChange":-0.028714607782728125,"balScaleChangeRate":-0.028714607782728125,"balScale":"7.38亿","balScaleRate":7.38,"avgPriceRate":1402,"riskType":"低风险","continent":"低风险","riskTypeColor":"#52C41A","stroke":"rgba(82,196,26,0.85)"}]

const G2chart = (props: any) => { const { dataChart = [], productCode = 'JIEBEI_PF23', widthChart, heightChart } = props; const chartNodeRef = useRef<any>(); const [chartInstance, setChartInstance] = useState<any>(null);

const getRatioForce = (values: any) => { return values ? numeral(parseFloat(values)).format('0.00%') : 0; };

useEffect(() => { if (chartNodeRef?.current) { const chart = new Chart({ container: 'container', theme: 'classic', autoFit: true, height: heightChart || 420, });

  // chart.interaction('fisheye');
  chart.interaction('elementHighlight', true);

  const interval = chart
    .point()
    .data([])
    .encode('x', 'balScaleChangeRate')
    .encode('y', 'totalScore')
    // .encode('series', 'riskType')
    .encode('size', 'balScaleRate')
    .encode('color', 'riskType')
    .encode('opacity', 'avgPriceRate')
    .encode('shape', 'point')
    .scale('y', { domain: [0, 100] })
    .label({
      text: 'orgName',
      formatter: (item: any, data: any) => {
        return data?.isHighRisk || data?.isVIP ? item : '';
      },
      position: 'inside',
      // transform: [
      //   {
      //     type: 'overflowHide',
      //   },
      // ],
      style: {
        fontSize: 12,
        fill: 'rgba(0,0,0,0.85)',
        pointerEvents: 'none',
      },
    })
    .scale('x', {
      type: 'linear',
      domain: [-2, 2],
      // tickCount: 10,
    }) // 指定值域
    .scale('size', { type: 'log', range: [6, 40] })
    // .style('fill', (datum, index, data) => {
    //   const { riskTypeColor } = datum;
    //   if (riskTypeColor) return riskTypeColor;
    //   return '#52C41A';
    // })
    .scale('color', {
      type: 'ordinal',
      // range: ['#FF4D4F', '#FAAD14', '#52C41A'],
      relations: [
        [(d: any) => d === '高风险', '#FF4D4F'], // 如果是值为 undefined,那么为灰色
        [(d: any) => d === '中风险', '#FAAD14'], // 如果是值为 undefined,那么为灰色
        [(d: any) => d === '低风险', '#52C41A'], // 如果是值为 undefined,那么为灰色
      ],
    })
    .style('lineWidth', 1)
    .style('fillOpacity', (datum: any, index: any, data: any) => {
      const { avgPrice } = datum;
      let avgPriceKey = 0.1;

      if (productCode === 'HUABEI') {
        if (avgPrice <= 0.04) {
          avgPriceKey = 0.12;
        } else if (avgPrice > 0.04 && avgPrice <= 0.05) {
          avgPriceKey = 0.16;
        } else if (avgPrice > 0.05 && avgPrice <= 0.06) {
          avgPriceKey = 0.2;
        } else if (avgPrice > 0.06 && avgPrice <= 0.07) {
          avgPriceKey = 0.24;
        } else if (avgPrice > 0.07 && avgPrice <= 0.08) {
          avgPriceKey = 0.28;
        } else if (avgPrice > 0.08 && avgPrice <= 0.09) {
          avgPriceKey = 0.32;
        } else if (avgPrice > 0.09 && avgPrice <= 0.1) {
          avgPriceKey = 0.36;
        } else if (avgPrice > 0.1 && avgPrice <= 0.11) {
          avgPriceKey = 0.4;
        } else if (avgPrice > 0.11 && avgPrice <= 0.12) {
          avgPriceKey = 0.44;
        } else if (avgPrice > 0.12 && avgPrice <= 0.13) {
          avgPriceKey = 0.48;
        } else if (avgPrice > 0.13) {
          avgPriceKey = 0.52;
        }
      } else {
        if (avgPrice <= 0.12) {
          avgPriceKey = 0.12;
        } else if (avgPrice > 0.12 && avgPrice <= 0.125) {
          avgPriceKey = 0.16;
        } else if (avgPrice > 0.125 && avgPrice <= 0.13) {
          avgPriceKey = 0.2;
        } else if (avgPrice > 0.13 && avgPrice <= 0.135) {
          avgPriceKey = 0.24;
        } else if (avgPrice > 0.135 && avgPrice <= 0.14) {
          avgPriceKey = 0.28;
        } else if (avgPrice > 0.14 && avgPrice <= 0.145) {
          avgPriceKey = 0.32;
        } else if (avgPrice > 0.145 && avgPrice <= 0.15) {
          avgPriceKey = 0.36;
        } else if (avgPrice > 0.15 && avgPrice <= 0.155) {
          avgPriceKey = 0.4;
        } else if (avgPrice > 0.155 && avgPrice <= 0.16) {
          avgPriceKey = 0.44;
        } else if (avgPrice > 0.16 && avgPrice <= 0.165) {
          avgPriceKey = 0.48;
        } else if (avgPrice > 0.165) {
          avgPriceKey = 0.52;
        }
      }

      return Number(avgPriceKey);
    })
    // .animate('enter', { type: 'zoomIn', duration: 1000 })
    .axis('y', {
      title: '机构配合度/联合风控度',
      style: {
        // dy: 15,
      },
    })
    .axis('x', { title: '日均规模变化率', labelFormatter: '.0%' })
    .legend('size', {
      title: '余额规模',
      labelFormatter: (datum: any, index: any, data: any) => {
        return `${datum.label}亿`;
      },
      color: ['#BFEAAA'],
      length: 200,
      width: 180,
      layout: { justifyContent: 'center' },
    })
    .legend('color', {
      title: '风险成本',
      length: 180,
      width: 180,
      gridRow: 1,
      gridCo: 1,
      justifyContent: 'flex-start',
      layout: { justifyContent: 'center' },
    })
    .legend('opacity', {
      title: '机构均价',
      labelFormatter: (datum: any, index: any, data: any) => {
        return `${datum.label / 100}%`;
      },
      color: ['#E5F7DD', '#BFEAAA'],
      length: 180,
      width: 180,
      layout: { justifyContent: 'center' },
      // labelFormatter: '.0%',
    })
    .state('active', {
      stroke: (d) => {
        return d?.stroke || 'rgba(82,196,26,0.85)';
      },
      lineWidth: 2,
    })
    .tooltip({
      text: 'orgName',
      title: (d: any) => {
        return d?.orgName;
      },
      items: [
        (d: any, index, data, column) => {
          return {
            name: '数据查询日期', // 指定 item 的名字
            value: moment(d.dt).format('YYYY-MM-DD'), // 使用 y 通道的值
          };
        },
        (d: any, index, data, column) => {
          return {
            name: '日均规模变化率', // 指定 item 的名字
            value: getRatioForce(d.balScaleChange), // 使用 y 通道的值
          };
        },
        (d: any, index, data, column) => {
          return {
            name: '联合风控度', // 指定 item 的名字
            value: d.totalScore, // 使用 y 通道的值
          };
        },
        (d: any, index, data, column) => {
          return {
            name: '风险成本', // 指定 item 的名字
            value: getRatioForce(d.riskCost), // 使用 y 通道的值
          };
        },
        (d: any, index, data, column) => {
          return {
            name: '余额规模', // 指定 item 的名字
            value: d.balScale, // 使用 y 通道的值
          };
        },
        (d: any, index, data, column) => {
          return {
            name: '机构均价', // 指定 item 的名字
            value: getRatioForce(d.avgPrice), // 使用 y 通道的值
          };
        },
      ],
    })
    .slider('y', true)
    .slider('x', true)
    .slider({
      x: { labelFormatter: '.0%' },
      y: { labelFormatter: '~s' },
    });

  chart
    .lineY()
    .data([60]) // 标注 50g/day 的线
    .style('stroke', 'rgba(65,97,128,0.65)')
    .style('lineWidth', 0.5)
    .label({
      // 设置标注的 label
      text: '联合风控度60分',
      position: 'right',
      style: {
        textBaseline: 'bottom',
        fill: 'rgba(44,53,66,0.65)',
        pointerEvents: 'none',
      },
    });

  chart
    .lineX()
    .data([0]) // 标注 65g/day 的线
    .style('stroke', 'rgba(65,97,128,0.65)')
    .style('lineWidth', 0.5)
    .label({
      // 设置标注的 label
      text: '较上一年未变动',
      position: 'top-left',
      style: {
        textBaseline: 'bottom',
        dy: 15,
        fill: 'rgba(44,53,66,0.65)',
        pointerEvents: 'none',
      },
    });

  chart.interaction('tooltip', {
    // render 回调方法返回一个innerHTML 或者 ReactNode
    render: (event: any, datas: any) => {
      const { title, items } = datas;
      if (items.length > 0 && items[0]) {
        let inDiv = ``;
        items?.forEach((list: any, index: any) => {
          inDiv =
            inDiv +
            `
                <div
                  class='tooltip-content-bottom'
                >
                  <span
                    class='tooltip-content-source'
                  >
                    ${list?.name}:
                  </span>
                  <span style="float: right;">
                    ${list?.value}
                  </span>
                </div>
                `;
        });
        const outDiv = `
          <div
            class='tooltip-content'
          >
            <div
              class='tooltip-content-head'
            >
            <span class='tooltip-content-dot' style="background: ${items[0]?.color};"></span> 
            <span class='tooltip-content-title'>${title}</span>
            </div>
            ${inDiv}
          </div>
        `;

        return outDiv;
      }
    },
  });

  setChartInstance(interval);

  chart.render();
}

}, []);

useEffect(() => { if (chartInstance) { if (dataChart?.length > 0) { const min = Math.min( ...dataChart.map((item: any) => parseFloat(item.balScaleChangeRate)), ); const max = Math.max( ...dataChart.map((item: any) => parseFloat(item.balScaleChangeRate)), );

    let minNew = 0;
    let maxNew = 0;
    if (0 - min > max) {
      if (0 - min > 1) {
        minNew = -1;
        maxNew = 1;
      } else {
        minNew = min;
        maxNew = -min;
      }
    } else {
      if (max > 1) {
        minNew = -1;
        maxNew = 1;
      } else {
        minNew = -max;
        maxNew = max;
      }
    }

    chartInstance?.scale('x', {
      type: 'linear',
      domain: [
        parseFloat(Number(minNew).toFixed(2)),
        parseFloat(Number(maxNew).toFixed(2)),
      ],
      // tickCount: 8,
    });
    chartInstance?.changeData(dataChart);
  } else {
    chartInstance?.changeData([]);
  }
}

}, [dataChart]);

return ( <div id="container" ref={chartNodeRef} style={{ height: heightChart || 420, width: widthChart || 710 }} /> ); };

export default G2chart;


Fund this Issue

$0.00
Funded

Pull requests