Antv/G2 文档
Antv/G2 双折线图
安装依赖
项目中安装 antv/g2
依赖库:
npm install @antv/g2 --save
安装成功:
项目使用
新建文件 IndicatorTrend.tsx
:
import { defineComponent, PropType, onMounted, ref } from 'vue'
import { useChartAutoResize } from '@/hooks/chart'
import styled from '@/styled-components'
import { Chart } from '@antv/g2';export interface TrendListItem {date: stringcity: stringtempvalue: number
}interface Props {dataList?: TrendListItem[]
}const Container = styled.div` width: 100%;height: 100%;
`const TitleBox = styled.h3`margin-bottom: 10px;
`const ChartContainer = styled.div`height:100%;
`export default defineComponent({props: {dataList: {type: Array as PropType<TrendListItem[]>,default: () => []}},setup() {const dataList = ref<TrendListItem[]>([])const canvasRef = ref<null | HTMLElement>(null)const chartRef = ref<null | InstanceType<typeof Chart>>(null)onMounted(() => {if (canvasRef.value) {const chart = new Chart({container: canvasRef.value,autoFit: true})chartRef.value = chart}refreshChartView()})useChartAutoResize(canvasRef, chartRef)function refreshChartView(){ const chart: any = chartRef.valuechart.clear()setTimeout(() => {chart.data(dataList.value)chart.scale({date: {range: [0, 1],},tempvalue: {nice: true,},});chart.tooltip({showCrosshairs: true,shared: true,});chart.axis('tempvalue', {label: {formatter: (val:number) => {return val + ' °C';},},});chart.line().position('date*tempvalue').color('city').shape('smooth');chart.point().position('date*tempvalue').color('city').shape('circle').style({stroke: '#fff',lineWidth: 1,});chart.render()})}return (props: Props) => {dataList.value = props.dataList || []return (<Container><TitleBox>总趋势</TitleBox> <ChartContainer> <div ref={canvasRef} /> </ChartContainer> </Container>)}}
})
其中,引用了公共方法 hooks/chart
:
import { ref, onUnmounted, watchEffect } from 'vue'
import { changeSizeAfterCanvasResize, deleteGlobalChartItem } from '@/utils/chart'// 没找到ref的类型
export const useChartAutoResize = (canvasRef: any, chartRef: any): void => {const queueIndex = ref<number>(-1)const isCreated = ref(false)function clearThisChart() {queueIndex.value > 0 && deleteGlobalChartItem(queueIndex.value)}// 后续如果需要重复绑定,可以返回一个更新的方法watchEffect(() => {if (!isCreated.value && canvasRef.value && chartRef.value) {clearThisChart()isCreated.value = truequeueIndex.value = changeSizeAfterCanvasResize(canvasRef.value, chartRef.value)}}, {flush: 'post'})onUnmounted(() => {clearThisChart()})
}
utils/chart
文件:
import { Chart } from '@antv/g2'
import { ChartResizeQueueItem } from '@/globalType'const getChartIndex: () => number = createChartIndex()export function getGlobalChartQueue(): ChartResizeQueueItem[] {return window.chartResizeQueue
}export function setGlobalChartQueue(arr: ChartResizeQueueItem[]): ChartResizeQueueItem[] {window.chartResizeQueue = arrreturn window.chartResizeQueue
}export function deleteGlobalChartItem(index: number): void {const queue = getGlobalChartQueue()setGlobalChartQueue(queue.filter(item => item.index !== index))
}// canvas适应父元素的大小,并刷新图表宽高
export function refreshChartSize(canvas: HTMLElement, chart: Chart): void {let width: number = 0let height: number = 0if (canvas.parentNode && getComputedStyle) {const styles = getComputedStyle(canvas.parentNode as HTMLElement)width = Number(styles.width.split('px')[0])height = Number(styles.height.split('px')[0])} else if (canvas.parentNode) {width = (canvas.parentNode as HTMLElement).offsetWidthheight = (canvas.parentNode as HTMLElement).offsetHeight}canvas.setAttribute('width', `${width}px`)canvas.setAttribute('height', `${height}px`)chart.changeSize(width, height)
}// 添加到全局图表队列,并且自动更新宽高
export function changeSizeAfterCanvasResize(canvas: HTMLElement, chart: InstanceType<typeof Chart>): number {const queue = getGlobalChartQueue()const index: number = getChartIndex()refreshChartSize(canvas, chart)setGlobalChartQueue(queue.concat([{ index, canvas, chart }]))return index
}function createChartIndex() {let index: number = 0return (): number => {index++return index}
}
globalType.ts
文件:
export interface ChartResizeQueueItem {index: numbercanvas: HTMLElement,chart: any
}
在父组件中引用 IndicatorTrend.tsx
组件:
<IndicatorTrend dataList={totalTrendList.value}></IndicatorTrend>
数据源为:
totalTrendList.value = [{date: '2023/8/1',city: 'bily',tempvalue: 4623}, {date: '2023/8/1',city: 'cily',tempvalue: 2208}, {date: '2023/8/1',city: 'bill',tempvalue: 182}, {date: '2023/8/2',city: 'bily',tempvalue: 6145}, {date: '2023/8/2',city: 'cily',tempvalue: 2016}, {date: '2023/8/2',city: 'bill',tempvalue: 257}, {date: '2023/8/3',city: 'bily',tempvalue: 508}, {date: '2023/8/3',city: 'cily',tempvalue: 2916}, {date: '2023/8/3',city: 'bill',tempvalue: 289}, {date: '2023/8/4',city: 'bily',tempvalue: 6268}, {date: '2023/8/4',city: 'cily',tempvalue: 4512}, {date: '2023/8/4',city: 'bill',tempvalue: 428}, {date: '2023/8/5',city: 'bily',tempvalue: 6411}, {date: '2023/8/5',city: 'cily',tempvalue: 8281}, {date: '2023/8/5',city: 'bill',tempvalue: 619}, {date: '2023/8/6',city: 'bily',tempvalue: 1890}, {date: '2023/8/6',city: 'cily',tempvalue: 2008}, {date: '2023/8/6',city: 'bill',tempvalue: 87}, {date: '2023/8/7',city: 'bily',tempvalue: 4251}, {date: '2023/8/7',city: 'cily',tempvalue: 1963}, {date: '2023/8/7',city: 'bill',tempvalue: 706}, {date: '2023/8/8',city: 'bily',tempvalue: 2978}, {date: '2023/8/8',city: 'cily',tempvalue: 2367}, {date: '2023/8/8',city: 'bill',tempvalue: 387}, {date: '2023/8/9',city: 'bily',tempvalue: 3880}, {date: '2023/8/9',city: 'cily',tempvalue: 2956}, {date: '2023/8/9',city: 'bill',tempvalue: 488}, {date: '2023/8/10',city: 'bily',tempvalue: 3606}, {date: '2023/8/10',city: 'cily',tempvalue: 678}, {date: '2023/8/10',city: 'bill',tempvalue: 507}, {date: '2023/8/11',city: 'bily',tempvalue: 4311}, {date: '2023/8/11',city: 'cily',tempvalue: 3188}, {date: '2023/8/11',city: 'bill',tempvalue: 548}, {date: '2023/8/12',city: 'bily',tempvalue: 4116}, {date: '2023/8/12',city: 'cily',tempvalue: 3491}, {date: '2023/8/12',city: 'bill',tempvalue: 456}, {date: '2023/8/13',city: 'bily',tempvalue: 6419}, {date: '2023/8/13',city: 'cily',tempvalue: 2852}, {date: '2023/8/13',city: 'bill',tempvalue: 689}, {date: '2023/8/14',city: 'bily',tempvalue: 1643}, {date: '2023/8/14',city: 'cily',tempvalue: 4788}, {date: '2023/8/14',city: 'bill',tempvalue: 280}, {date: '2023/8/15',city: 'bily',tempvalue: 445}, {date: '2023/8/15',city: 'cily',tempvalue: 4319}, {date: '2023/8/15',city: 'bill',tempvalue: 176}]
页面效果: