echarts 自定义图表参考
type: ‘custom’ https://echarts.apache.org/zh/option.html#series-custom.type
https://blog.csdn.net/WuLex/article/details/78828301
image.png

format

xAxis.axisLabel.formatter
https://echarts.apache.org/zh/option.html#xAxis.axisLabel.formatter

  1. {
  2. xAxis: {
  3. name: '时间',
  4. type: 'time',
  5. interval: 3600 * 1000, // 以一个小时递增
  6. // x轴零刻度对应的实际值,将data里最小时间的整点时间设为min,否则min会以data里面的min为开始进行整点递增
  7. min: '2009/6/1 1:00',
  8. axisLabel: {
  9. color: '#9da5b2',
  10. formatter: '{HH}:{mm}',
  11. }
  12. }
  13. }

options

  1. /**
  2. * Description: 用条形图的不同颜色,来表示不同时间区间段的状态
  3. * y轴用于展示各网口
  4. * x轴用于展示时间(分钟)
  5. * 以 ECS为例
  6. * 图中则表示了0~10分钟为正常,10~25分钟为繁忙,25~45分钟为故障,45~60分钟为离线
  7. */
  8. import moment from 'moment';
  9. import * as echarts from 'echarts/core';
  10. function getzf(num) {
  11. if (parseInt(num) < 10) { num = '0' + num; }
  12. return num;
  13. }
  14. // 各状态的颜色
  15. const color = ['#61a0a8', '#d48265', '#c23531'];
  16. // 状态
  17. const state = ['正常', '故障', '离线'];
  18. // 设备
  19. const deviceData = ['ECS', 'RDS', 'REDIS'];
  20. export function getOption({ length, theme}) {
  21. return {
  22. color,
  23. grid: {
  24. top: length === 1 ? 24 : 40,
  25. left: 24,
  26. right: 40,
  27. bottom: 32,
  28. containLabel: true,
  29. },
  30. xAxis: {
  31. name: '时间',
  32. type: 'time',
  33. interval: 3600 * 1000, // 以一个小时递增
  34. // x轴零刻度对应的实际值,将data里最小时间的整点时间设为min,否则min会以data里面的min为开始进行整点递增
  35. min:'2009/6/1 1:00',
  36. axisLabel: {
  37. color: '#9da5b2',
  38. formatter: (value) => { // value 时间戳
  39. console.log('value', value)
  40. return moment(value).format('HH:mm');
  41. },
  42. }
  43. },
  44. yAxis: {
  45. name: '设备',
  46. data: deviceData,
  47. },
  48. series: [
  49. // 用空bar来显示四个图例
  50. { name: state[0], type: 'bar', data: [] },
  51. { name: state[1], type: 'bar', data: [] },
  52. { name: state[2], type: 'bar', data: [] },
  53. {
  54. type: 'custom',
  55. // 自定义的图形元素渲染逻辑,通过 renderItem 函数实现的
  56. renderItem: (params, api) => {
  57. // api.value(0) 取出当前 dataItem 中第一个维度的数值
  58. const categoryIndex = api.value(0)
  59. // 用 api.coord(...) 将数值在当前坐标系中转换成为屏幕上的点的像素值
  60. const start = api.coord([api.value(1), categoryIndex])
  61. const end = api.coord([api.value(2), categoryIndex])
  62. const height = api.size([0, 1])[1];
  63. return {
  64. type: 'rect', // 图形元素是矩形。还可以是 'circle' 'sector' 'polygon'
  65. // 矩形的位置和大小
  66. shape: echarts.graphic.clipRectByRect(
  67. {
  68. x: start[0],
  69. y: start[1] - height / 2,
  70. width: end[0] - start[0],
  71. height: height,
  72. },
  73. {
  74. x: params.coordSys.x,
  75. y: params.coordSys.y,
  76. width: params.coordSys.width,
  77. height: params.coordSys.height,
  78. }
  79. ),
  80. style: api.style(),
  81. }
  82. },
  83. encode: {
  84. x: [1, 2], // data 中『维度1』和『维度2』对应到 X 轴
  85. y: 0, // data 中『维度0』对应到 Y 轴
  86. },
  87. data: [
  88. {
  89. itemStyle: { normal: { color: color[0] } },
  90. name: '正常',
  91. // 0 代表y轴的索引,1,2代表x轴数据开始和结束
  92. value: [0, '2009/6/1 1:28', '2009/6/1 5:00'],
  93. },
  94. {
  95. itemStyle: { normal: { color: color[1] } },
  96. name: '故障',
  97. value: [0, '2009/6/1 6:13', '2009/6/1 8:22']
  98. },
  99. // 第二个数据; 1 代表第二个数据
  100. {
  101. itemStyle: { normal: { color: color[0] } },
  102. name: '正常',
  103. value: [1, '2009/6/1 1:28', '2009/6/1 5:00'],
  104. },
  105. {
  106. itemStyle: { normal: { color: color[0] } },
  107. name: '正常',
  108. value: [1, '2009/6/1 6:13', '2009/6/1 8:22']
  109. },
  110. {
  111. itemStyle: { normal: { color: color[1] } },
  112. name: '故障',
  113. value: [1, '2009/6/1 12:47', '2009/6/1 14:52']
  114. },
  115. // 第三个数据; 2 代表第三个数据
  116. {
  117. itemStyle: { normal: { color: color[0] } },
  118. name: '正常',
  119. value: [2, '2009/6/1 1:28', '2009/6/1 5:00'],
  120. },
  121. {
  122. itemStyle: { normal: { color: color[2] } },
  123. name: '离线',
  124. value: [2, '2009/6/1 14:52', '2009/6/1 17:00']
  125. },
  126. ],
  127. },
  128. ],
  129. tooltip: {
  130. formatter: (params) => {
  131. const { name, value} = params;
  132. const [a,x, y] = value;
  133. return `${deviceData[a]}-${name}: ${x} ~ ${y}`;
  134. },
  135. },
  136. legend: {
  137. data: state,
  138. bottom: 8,
  139. selectedMode: false, // 图例设为不可点击
  140. textStyle: {
  141. color: theme === 'dark' ? '#fff' : '#333',
  142. },
  143. },
  144. };
  145. }

