第一次热力图中的色块图时,差点被官网demo的数据格式吓退了。但是既然产品选择了,作为开发,只能尽最大努力来实现了。于是和同事讨论这个数据格式,照着官网处理后的数据格式,感觉每个数据都要给定具体的做标点才行,这!又一次觉得实现不了。好在没有放弃,继续做各种测试,最后恍然大悟,其实热力图的数据结构和普通的做柱状/折线图没啥区别。
时隔快一年了,当初做的项目现在已经进入了迭代的死循环。而再回头看看当初困扰自己的热力图,似乎还是有些陌生,再看看官网demo,还是搞不明白。想骂自己太笨了,自己写的代码都看不太明白,可又想到以后这可能会成为常态,行吧,也罢,随它吧。
热力图-色块图组件封装(可设置滚动条Slider)
import React from "react";
import {
Chart,
Geom,
Axis,
Tooltip,
Label,
} from "bizcharts";
// @ts-ignore
import Slider from 'bizcharts-plugin-slider';
// @ts-ignore
import DataSet from '@antv/data-set';
import {dealSliderChange, filterSliderData} from "@/pages/charts/utils/chartsCommon";
interface IBasicHeatMapProps {
data: any[]; // 数据源
xAxis: string; // x轴坐标
yAxis: string; // y轴坐标
height?:number;
legendName: string; // 图例对应的变量(数据中表示种类的字段) 热力图中的图例一般用连续型图例
color?: string;// 色块的颜色 ,不填时,使用默认颜色
maxLen?:number;
}
/**
* 基础热力图-色块图
* @param props
* @constructor
*/
const BasicHeatMap:React.FC<IBasicHeatMapProps>=(props)=>{
const {height=400,xAxis,yAxis,data,legendName, color = '#BAE7FF-#1890FF-#0050B3',maxLen}=props;
let flag:boolean=false;
let ds:any;
let dv:any;
// 是否传入maxLen(有滚动条时必须传入)
if(maxLen){
// 设置一个flag,用来判断是否出现滚动条(以及是否需要处理数据)
flag=data.length>maxLen;
if(flag){
const startLength = 0;
const endLength = maxLen - 1;
ds=new DataSet({
state: {
start: data[startLength][xAxis],
end: data[endLength][xAxis],
},
});
dv=ds.createView()
.source(data)
.transform({
type: 'filter',
// eslint-disable-next-line consistent-return
callback: (obj: any) => filterSliderData(flag,ds,data,obj,xAxis),
});
}
}
const cols = {};
cols[xAxis] = {
type: 'cat',
};
cols[yAxis] = {
type: 'cat',
};
return (
<>
<Chart height={height} data={dv||data} forceFit scale={cols}>
<Axis name={xAxis}
grid={{
align: 'center',
lineStyle: {
lineWidth: 1,
lineDash: null,
stroke: '#f0f0f0',
},
showFirstLine: true,
} as any }
/>
<Axis name={yAxis}
grid={{
align: 'center',
lineStyle: {
lineWidth: 1,
lineDash: null,
stroke: '#f0f0f0',
},
} as any}
/>
<Tooltip
/>
<Geom type="polygon"
position={`${xAxis}*${yAxis}`}
color={[legendName, color]}
style={{
stroke: '#fff',
lineWidth: 1,
}}
>
<Label
content={legendName}
offset={-2}
textStyle={{
fill: '#fff',
fontWeight: 'bold',
shadowBlur: 2,
shadowColor: 'rgba(0, 0, 0, .45)',
}}
/>
</Geom>
</Chart>
{
flag &&<Slider
onChange={(obj:any)=>dealSliderChange(obj,ds)}
height={20}
width="auto"
xAxis={xAxis}
yAxis={yAxis}
data={data}
start={ds.state.start}
end={ds.state.end}
padding={[50]}
textStyle={{
fontSize: '0',
}}
backgroundChart={{
type: 'heatmap',
}}
/>
}
</>
);
}
export default BasicHeatMap;
import React,{memo} from 'react';
import BasicHeatMap from "@/pages/charts/compnent/BasicHeatMap";
import {maxLen} from "@/pages/charts/utils/chartsCommon";
const BasicHeatMapMemo=memo(BasicHeatMap);
const radarData=[
{month: "一月份", day:"星期一", sales: 10},
{month: "二月份", day:"星期一", sales: 5},
{month: "三月份", day:"星期一", sales: 10},
{month: "四月份", day:"星期一", sales: 10},
{month: "五月份", day:"星期一", sales: 10},
{month: "六月份", day:"星期一", sales: 10},
{month: "七月份", day:"星期一", sales: 10},
{month: "八月份", day:"星期二", sales: 10},
{month: "九月份", day:"星期一", sales: 10},
{month: "十月份", day:"星期二", sales: 10},
{month: "十一月份", day:"星期一", sales: 10},
{month: "十二月份", day:"星期一", sales: 10},
{month: "一月份", day:"星期二", sales: 10},
{month: "二月份", day:"星期二", sales: 35},
{month: "三月份", day:"星期二", sales: 10},
{month: "四月份", day:"星期二", sales: 60},
{month: "五月份", day:"星期二", sales: 10},
{month: "六月份", day:"星期二", sales: 10},
{month: "七月份", day:"星期二", sales: 10},
{month: "八月份", day:"星期二", sales: 90},
{month: "九月份", day:"星期二", sales: 10},
{month: "十月份", day:"星期二", sales: 330},
{month: "十一月份", day:"星期二", sales: 40},
{month: "十二月份", day:"星期二", sales: 50},
{month: "一月份", day:"星期三", sales: 10},
{month: "二月份", day:"星期三", sales: 35},
{month: "三月份", day:"星期三", sales: 10},
{month: "四月份", day:"星期三", sales: 10},
{month: "五月份", day:"星期三", sales: 10},
{month: "六月份", day:"星期三", sales: 50},
{month: "七月份", day:"星期三", sales: 40},
{month: "八月份", day:"星期三", sales: 90},
{month: "九月份", day:"星期三", sales: 10},
{month: "十月份", day:"星期三", sales: 330},
{month: "十一月份", day:"星期三", sales: 40},
{month: "十二月份", day:"星期三", sales: 50},
{month: "一月份", day:"星期六", sales: 10},
{month: "二月份", day:"星期六", sales: 35},
{month: "三月份", day:"星期六", sales: 1700},
{month: "四月份", day:"星期六", sales: 1070},
{month: "五月份", day:"星期六", sales: 1770},
{month: "六月份", day:"星期六", sales: 580},
{month: "七月份", day:"星期六", sales: 490},
{month: "八月份", day:"星期六", sales:456},
{month: "九月份", day:"星期六", sales: 1000},
{month: "十月份", day:"星期六", sales: 630},
{month: "十一月份", day:"星期六", sales: 490},
{month: "十二月份", day:"星期六", sales: 560},
];
const ChartsIndex:React.FC<{}>=()=>{
return(
<div style={{background:'white'}}>
<h1>bizCharts图表封装</h1>
<h2>热力图-色块图</h2>
<BasicHeatMapMemo data={radarData} xAxis="month" yAxis="day" legendName="sales" maxLen={maxLen}/>
</div>
);
}
export default ChartsIndex;