ECharts 快速使用
最终效果
使用介绍
echarts图表的绘制,大体分为三步:
- 根据 DOM实例,通过 echarts.init方法,生成 echarts实例
- 构建 options配置对象,整个echarts的样式,皆有该对象决定
- 最后通过
实例.setOption
方法,设置配置对象配置对象是echarts中最复杂的部分,也就是核心。
<!-- 为 ECharts 准备一个定义了宽高的 DOM -->
<div id="main" style="width: 600px;height:400px;"></div>
<script type="text/javascript">// 基于准备好的dom,初始化echarts实例const myChart = echarts.init(document.getElementById('main'));// 指定图表的配置项和数据const option = {title: {text: 'ECharts 入门示例'},tooltip: {},legend: {data: ['销量']},xAxis: {data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']},yAxis: {},series: [{name: '销量',type: 'bar',data: [5, 20, 36, 10, 10, 20]}]};// 使用刚指定的配置项和数据显示图表。myChart.setOption(option);
</script>
那么最难的 option 配置对象怎么看呢?这里我们可以跟着官方示例学习:echarts 示例,通过不断修改示例达到我们预期的效果。
还有一个难点,就是如果我们的配置写的不完全或者写的不对,是不能够看到部分效果的,也就是说,要么就是一张完整的图表,要么就是一张空白。
经过上述种种难点,我总结出一个使用 echarts 的好办法,结合 ChatGPT。
我们先向他描述图表的大致形状,然后让它先生成一个能够运行的图表,之后我们不断细化需求,进行更改。
比如:
我:我要使用 echarts 绘制一些图表,但是不知道相关代码配置怎么写,
我需要你按照我接下来的要求给出代码。
ChatGPT:xxx
我:我想绘制一张横向的柱形图,比如柱形图第一行
坐标为华北,数据为20;第二行 坐标为 西北,数据为30 ;
代码应该怎么写?
ChatGPT:xxx
我:我不想要横坐标。
ChatGPT:xxx
最终生成:
总之就是这样,逐渐细化需求,直到完成我们的要求为止。
具体示例
这里可以先试用 tailwindcss 进行初始布局搭建。
tailwindcss 结合框架使用跟着文档就就可以。
基本布局
下面均使用 mock 数据。
index
function Index(props) {return (<divstyle={{backgroundImage: `url(${bgImage})`,backgroundSize: 'cover',backgroundRepeat: 'no-repeat',width: '100%',height: '94vh',color: 'white',display: 'flex',overflow: 'hidden',padding: '5px',}}>{/*左*/}<div className="flex-1 mr-2 bg-opacity-50 bg-slate-800 p-3 flex flex-col">{/* 横向柱状图*/}<HorizontalBar className="h-1/3 box-border pb-4" />{/* 雷达图*/}<RadarBar className="h-1/3 box-border pb-4" />{/* 关系图*/}<Relation className="h-1/3" /></div>{/*中*/}<div className="w-1/2 mr-2 flex flex-col">{/* 数据总览图*/}<TotalData classNmae="bg-opacity-50 bg-slate-800 p-3 " />{/* 地图可视化*/}<MapChart classNmae="bg-opacity-50 bg-slate-800 p-3 mt-2 flex-1" /></div>{/*右*/}<div className="flex-1 bg-opacity-50 bg-slate-800 p-3 flex flex-col">{/* 竖向柱状图*/}<VerticalBar className="h-1/3 box-border pb-4" />{/* 环形图*/}<RingBar className="h-1/3 box-border pb-4" />{/* 文档云图*/}<WordCloud className="h-1/3 " /></div></div>);
}
HorizontalBar
import * as echarts from 'echarts';
import { useEffect, useRef } from 'react';function HorizontalBar(props) {const data = {regions: [{ id: 1, name: '华北', value: 63 },{ id: 2, name: '华南', value: 86 },{ id: 3, name: '华东', value: 85 },{ id: 4, name: '西南', value: 63 },{ id: 5, name: '西北', value: 54 },{ id: 6, name: '东北', value: 79 },],};// 1. 初始化 echarts 实例let myChart = null;const target = useRef(null);useEffect(() => {myChart = echarts.init(target.current);renderChart();}, []);// 2. 构建 options 配置对象const renderChart = () => {const options = {// x 轴展示数据xAxis: {// 不显示 x 轴show: false,// x 轴类型为数据进行展示type: 'value',// 设置 x 轴最大值max: function (value) {// 将 x 轴个数据中的的最大值 * 1.2 作为 x 轴的最大值return parseInt(value.max * 1.2);},},// y 轴展示数据yAxis: {// y 轴为类型数据展示type: 'category',// data 为所需展示的数据data: data.regions.map((item) => item.name), // 映射数据// 反向展示数据 默认情况从下到上展示数据inverse: true,// 不展示轴线axisLine: {show: false,},// 不展示刻度axisTick: {show: false,},axisLabel: {color: '#9eb1c8',},},// 图表位置 上下左右grid: {top: 0,right: 0,bottom: 0,left: 0,// 包含标签containLabel: true,},// 核心配置series: [{// 柱形图type: 'bar',// 展示数据data: data.regions.map((item) => ({name: item.name,value: item.value,})),showBackground: true,backgroundStyle: {color: 'rgba(180,180,180,0.2)',},// x 数据项样式itemStyle: {color: '#479AD3',barBorderRadius: 5,shadowColor: 'rgba(0,0,0,0.3)',// 阴影模糊shadowBlur: 5,},barWidth: 12,// x 上的字体标签label: {show: true,position: 'right',textStyle: {color: '#fff',},},},],};// 3. 根据数据构建 options 配置对象 myCharts.setOption(options)myChart.setOption(options);};return (<div className={props.className}><div>学生来源信息</div><div ref={target} className="w-full h-full"></div></div>);
}export default HorizontalBar;
MapChart
import mapJson from '@/assets/screen/MapData/china.json';
import * as echarts from 'echarts';
import { useEffect, useRef } from 'react';function MapChart(props) {const data = {mapData: {categoryData: {2020: [{ name: '北京', value: 42 },{ name: '天津', value: 24 },{ name: '上海', value: 53 },{ name: '重庆', value: 64 },{ name: '河北', value: 87 },{ name: '河南', value: 52 },{ name: '云南', value: 14 },{ name: '辽宁', value: 35 },{ name: '黑龙江', value: 85 },{ name: '湖南', value: 95 },{ name: '安徽', value: 41 },{ name: '山东', value: 45 },{ name: '新疆', value: 56 },{ name: '江苏', value: 43 },{ name: '浙江', value: 56 },{ name: '江西', value: 63 },{ name: '湖北', value: 41 },{ name: '广西', value: 23 },{ name: '甘肃', value: 56 },{ name: '山西', value: 62 },{ name: '内蒙古', value: 64 },{ name: '陕西', value: 54 },{ name: '吉林', value: 34 },{ name: '福建', value: 16 },{ name: '贵州', value: 71 },{ name: '广东', value: 32 },{ name: '青海', value: 56 },{ name: '西藏', value: 52 },{ name: '四川', value: 63 },{ name: '宁夏', value: 74 },{ name: '海南', value: 51 },],2021: [{ name: '北京', value: 76 },{ name: '天津', value: 54 },{ name: '上海', value: 23 },{ name: '重庆', value: 64 },{ name: '河北', value: 54 },{ name: '河南', value: 52 },{ name: '云南', value: 34 },{ name: '辽宁', value: 35 },{ name: '黑龙江', value: 65 },{ name: '湖南', value: 95 },{ name: '安徽', value: 34 },{ name: '山东', value: 34 },{ name: '新疆', value: 56 },{ name: '江苏', value: 76 },{ name: '浙江', value: 23 },{ name: '江西', value: 65 },{ name: '湖北', value: 41 },{ name: '广西', value: 34 },{ name: '甘肃', value: 43 },{ name: '山西', value: 65 },{ name: '内蒙古', value: 64 },{ name: '陕西', value: 54 },{ name: '吉林', value: 98 },{ name: '福建', value: 76 },{ name: '贵州', value: 71 },{ name: '广东', value: 65 },{ name: '青海', value: 56 },{ name: '西藏', value: 43 },{ name: '四川', value: 63 },{ name: '宁夏', value: 54 },{ name: '海南', value: 51 },],2022: [{ name: '北京', value: 23 },{ name: '天津', value: 24 },{ name: '上海', value: 43 },{ name: '重庆', value: 64 },{ name: '河北', value: 65 },{ name: '河南', value: 52 },{ name: '云南', value: 14 },{ name: '辽宁', value: 35 },{ name: '黑龙江', value: 98 },{ name: '湖南', value: 95 },{ name: '安徽', value: 65 },{ name: '山东', value: 45 },{ name: '新疆', value: 56 },{ name: '江苏', value: 87 },{ name: '浙江', value: 65 },{ name: '江西', value: 63 },{ name: '湖北', value: 54 },{ name: '广西', value: 45 },{ name: '甘肃', value: 56 },{ name: '山西', value: 62 },{ name: '内蒙古', value: 64 },{ name: '陕西', value: 54 },{ name: '吉林', value: 23 },{ name: '福建', value: 16 },{ name: '贵州', value: 54 },{ name: '广东', value: 32 },{ name: '青海', value: 21 },{ name: '西藏', value: 52 },{ name: '四川', value: 43 },{ name: '宁夏', value: 32 },{ name: '海南', value: 51 },],2023: [{ name: '北京', value: 65 },{ name: '天津', value: 54 },{ name: '上海', value: 53 },{ name: '重庆', value: 64 },{ name: '河北', value: 23 },{ name: '河南', value: 52 },{ name: '云南', value: 43 },{ name: '辽宁', value: 35 },{ name: '黑龙江', value: 85 },{ name: '湖南', value: 95 },{ name: '安徽', value: 34 },{ name: '山东', value: 45 },{ name: '新疆', value: 56 },{ name: '江苏', value: 42 },{ name: '浙江', value: 56 },{ name: '江西', value: 63 },{ name: '湖北', value: 41 },{ name: '广西', value: 23 },{ name: '甘肃', value: 23 },{ name: '山西', value: 62 },{ name: '内蒙古', value: 64 },{ name: '陕西', value: 54 },{ name: '吉林', value: 34 },{ name: '福建', value: 43 },{ name: '贵州', value: 65 },{ name: '广东', value: 32 },{ name: '青海', value: 56 },{ name: '西藏', value: 52 },{ name: '四川', value: 76 },{ name: '宁夏', value: 43 },{ name: '海南', value: 51 },],2024: [{ name: '北京', value: 31 },{ name: '天津', value: 54 },{ name: '上海', value: 53 },{ name: '重庆', value: 64 },{ name: '河北', value: 33 },{ name: '河南', value: 52 },{ name: '云南', value: 54 },{ name: '辽宁', value: 42 },{ name: '黑龙江', value: 85 },{ name: '湖南', value: 95 },{ name: '安徽', value: 41 },{ name: '山东', value: 45 },{ name: '新疆', value: 56 },{ name: '江苏', value: 53 },{ name: '浙江', value: 56 },{ name: '江西', value: 43 },{ name: '湖北', value: 64 },{ name: '广西', value: 23 },{ name: '甘肃', value: 56 },{ name: '山西', value: 65 },{ name: '内蒙古', value: 64 },{ name: '陕西', value: 54 },{ name: '吉林', value: 34 },{ name: '福建', value: 54 },{ name: '贵州', value: 71 },{ name: '广东', value: 13 },{ name: '青海', value: 56 },{ name: '西藏', value: 52 },{ name: '四川', value: 23 },{ name: '宁夏', value: 74 },{ name: '海南', value: 51 },],},colors: ['#1DE9B6','#F46E36','#04B9FF','#5DBd32','#FFC809','#FB05D5','#BDA29A','#6E7074','#546570','#C4CCD3',],topData: {2020: [{name: '天津',value: [117.4219, 39.4189, 84.1],},{name: '河北',value: [114.4995, 38.1006, 85.8],},{name: '河南',value: [113.4668, 34.6234, 83.6],},{name: '北京',value: [116.4551, 40.2539, 83.2],},{name: '山东',value: [117.1582, 36.8701, 82.5],},{name: '安徽',value: [117.29, 32.0581, 81.7],},{name: '湖北',value: [114.3896, 30.6628, 81.4],},{name: '江苏',value: [118.8062, 31.9208, 81.1],},{name: '新疆',value: [87.9236, 43.5883, 80.4],},{name: '湖南',value: [113.0823, 28.2568, 80.1],},],2021: [{name: '天津',value: [117.4219, 39.4189, 84.1],},{name: '河北',value: [114.4995, 38.1006, 85.8],},{name: '河南',value: [113.4668, 34.6234, 83.6],},{name: '北京',value: [116.4551, 40.2539, 83.2],},{name: '山东',value: [117.1582, 36.8701, 82.5],},{name: '安徽',value: [117.29, 32.0581, 81.7],},{name: '湖北',value: [114.3896, 30.6628, 81.4],},{name: '江苏',value: [118.8062, 31.9208, 81.1],},{name: '新疆',value: [87.9236, 43.5883, 80.4],},{name: '湖南',value: [113.0823, 28.2568, 80.1],},],2022: [{name: '天津',value: [117.4219, 39.4189, 84.1],},{name: '河北',value: [114.4995, 38.1006, 85.8],},{name: '河南',value: [113.4668, 34.6234, 83.6],},{name: '北京',value: [116.4551, 40.2539, 83.2],},{name: '山东',value: [117.1582, 36.8701, 82.5],},{name: '安徽',value: [117.29, 32.0581, 81.7],},{name: '湖北',value: [114.3896, 30.6628, 81.4],},{name: '江苏',value: [118.8062, 31.9208, 81.1],},{name: '新疆',value: [87.9236, 43.5883, 80.4],},{name: '湖南',value: [113.0823, 28.2568, 80.1],},],2023: [{name: '天津',value: [117.4219, 39.4189, 84.1],},{name: '河北',value: [114.4995, 38.1006, 85.8],},{name: '河南',value: [113.4668, 34.6234, 83.6],},{name: '北京',value: [116.4551, 40.2539, 83.2],},{name: '山东',value: [117.1582, 36.8701, 82.5],},{name: '安徽',value: [117.29, 32.0581, 81.7],},{name: '湖北',value: [114.3896, 30.6628, 81.4],},{name: '江苏',value: [118.8062, 31.9208, 81.1],},{name: '新疆',value: [87.9236, 43.5883, 80.4],},{name: '湖南',value: [113.0823, 28.2568, 80.1],},],2024: [{name: '天津',value: [117.4219, 39.4189, 84.1],},{name: '河北',value: [114.4995, 38.1006, 85.8],},{name: '河南',value: [113.4668, 34.6234, 83.6],},{name: '北京',value: [116.4551, 40.2539, 83.2],},{name: '山东',value: [117.1582, 36.8701, 82.5],},{name: '安徽',value: [117.29, 32.0581, 81.7],},{name: '湖北',value: [114.3896, 30.6628, 81.4],},{name: '江苏',value: [118.8062, 31.9208, 81.1],},{name: '新疆',value: [87.9236, 43.5883, 80.4],},{name: '湖南',value: [113.0823, 28.2568, 80.1],},],},voltageLevel: ['2020', '2021', '2022', '2023', '2024'],},};const target = useRef(null);let myChart = null;useEffect(() => {myChart = echarts.init(target.current);renderChart();}, []);const renderChart = () => {// echarts 渲染echarts.registerMap('china', mapJson);let options = {// 时间线,提供了在多个 ECharts option 间进行切换timeline: {// 数据data: data.mapData.voltageLevel,// 类目轴axisType: 'category',// 自动切换autoPlay: true,// 间隔时间playInterval: 3000,// 位置left: '10%',right: '10%',bottom: '0%',width: '80%',// 轴的文本标签label: {// 默认状态normal: {textStyle: {color: '#ddd',},},// 高亮状态emphasis: {textStyle: {color: '#fff',},},},// 文字大小symbolSize: 10,// 线的样式lineStyle: {color: '#555',},// 选中点的样式checkpointStyle: {borderColor: '#888',borderWidth: 2,},// 控件样式controlStyle: {// 上一步按钮showNextBtn: true,// 下一步按钮showPrevBtn: true,// 默认样式normal: {color: '#666',borderColor: '#666',},// 高亮样式emphasis: {color: '#aaa',borderColor: '#aaa',},},},// 柱形图右侧展示baseOption: {grid: {right: '2%',top: '15%',bottom: '10%',width: '20%',},// 中国地图geo: {// 展示show: true,// 中国地图map: 'china',// 开启缩放roam: true,// 初始缩放zoom: 0.8,// 中心点center: [113.83531246, 34.0267395887],// 默认状态的省份样式itemStyle: {normal: {// 边框色值borderColor: 'rgba(147, 235, 248, 1)',// 边框宽度borderWidth: 1,// 区域颜色areaColor: {// 经向色值type: 'radial',x: 0.5,y: 0.5,r: 0.5,colorStops: [// 0% 处的颜色{offset: 0,color: 'rgba(147, 235, 248, 0)',},// 100% 处的颜色{offset: 1,color: 'rgba(147, 235, 248, .2)',},],// 缺省为 falseglobalCoord: false,},},// 鼠标移入的色值emphasis: {areaColor: '#389BB7',borderWidth: 0,},},},},// 绑定时间轴的多个图表options: [],};// 为每一年度的图表添加数据data.mapData.voltageLevel.forEach((item, index) => {options.options.push({// 背景色backgroundColor: '#142037',title: [// 主标题,对应地图{text: '2020-2024 年度使用人数统计',left: '0%',top: '0',textStyle: {color: '#ccc',fontSize: 30,},},// 副标题,对应柱形图{id: 'statistic',text: item + '年数据统计情况',right: '0%',top: '4%',textStyle: {color: '#ccc',fontSize: 20,},},],// X 轴配置xAxis: {// 数据轴type: 'value',// 脱离 0 值比例scale: true,// 位置position: 'top',// 不显示分割线splitLine: {show: false,},// 不显示轴线axisLine: {show: false,},// 不显示刻度尺axisTick: {show: false,},// 类别文字axisLabel: {margin: 2,textStyle: {color: '#aaa',},},},// Y 轴yAxis: {// 选项轴type: 'category',// 轴线axisLine: {show: true,lineStyle: {color: '#ddd',},},// 轴刻度axisTick: {show: false,lineStyle: {color: '#ddd',},},// 轴标签axisLabel: {interval: 0,textStyle: {color: '#ddd',},},// 根据年份,获取对应数据data: data.mapData.categoryData[item].map((item) => item.name),},// 核心配置series: [// 柱形图{zlevel: 1.5,// 柱形图type: 'bar',// 每个柱子的色值itemStyle: {normal: {color: data.mapData.colors[index],},},// 根据年份,获取对应数据data: data.mapData.categoryData[item].map((item) => item.value),},// 散点图{// 散点(气泡)图type: 'effectScatter',// 使用地理坐标系coordinateSystem: 'geo',// 数据data: data.mapData.topData[item],// 标记大小symbolSize: function (val) {return val[2] / 4;},// 绘制完成后显示特效showEffectOn: 'render',// 展示涟漪特效rippleEffect: {brushType: 'stroke',},// 文字label: {normal: {formatter: '{b}',position: 'right',show: true,},},// 每一项的配置itemStyle: {normal: {color: data.mapData.colors[index],// 阴影配置shadowBlur: 5,shadowColor: data.mapData.colors[index],},},zlevel: 1,},],});});myChart.setOption(options);};return <div ref={target} className={props.classNmae}></div>;
}export default MapChart;
RadarBar
import * as echarts from 'echarts';
import { useEffect, useRef } from 'react';function RadarBar(props) {const data = {regions: [{ id: 1, name: '华北', value: 63 },{ id: 2, name: '华南', value: 86 },{ id: 3, name: '华东', value: 85 },{ id: 4, name: '西南', value: 63 },{ id: 5, name: '西北', value: 54 },{ id: 6, name: '东北', value: 79 },],};const target = useRef(null);let myChart = null;useEffect(() => {myChart = echarts.init(target.current);renderChart();}, []);const renderChart = () => {const options = {// 雷达图的坐标系位置radar: {name: {textStyle: {color: '#05D5FF',fontSize: 14,},},shape: 'polygon', // 雷达图绘制类型,支持 'polygon' 和 'circle'center: ['50%', '50%'],radius: '80%', // 雷达图半径startAngle: 120,// 轴线axisLine: {lineStyle: {color: 'rgba(5,213,255,.8)',},},// 分割线(网格线)splitLine: {show: true,lineStyle: {width: 1,color: 'rgba(5,213,255,.8)', // 分割线颜色},},// 指示器(文字指示)indicator: data.regions.map((item) => {return {name: item.name,max: 100,};}),splitArea: {show: false,},},// 坐标极点polar: {center: ['50%', '50%'],radius: '0%',},// 坐标角度angleAxis: {min: 0,// 分割间隔interval: 5,clockwise: false, // 刻度增长是否按照顺时针 默认顺时针},// 径向轴radiusAxis: {min: 0,interval: 20,splitLine: {show: true,},},// 核心配置 只有一个对象直接可以写对象 多个对象使用数组包裹series: {type: 'radar',symbol: 'circle', // 标记图形类型symbolSize: 10, // 标记拐角大小itemStyle: {normal: {color: '#05D5FF',},},// 填充 styleareaStyle: {normal: {color: '#05D5FF',opacity: 0.5,},},lineStyle: {width: 2,color: '#05D5FF',},label: {normal: {show: true,color: '#fff',},},data: [{value: data.regions.map((item) => item.value),},],},};myChart.setOption(options);};return (<div className={props.className}><div>监控云端方位报警风险</div><div ref={target} className="w-full h-full"></div></div>);
}export default RadarBar;
Relation
import * as echarts from 'echarts';
import { useEffect, useRef } from 'react';function Relation(props) {const data = {relations: [{id: 1,name: '软件工程II',source: '软件工程II',speed: 66,target: '软件工程I',value: [0, 300],},{id: 2,name: '软件概述',source: '软件工程I',speed: 78,target: '软件概述',value: [100, 300],},{id: 3,name: '软件内容',source: '软件工程I',speed: 92,target: '软件内容',value: [100, 100],},{id: 4,name: '软件导论',source: '软件导论',speed: 33,target: '软件工程I',value: [0, 100],},{ id: 0, name: '软件工程I', speed: 117, value: [50, 200] },],};const target = useRef(null);let myChart = null;useEffect(() => {myChart = echarts.init(target.current);renderChart();}, []);const renderChart = () => {const options = {// X 轴不需要展示xAxis: {show: false,type: 'value',},// Y 轴不需要展示yAxis: {show: false,type: 'value',},// 核心数据配置series: [{// 用于展现节点以及节点之间的关系数据type: 'graph',// 不采用任何布局layout: 'none',// 使用二维的直角坐标系coordinateSystem: 'cartesian2d',// 节点标记的大小symbolSize: 26,// z-indexz: 3,// 边界标签(线条文字)edgeLabel: {normal: {show: true,color: '#fff',textStyle: {fontSize: 14,},formatter: function (params) {let txt = '';if (params.data.speed !== undefined) {txt = params.data.speed;}return txt;},},},// 圆饼下文字label: {normal: {show: true,position: 'bottom',color: '#5e5e5e',},},// 边两端的标记类型edgeSymbol: ['none', 'arrow'],// 边两端的标记大小edgeSymbolSize: 8,// 圆数据data: data.relations.map((item) => {// id 为 0 ,表示数据中心,数据中心单独设置if (item.id !== 0) {return {name: item.name,category: 0,active: true,speed: `${item.speed}kb/s`,// 位置value: item.value,};} else {return {name: item.name,// 位置value: item.value,// 数据中心圆的大小symbolSize: 100,// 圆的样式itemStyle: {normal: {// 渐变色color: {colorStops: [{ offset: 0, color: '#157eff' },{ offset: 1, color: '#35c2ff' },],},},},// 字体label: { normal: { fontSize: '14' } },};}}),// 线links: data.relations.map((item, index) => ({// 方向source: item.source,target: item.target,// 线上的文字speed: `${item.speed}%`,// 线的样式lineStyle: { normal: { color: '#12b5d0', curveness: 0.2 } },// 文字位置label: {show: true,position: 'middle',offset: [10, 0],},})),},{// 用于带有起点和终点信息的线数据的绘制type: 'lines',// 使用二维的直角坐标系coordinateSystem: 'cartesian2d',// z-indexz: 1,// 线特效的配置effect: {show: true,smooth: false,trailLength: 0,symbol: 'arrow',color: 'rgba(55,155,255,0.5)',symbolSize: 12,},// 线的样式lineStyle: {normal: {curveness: 0.2,},},// 线的数据级,前后线需要重合。数据固定data: [[{ coord: [0, 300] }, { coord: [50, 200] }],[{ coord: [0, 100] }, { coord: [50, 200] }],[{ coord: [50, 200] }, { coord: [100, 100] }],[{ coord: [50, 200] }, { coord: [100, 300] }],],},],};myChart.setOption(options);};return (<div className={props.className}><div>知识溯源概念模型</div><div ref={target} className="w-full h-full"></div></div>);
}export default Relation;
RingBar
import * as echarts from 'echarts';
import { useEffect, useRef } from 'react';function RingBar(props) {const data = {courses: [{ id: 1, name: '软件工程概论', value: 1363 },{ id: 2, name: 'Java程序设计', value: 1086 },{ id: 3, name: '计算机网络', value: 666 },{ id: 4, name: '操作系统', value: 999 },{ id: 5, name: '数据结构与算法', value: 765 },],};const target = useRef(null);let myChart = null;useEffect(() => {myChart = echarts.init(target.current);renderChart();}, []);/*** 双环形图绘制原理:* 1. 环形图通过饼图绘制。内外边距的距离减小,即为环形。环形中心点需要不断改变,否则会重叠* 2. 环形图绘制分为 上层和底层 两部分。上层作为绘制进度,底层作为背景图* 3. 依据 getSeriesData 生成对应的 上层和底层 series 数据,进行渲染*/const getSeriesData = () => {const series = [];data.courses.forEach((item, index) => {// 上层环形绘制series.push({name: item.name,// 使用饼图绘制,减少饼图宽度即为环形图type: 'pie',// 逆时针排布clockWise: false,// 不展示鼠标移入动画hoverAnimation: false,// 半径位置,需要依次递减,否则会重复在一处进行展示radius: [73 - index * 15 + '%', 68 - index * 15 + '%'],// 中心点center: ['55%', '55%'],// 不展示 labellabel: { show: false },// 数据配置data: [// 设置数据与名称{ value: item.value, name: item.name },// 最大数据,展示比例{value: 1000,name: '',itemStyle: { color: 'rgba(0,0,0,0)', borderWidth: 0 },tooltip: { show: false },hoverAnimation: false,},],});// 底层图series.push({name: item.name,type: 'pie',// 图形不响应事件silent: true,// z-index: 置于底层z: 1,// 逆时针排布clockWise: false,// 不展示鼠标移入动画hoverAnimation: false,// 半径位置,需要依次递减,否则会重复在一处进行展示radius: [73 - index * 15 + '%', 68 - index * 15 + '%'],// 中心点center: ['55%', '55%'],// 不展示 labellabel: { show: false },// 数据data: [// 绘制底线 75%{value: 7.5,itemStyle: { color: 'rgb(3, 31, 62)', borderWidth: 0 },tooltip: { show: false },hoverAnimation: false,},// 绘制底线 25% 透明区域{value: 2.5,name: '',itemStyle: { color: 'rgba(0,0,0,0)', borderWidth: 0 },tooltip: { show: false },hoverAnimation: false,},],});});return series;};const renderChart = () => {const options = {// 图例配置legend: {show: true,// 图例色块icon: 'circle',// 位置top: '14%',left: '60%',// 图例展示数据data: data.courses.map((item) => item.name),// 总宽度(一列)width: -5,// 每个色块的宽itemWidth: 10,// 每个色块的高度itemHeight: 10,// item 间距itemGap: 6,// 展示内容formatter: function (name) {return '{title|' + name + '}';},// 字体配置textStyle: {rich: {title: {fontSize: 12,lineHeight: 5,color: 'rgba(255,255,255,0.8)',},},},},// 提示层(鼠标移上去的提示信息)tooltip: {show: true,trigger: 'item',formatter: '{a}<br>{b}:{c}({d}%)',},// Y 轴展示选项yAxis: [{type: 'category',// 反向展示inverse: true,// 不展示轴线axisLine: {show: false,},// 不展示刻度axisTick: {show: false,},},],// X 轴不展示(没有 x 轴)xAxis: [{show: false,},],// 每两个标记一条线 相当于 10 个饼图series: getSeriesData(),};myChart.setOption(options);};return (<div className={props.className}><div>课程掌握熟练度处理</div><div ref={target} className="w-full h-full"></div></div>);
}export default RingBar;
TotalData
// import * as echarts from 'echarts';
import '@/assets/screen/fonts/css/style.css';
import { CountUp } from 'countup.js';
import { useEffect, useRef } from 'react';function TotalData(props) {const data = {totalData: {db: '65446',hb: '87788',hd: '76456',total: '6784739',xb: '75753',xn: '74564',zn: '42135',},};const totalCountTarget = useRef(null);const city1 = useRef(null);const city2 = useRef(null);const city3 = useRef(null);const city4 = useRef(null);const city5 = useRef(null);const city6 = useRef(null);useEffect(() => {new CountUp(totalCountTarget.current, data.totalData.total).start();new CountUp(city1.current, data.totalData.hb).start();new CountUp(city2.current, data.totalData.db).start();new CountUp(city3.current, data.totalData.hd).start();new CountUp(city4.current, data.totalData.zn).start();new CountUp(city5.current, data.totalData.xn).start();new CountUp(city6.current, data.totalData.xb).start();}, []);return (<div className={props.className}><div className="p-6"><div className="text-slate-300 text-center">数据总量:<spanref={totalCountTarget}className="text-7xl ml-2 mr-2 font-bold font-[Electronic] text-gradient">679,473,929</span>条记录</div><div className="mt-3 flex flex-wrap"><div className="w-1/3 text-center text-slate-400 text-sm">抬头:<spanref={city1}className="text-[#5DC5EF] text-3xl font-[Electronic]">8,778,988</span></div><div className="w-1/3 text-center text-slate-400 text-sm">睡觉:<spanref={city2}className="text-[#5DC5EF] text-3xl font-[Electronic]">8,778,988</span></div><div className="w-1/3 text-center text-slate-400 text-sm">举手:<spanref={city3}className="text-[#5DC5EF] text-3xl font-[Electronic]">8,778,988</span></div><div className="w-1/3 text-center text-slate-400 text-sm">低头:<spanref={city4}className="text-[#5DC5EF] text-3xl font-[Electronic]">8,778,988</span></div><div className="w-1/3 text-center text-slate-400 text-sm">站立:<spanref={city5}className="text-[#5DC5EF] text-3xl font-[Electronic]">8,778,988</span></div><div className="w-1/3 text-center text-slate-400 text-sm">坐直:<spanref={city6}className="text-[#5DC5EF] text-3xl font-[Electronic]">8,778,988</span></div></div></div></div>);
}export default TotalData;
VerticalBar
import * as echarts from 'echarts';
import { useEffect, useRef } from 'react';function VerticalBar(props) {const data = {servers: [{ id: 1, name: '很好', value: 33 },{ id: 2, name: '较好', value: 20 },{ id: 3, name: '略好', value: 13 },{ id: 4, name: '略差', value: 17 },{ id: 5, name: '较差', value: 14 },{ id: 6, name: '很差', value: 3 },],};const target = useRef(null);let myChart = null;useEffect(() => {myChart = echarts.init(target.current);renderChart();}, []);const renderChart = () => {const options = {// X 轴展示选项xAxis: {type: 'category',// 根据根据服务端数据筛选data: data.servers.map((item) => item.name),// 文字色值axisLabel: {color: '#9EB1C8',},},// Y 轴展示数据yAxis: {// 数据展示type: 'value',// 不显示轴show: false,// 最大值(防止触顶)max: function (value) {// 取整return parseInt(value.max * 1.2);},},// echarts 网格绘制的位置,对应 上、右、下、左grid: {top: 16,right: 0,bottom: 26,left: -26,// 计算边距时,包含标签containLabel: true,},// 柱形图核心配置series: [{// 柱形图type: 'bar',// 数据筛选data: data.servers.map((item) => ({name: item.name,value: item.value,})),// 每个轴的样式itemStyle: {color: '#479AD3', // 设置柱子的颜色barBorderRadius: 5, // 设置柱子的圆角shadowColor: 'rgba(0, 0, 0, 0.3)', // 设置柱子的阴影颜色shadowBlur: 5, // 设置柱子的阴影模糊大小},// 柱子宽度barWidth: 12,// 文本label: {show: true,// 设置标签位置为右侧position: 'top',textStyle: {// 设置标签文本颜色color: '#fff',},// 格式化展示数值formatter: '{c}%',},},],};myChart.setOption(options);};return (<div className={props.className}><div>听课抬头率分布占比</div><div ref={target} className="w-full h-full"></div></div>);
}export default VerticalBar;
WordCloud
import * as echarts from 'echarts';
import 'echarts-wordcloud';
import { useEffect, useRef } from 'react';function WordCloud(props) {const data = {wordData: [{ value: 24, name: '链表' },{ value: 18, name: '队列' },{ value: 16, name: '树' },{ value: 12, name: 'Java' },{ value: 10, name: 'JavaScript' },{ value: 8, name: 'C++' },{ value: 6, name: '设计模式' },{ value: 45, name: '算法' },{ value: 4, name: '数据结构' },{ value: 2, name: '操作系统' },{ value: 1, name: '计算机网络' },{ value: 43, name: '前端' },{ value: 3, name: '后端' },{ value: 5, name: '数据库' },{ value: 7, name: 'HTML' },{ value: 9, name: 'CSS' },{ value: 11, name: 'Vue' },{ value: 13, name: 'React' },{ value: 15, name: 'Webpack' },{ value: 17, name: 'Node.js' },],};const target = useRef(null);let myChart = null;useEffect(() => {myChart = echarts.init(target.current);renderChart();}, []);/*** 生成随机色值*/const randomRGB = () => {const r = Math.floor(Math.random() * 255);const g = Math.floor(Math.random() * 255);const b = Math.floor(Math.random() * 255);return `rgb(${r}, ${g}, ${b})`;};const renderChart = () => {const options = {series: [{// 类型type: 'wordCloud',// 形状shape: 'circle',width: '100%',height: '100%',// 数据映射文本的大小范围sizeRange: [12, 52],// 文字旋转范围rotationRange: [0, 0],// 单词之间的间距gridSize: 5,// 渲染动画layoutAnimation: true,// 字体textStyle: {// 随机色值color: randomRGB,},// 高亮字体emphasis: {textStyle: {fontWeight: 'bold',color: '#000',},},// 数据data: data.wordData,},],};myChart.setOption(options);};return (<div className={props.className}><div>关键词条</div><div ref={target} className="w-full h-full"></div></div>);
}export default WordCloud;
相关文章:
ECharts 快速使用
最终效果 使用介绍 echarts图表的绘制,大体分为三步: 根据 DOM实例,通过 echarts.init方法,生成 echarts实例构建 options配置对象,整个echarts的样式,皆有该对象决定最后通过实例.setOption方法…...
进程--消息队列和共享内存
目录 消息队列 创建消息队列 删除消息队列 发送消息和接收 消息队列 消息队列就是一个消息的列表,进程可以在消息队列中添加消息和的读取消息 消息队列具有FIFO的特性,具有无名管道与有名管道各自的优势,可以支持任意两个进程的进程间通讯…...
useCallback()
官网直达:https://zh-hans.react.dev/reference/react/useCallback 点击按钮,子组件会重新渲染 import { memo, useState, useCallback } from react;const Child (props) > {console.log(我是子组件!我在渲染呢!࿰…...
Python面试题精选及解析--第二篇
在Python的面试中,除了基础语法和常用库的知识外,面试官往往还会通过一系列的问题来考察应聘者的逻辑思维、问题解决能力以及项目经验。以下是一些精心挑选的Python面试题及其详细答案,旨在帮助求职者更好地准备面试。 面试题一:…...
Linux操作常用问题
目录 Ubuntu操作问题vi编辑方向键键盘乱码回退键不能使用的问题解决问题的方法 Ubuntu操作问题 vi编辑方向键键盘乱码回退键不能使用的问题 编辑/etc/systemd/resolved.conf文件来修改DNS,结果编辑时键盘乱码,按下方向键会出现ABCD,且回退键…...
汽车发动机系统(ems)详细解析
汽车发动机系统EMS,即Engine-Management-System(发动机管理系统),是现代汽车电子控制技术的重要组成部分。以下是对汽车发动机系统EMS的详细解析,内容将涵盖其定义、工作原理、主要组成、功能特点、技术发展以及市场应…...
对比学习训练是如何进行的
对比学习(Contrastive Learning)是一种自监督学习的方法,旨在通过拉近相似样本的表示、拉远不相似样本的表示来学习特征表示。在训练过程中,模型并不依赖标签,而是通过样本之间的相似性进行学习。以下是对比学习的基本…...
React 生命周期 - useEffect 介绍
在 React 中,useEffect 钩子可以被看作是函数组件中的一种副作用管理工具,它的行为可以模拟类组件中的不同生命周期方法。useEffect 的执行时机取决于其依赖项数组(第二个参数)的设置方式。 根据 useEffect 的使用方式,…...
OpenCV-指纹识别
文章目录 一、意义二、代码实现1.计算匹配点2.获取编号3.获取姓名4.主函数 三、总结 一、意义 使用OpenCV进行指纹识别是一个复杂且挑战性的任务,因为指纹识别通常需要高精度的特征提取和匹配算法。虽然OpenCV提供了多种图像处理和计算机视觉的工具,但直…...
IPD的核心思想
IPD是一套领先的、成熟的研发管理思想、模式和方法。它是根据大量成功的研发管理实践总结出来的,并被大量实践证明的高效的产品研发模式。 那么,按照IPD来开展产品研发与产品管理工作,应该基于哪些基本思想或原则?市场导向、客户…...
如何在算家云搭建MVSEP-MDX23(音频分离)
一、MVSEP-MDX23简介 模型GitHub网址:MVSEP-MDX23-music-separation-model/README.md 在 main ZFTurbo/MVSEP-MDX23-音乐分离模型 GitHub 上 在音视频领域,把已经发布的混音歌曲或者音频文件逆向分离一直是世界性的课题。音波混合的物理特性导致在没有…...
常用的Java安全框架
Spring Security: 就像Java安全领域的“瑞士军刀”,功能全面且强大。 支持认证、授权、加密、会话管理等安全功能。 与Spring框架无缝集成,使用起来特别方便。 社区活跃,文档丰富,遇到问题容易找到解决方案。 Apach…...
使用 PHP 的 strip_tags函数保护您的应用安全
在现代 web 开发中,处理用户输入是一项常见的任务。然而,用户输入的内容往往包含 HTML 或 PHP 标签,这可能会导致安全漏洞,如跨站脚本攻击(XSS)。为了解决这个问题,PHP 提供了一个非常有用的函数…...
您的计算机已被Lockbit3.0勒索病毒感染?恢复您的数据的方法在这里!
导言 在数字化时代,互联网已成为我们生活、工作和学习中不可或缺的一部分。然而,随着网络技术的飞速发展,网络安全威胁也日益严峻。其中,勒索病毒作为一种极具破坏性的网络攻击手段,正逐渐成为企业和个人面临的重大挑…...
经典sql题(十二)UDTF之Explode炸裂函数
1. EXPLODE: UDTF 函数 1.1 功能说明 EXPLODE 函数 是Hive 中的一种用户定义的表函数(UDTF),用于将数组或映射结构中的复杂的数据结构每个元素拆分为单独的行。这在处理复杂数据时非常有用,尤其是在需要将嵌套数据“打散”以便更…...
【AIGC】ChatGPT提示词解析:如何打造个人IP、CSDN爆款技术文案与高效教案设计
博客主页: [小ᶻZ࿆] 本文专栏: AIGC | ChatGPT 文章目录 💯前言💯打造个人IP爆款文案提示词使用方法 💯CSDN爆款技术文案提示词使用方法 💯高效教案设计提示词使用方法 💯小结 💯前言 在这…...
【Ubuntu】Ubuntu常用命令
文章目录 网卡路由常用命令:编辑文件echo 权限设置gcc编译器: 重启网络服务 sudo service network-manager restart 网卡 #查看网卡信息 ip a #区分光网卡电网卡 sudo lshw -class network -businfo ifconfig ifconfig eth1 192.168.1.12/24 #重启网卡…...
架构设计笔记-5-软件工程基础知识-2
知识要点 构件组装是将库中的构件经适当修改后相互连接,或者将它们与当前开发项目中的软件元素连接,最终构成新的目标软件。 构件组装技术大体可分为: 1. 基于功能的组装技术:基于功能的组装技术采用子程序调用和参数传递的方式将构件组装起来。它要求库中的构件以子程序…...
[网络]抓包工具介绍 tcpdump
一、tcpdump tcpdump是一款基于命令行的网络抓包工具,可以捕获并分析传输到和从网络接口流入和流出的数据包。 1.1 安装 tcpdump 通常已经预装在大多数 Linux 发行版中。如果没有安装,可以使用包管理器 进行安装。例如 Ubuntu,可以使用以下…...
基于STM32和FPGA的射频数据采集系统设计流程
一、项目概述 高速采集射频(RF)信号是一个关键的需求。本文旨在设计一种基于STM32和FPGA的射频数据采集系统,以实现对接收到的射频信号的高精度和高速度的处理。该系统适用于无线通信、信号分析、雷达系统等应用场景。 技术栈关键词&#x…...
自动变速箱系统(A/T)详细解析
自动变速箱系统(A/T),即Automatic Transmission,是一种能够在车辆行驶过程中自动完成换挡操作的传动系统。以下是对自动变速箱系统(A/T)的详细解析,内容涵盖其定义、工作原理、主要组成、类型、…...
【Kubernetes】常见面试题汇总(四十三)
目录 98. kube-apiserver 和 kube-scheduler 的作用是什么? 99.您对云控制器管理器了解多少? 特别说明: 题目 1-68 属于【Kubernetes】的常规概念题,即 “ 汇总(一)~(二十二)…...
OpenCL 学习(1)---- OpenCL 基本概念
目录 Overview异构并行计算OpenCL 架构平台模型执行模型OpenCL 上下文OpenCL 命令队列内核执行编程模型存储器模型存储器对象共享虚拟存储器 Overview OpenCL(Open Computing Language,开放计算语言) 最早由苹果公司提交草案,并于 AMD, IBM ,intel 和 n…...
自定义注解加 AOP 实现服务接口鉴权以及内部认证
注解 何谓注解? 在Java中,注解(Annotation)是一种特殊的语法,用符号开头,是 Java5 开始引入的新特性,可以看作是一种特殊的注释,主要用于修饰类、方法或者变量,提供某些信…...
《软件工程概论》作业一:新冠疫情下软件产品设计(小区电梯实体按钮的软件替代方案)
课程说明:《软件工程概论》为浙江科技学院2018级软件工程专业在大二下学期开设的必修课。课程使用《软件工程导论(第6版)》(张海藩等编著,清华大学出版社)作为教材。以《软件设计文档国家标准GBT8567-2006》…...
基于Ernie-Bot打造语音对话功能
大模型场景实战培训,提示词效果调优,大模型应用定制开发,点击咨询 咨询热线:400-920-8999转2 GPT-4的语音对话功能前段时间在网上火了一把,许多人被其强大的自然语言处理能力和流畅的语音交互所吸引。现在,…...
动手学深度学习(李沐)PyTorch 第 3 章 线性神经网络
3.1 线性回归 线性回归是对n维输入的加权,外加偏差 线性回归可以看作是单层神经网络 回归问题中最常用的损失函数是平方误差函数。 平方误差可以定义为以下公式: 常数1/2不会带来本质的差别,但这样在形式上稍微简单一些 (因为当…...
ROS理论与实践学习笔记——2 ROS通信机制之服务通信
服务通信也是ROS中一种极其常用的通信模式,服务通信是基于请求响应模式的,是一种应答机制。也即: 一个节点A向另一个节点B发送请求,B接收处理请求并产生响应结果返回给A,用于偶然的、对时时性有要求、有一定逻辑处理需求的数据传输…...
技术成神之路:设计模式(十八)适配器模式
介绍 适配器模式(Adapter Pattern)是一种结构型设计模式,它允许接口不兼容的类可以协同工作,通过将一个类的接口转换成客户端所期望的另一个接口,使得原本由于接口不兼容而不能一起工作的类可以一起工作。 1.定义 适配…...
图神经网络:处理复杂关系结构与图分类任务的强大工具
创作不易,您的打赏、关注、点赞、收藏和转发是我坚持下去的动力! 图神经网络(Graph Neural Network, GNN)是针对图数据的一类神经网络模型。图数据具有节点(节点代表实体)和边(边代表节点之间的…...
装潢设计软件免费/seo代码优化工具
一. 前言在使用实践中, fastjson其实确实是简便易用, 但是无奈会有一定的安全漏洞隐患, 为了安全起见, 避免作频繁的 fastjson版本升级, 因此考虑用安全性更佳的jackson来替代全线应用中的fastjson, 其中遇到的问题还相当多, 总结归纳下重点有如下几点:应用场景下时间日期的使用…...
wordpress加载本地字体/seo排名优化北京
这里是腾讯汽车官方汽车科技公众号点击上方“汽车AI科技”选择“置顶或星标公众号”最新汽车科技消息,第一时间送达腾讯汽车 图文/常岩这是一个最好的时代,我们欣喜于汽车产业前所未有的一次技术产业升级;这是一个最坏的时代,我们…...
网站开发设计工具/网站关键词排名分析
对于该教程而言,缺少了删除已存在的电影记录的功能。因此,我在这里给出删除功能的代码供大家参考学习。 另外,需要注意的是要为VS2008打上SP1服务包,不然就不能使用ADO.NET Entity Data Model功能了。附按本教程制作的MovieDataba…...
广西网络公司有几家/广西网站seo
/* 题意: 给若干字符串,添加最少的字符把它们变成回文 ,并输出回文。 记忆化搜索,如果s[i]s[j],dp[i][j]dfs(i1,j-1); 否则 dp[i][j]min(dp[i][j],dfs(i1,j),dfs(i,j-1); 最先开始也不造怎么输出,后来看了题解…...
网站域名被劫持/西安seo霸屏
到目前为止我们所接触过的角色都是可以接收消息的,而消息的类型也是五花八门,如String、元组、case类/自定义消息等。然而发送消息的行为在感觉上与我们日常编程工作中所使用的常规函数调用还是有很大区别的,为了弥合二者之间的鸿沟ÿ…...
网站访问量什么意思/最近新闻事件
请问唐氏筛查低风险人群,有必要做无创DNA吗?唐氏筛查低风险,有必要做无创DNA检查吗?这个问题问的好,如果单纯性的唐氏筛查低风险,那么根本没有必要再做无创DNA检查了。现实生活中还是存在很多唐氏筛查低风险…...