在线离线柱图

image.png

  1. import * as echarts from 'echarts/core';
  2. const state = ['在线', '离线'];
  3. const color = ['#41c669', '#ff6160']
  4. function onlineToOffline({ dataSource, theme, color = ['#41c669', '#ff6160'] }) {
  5. const _options = {
  6. color,
  7. xAxis: {
  8. min: 0, // x轴零刻度对应的实际值
  9. },
  10. yAxis: {
  11. // type: 'category',
  12. // boundaryGap: false,
  13. // data: dataSource.map(it => it.label), // ['REDIS', 'ECS']
  14. axisTick: {
  15. lineStyle: { color: '#c1c5ca41' },
  16. alignWithLabel: true,
  17. },
  18. splitLine: { show: false },
  19. axisLine: { lineStyle: { color: 'rgba(0,0,0,0)' } },
  20. axisLabel: { color: '#9da5b2', fontSize: 11, overflow: 'break' },
  21. },
  22. series: [
  23. // 用 空bar来显示图例
  24. { name: state[0], type: 'bar', data: [] },
  25. { name: state[1], type: 'bar', data: [] },
  26. {
  27. type: 'custom',
  28. renderItem: (params, api) => {
  29. const categoryIndex = api.value(0);
  30. const start = api.coord([api.value(1), categoryIndex]);
  31. const end = api.coord([api.value(2), categoryIndex]);
  32. const height = 24;
  33. return {
  34. type: 'rect',
  35. shape: echarts.graphic.clipRectByRect(
  36. {
  37. x: start[0],
  38. y: start[1] - height / 2,
  39. width: end[0] - start[0],
  40. height,
  41. },
  42. {
  43. x: params.coordSys.x,
  44. y: params.coordSys.y,
  45. width: params.coordSys.width,
  46. height: params.coordSys.height,
  47. }
  48. ),
  49. style: api.style(),
  50. };
  51. },
  52. encode: {
  53. x: [1, 2],
  54. y: 0,
  55. },
  56. data: [
  57. {
  58. itemStyle: { normal: { color: color[0] } },
  59. name: state[0],
  60. value: [0, 0, 45],
  61. },
  62. {
  63. itemStyle: { normal: { color: color[1] } },
  64. name: state[1], // 离线
  65. value: [0, 45, 50],
  66. },
  67. {
  68. itemStyle: { normal: { color: color[0] } },
  69. name: state[0],
  70. value: [0, 50, 60],
  71. },
  72. ],
  73. },
  74. ],
  75. tooltip: {
  76. trigger: 'axis',
  77. backgroundColor: 'rgba(50,50,50,.8)',
  78. textStyle: {
  79. fontSize: 12,
  80. color: '#ccc',
  81. },
  82. enterable: true,
  83. extraCssText: 'max-height: 300px; overflow: auto;',
  84. appendToBody: true,
  85. },
  86. legend: {
  87. data: state,
  88. icon: 'rect',
  89. top: -4,
  90. itemWidth: 12,
  91. itemHeight: 8,
  92. textStyle: {
  93. fontSize: 12,
  94. color: theme === 'dark' ? '#fff' : '#333',
  95. },
  96. selectedMode: false, // 图例设为不可点击
  97. },
  98. grid: {
  99. top: 32,
  100. right: 8,
  101. bottom: 0,
  102. left: 0,
  103. containLabel: true, // 防止标签溢出
  104. },
  105. };
  106. return _options;
  107. }
  108. export default onlineToOffline;

https://www.jb51.net/article/149502.htm