bizcharts其他問題解決整理


1.對於legend項目比較多的情況下,由於legend超出導致換行(因為對於使用canvas的模式下,右側legend的高度實際上等於canvas畫圖的高度),但是頁面布局不允許換行,解決方式:

  useHtml={true} 將legend的渲染方式改為html的,這樣可以自定義樣式,脫離canvas的控制

<Legend position=‘right’
  useHtml={true}
  g2-legend = {{
    marginLeft: '100px',
    marginTop: '-107px'
  }}
  g2-legend-list={{
    border: 'none'
  }}
/>

2.雙柱狀圖

adjust 聲明幾何標記對象的數據調整方式,可用於繪制層疊圖、擾動圖、分組圖等。支持單一的數據調整方式也支持各種數據調整方式的組合。 支持的調整類型包括: 'stack', 'dodge', 'jitter', 'symmetric'

需要注意的是區分雙軸的數據的參數需要使用字符串區分,比如說不能用 left:true 和 left:false,但是可以轉成 left:’true’ left:’false’

<Geom
            type="interval"
            position="月份*月均降雨量"
            color={"name"}
            adjust={[
              {
                type: "dodge",
                marginRatio: 1 / 32
              }
            ]}
          />

3.帶坐標軸的餅圖

render() {
         const data = [
            { termField: "field1", termCountPercent: 20 },
            { termField: "field2", termCountPercent: 20 },
            { termField: "field3", termCountPercent: 20 },
            { termField: "field4", termCountPercent: 20 },
        ]
        const cols={
            termCountPercent:{tickCount:5}
        }
        return (
            <Chart padding={[20, 20, 20, 20]} forFit scale={cols} data={data}>
                <Coord type="polar" radius={1} scale={[1.1, 1.1]}></Coord>
                <Legend position="right" textStyle={{ fill: '#fff', fontSize: '12' }} offsetX={-10} useHtml={true} />
                <Tooltip crosshairs={{ type: 'cross', style: { stroke: "rgba(255,255,255,0)" } }} />
                <Axis name="termField"
                    label={{ offset: 15, autoRotate: true, formatter: val => `${val}` }}
                    grid={{ type: 'line', lineStyle: { lineWidth: 1, stroke: "#ccc" } }}
                    line={{ stroke: "#FFF" }}
                    tickLine={{ lineWidth: 1, length: 15, stroke: "#ccc" }} />
                <Axis name="termCountPercent"
                    label={null}
                    grid={{ type: 'circle', lineStyle: { lineWidth: 1, stroke: "#ccc" } }}
                    tickLine={null} />
                <Geom
                    type="intervalStack"
                    position="termField*termCountPercent"
                    color={['termField']}
                    opacity={1}
                    style={{ lineWidth: 1 }} />
            </Chart>
        )
    }

4.Geom中 interval 與intervalStack 的區別,

x軸對應的數據只有一份的時候這倆沒有什么區別,在x軸對應的數據有兩份時,intervalStack是層疊柱狀圖,interval只是柱狀圖一根柱子

 

5.View:由 Chart 生成和管理,擁有自己獨立的數據源、坐標系和圖層,用於異構數據的可視化以及圖表組合,一個 Chart 由一個或者多個視圖 View 組成

注意:start 和 end 都是從左上角開始計算的

<View start={{x:0, y:0}} end={{x:1, y:0.5}}/>  // 黃色區域

<View start={{x:0, y:0.65}} end={{x:1, y:1 }}/>  // 紅色區域

6.餅圖點擊每一項的動畫效果控制Geom 的select屬性

開啟、關閉以及設置 shape 對於鼠標 click 事件的響應效果。BizCharts 默認僅為餅圖開啟了選中效果

 

 

7.默認使用 Canvas 渲染,可以改用 SVG 版本、

如何選擇:如果單就圖表庫的視角來看,選擇 Canvas 和 SVG 各有千秋。小畫布、大數據量的場景適合用 Canvas,譬如熱力圖、大數據量的散點圖等。如果畫布非常大,有縮放、平移等高頻的交互,或者移動端對內存占用量非常敏感等場景,可以使用 SVG 的方案。

 8.Aixs 默認日期格式化

bizCharts 和 g2 默認會將符合”YYYY.MM.DD”的日期格式化成”YYYY-MM-DD”(默認先轉成時間戳格式,然后格式化成”-”的,目前看來是只對”YYYY.MM.DD”會格式化,像是”YYYY.MM”不影響),而這個並不是我們系統中想要的話,本來的YYYY.MM.DD”才是我們想要的格式類型,這時候就要自己動手格式化,避免默認操作

Chart有scale={cols} 的屬性,設置scale

 const cols = {
        year:{ formatter: (val) => `${ moment(val).format(“YYYY.MM.DD” )}` },
    };

 

 

9.餅圖的 tooltip 輪播,輪播到當前高亮或者是select

針對theta類型的餅圖:

注意:坐標軸不展示,但是還是要寫的; 

找tooltip輪播的三個點

import React, { Component } from 'react';
import { Chart, Geom, Axis, Tooltip, Coord, Label, Legend, View, Guide, Shape } from 'bizcharts';
import DataSet from '@antv/data-set';
const { DataView } = DataSet;

export default class Basic extends Component {
    constructor() {
        super();
        this.state = {
            tooltipStuff: true, // tooltip是否輪播
            mockData: []  // 頁面數據
        }
    }

    componentDidMount() {
        this.setState({
            mockData: [
                { type: 'type1', value: 250, percent: 25 },
                { type: 'type2', value: 500, percent: 50 },
                { type: 'type3', value: 250, percent: 25 },
            ]
        })
    }

    onGetG2InstanceTooltips = (chart, data) => {
        let basePercent = 0;
        let pointList = [];
        const outerRadius = 0.5, innerRadius = 0.45;
        // 坐標系的內外半徑和data都可以從chart的屬性中找到,為了省事我的代碼里是寫死的
        const coord = chart.get('coord')
        data.map((item, index) => {
            pointList.push({ index: index, point: this.getThetaPiePoint(basePercent, item['newPercent'], coord, outerRadius, innerRadius), data: item })
            basePercent += item['newPercent']
        })
        this.setState({ tooltipStuff: true }, () => {
            this.onActivedPointInterval(pointList, chart)
        })
    }

    getThetaPiePoint = (basePercent, percent, coord, outerRadius, innerRadius) => {
        const { radius, circleCentre } = coord  // circleCentre 圓環圓心所在坐標
        const middleRadius = (outerRadius, innerRadius) / 2  // 找圓環中間的半徑
        const middleLength = middleRadius * radius / outerRadius  // 獲取圓環上新的點的半徑
        const angle = Math.PI * 2 * (basePercent + percent / 2) - Math.PI / 2   // 角度 Math.PI * 2(占比 / 2) - Math.PI / 2  圓環的角度開始的位置在手表的12點中位置
        const x1 = circleCentre.x + middleLength * Math.cos(angle)  // x1 = x0 + r*cos(a)
        const y1 = circleCentre.y + middleLength * Math.sin(angle)  // y1 = y0 + r*sin(a)
        // 取的點是geom每一塊的中心的點,如圖
        return { x: x1, y: y1 }
    }
    // tooltip 輪播與Geom的交互有兩種:select效果,active效果
    // 方案一:select效果
    onSelectedPointInterval = (pointList, chart) => {
        let i = 0
        this.selectedInterval = setInterval(() => {
            if (!!this.state.tooltipStuff) {
                ++i;
                if (i > pointList.length - 1) {
                    i = -1
                } else {
                    const geoms = chart.get('geoms')[0]
                    const items = geoms.get('data')
                    geoms.setSelected(items[pointList[i].index])
                    chart.showTooltip(pointList[i].point)
                }
            }
        }, 1000 * 3);
    }
    // 方案二:active效果,項目中由於每一塊chart占用的空間比較小,所以采用了這種方式
    onActivedPointInterval = (pointList, chart) => {
        let i = 0
        this.activeInterval = setInterval(() => {
            if (!!this.state.tooltipStuff) {
                ++i;
                if (i > pointList.length - 1) {
                    i = -1
                } else {
                    const geoms = chart.get('geoms')[0]
                    const shapes = geoms.getShapes();
                    // _id 是bizcharts用來區分執行動畫的,所以不能再<Chart/> 中加入 {animate:false},在這里用來表示geom的每一項,跟Geom的color屬性傳遞的字段一致,如 _id:"chart-geom0-1-#64d5ec"
                    const shapeItemIndex = shapes.findIndex(item => item._id.includes(pointList[i].data.color))
                    geoms.setShapesActived([shapes[shapeItemIndex]])  // 需要傳入數組
                    chart.showTooltip(pointList[i].point)
                }
            }
        }, 1000 * 3);
    }
    // 鼠標移入
    onPlotMoveTooltips = (ev) => {
        this.setState({ tooltipStuff: false })
    }
    // 鼠標移出
    onPlotLeaveTooltips = (ev) => {
        this.setState({ tooltipStuff: true })
    }


    render() {
        const dv = new DataView()
        // 后台返回的percent頁面展示需要用,所以我定義了一個計算圓環百分比的newPercent,根據value計算出來的,避免了小數位數等問題
        dv.source(this.state.mockData).transform({
            type: 'percent',
            field: 'value',
            dimension: 'type',
            as: 'newPercent'
        })
        const cols = {
            percent: { formatter: (val) => `${(val * 100).toFixed(2)}%` }
        }
        const itemColor = [
            { field: 'type1', color: '#e9b05c' },
            { field: 'type2', color: '#5b6bfe' },
            { field: 'type3', color: '#64d5ec' },
        ]
        itemColorMap = (type) => {
            return itemColor.find(item => item.field === type)["color"]
        }
        return (
            <div>
                {
                    !!this.state.mockData && this.state.mockData.length > 0 ?
                        <Chart height={400} data={dv} scale={cols} forceFit
                            onGetG2Instance={(chart, data) => this.onGetG2InstanceTooltips(chart, dv['rows'])}
                            onPlotMove={(ev) => this.onPlotMoveTooltips(ev)}
                            onPlotLeave={(ev) => this.onPlotLeaveTooltips(ev)}>
                            <Coord type="theta" radius={0.5} innerRadius={0.45} />
                            <Axis name="type" />
                            <Axis name="newPercent" />
                            <Tooltip
                                crosshairs={{ type: "cross", style: { stroke: 'rgba(0,0,0,0)' } }}
                                showTitle={false} />
                            <Geom type="line" position="year*value" size={2} />
                            <Geom
                                type="intervalStack"
                                position="newPercent"
                                color={["type", (type => { itemColorMap(type) })]}
                                opacity={1}
                                select={false}
                                active={[true, { highlight: true }]}
                                tooltip={["type*value*percent", (type, value, percent) => { return { name: type, value: `${value}(${percent.toFixed(2)}%)` } }]} />
                        </Chart> : null
                }
            </div>
        )
    }
}

 

 

10. 未完待續 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM