从excel提取和过滤数据到echarts中绘制图

打印 上一主题 下一主题

主题 1603|帖子 1603|积分 4809

主页面

介绍

echarts的事例页面,导入数据比较麻烦,此项目从excel中提取数据(含过滤数据),以注入页面.
代码阐明


  • 全部的需要从excel中读取的参数,从代码中替换.需以{{data}} 包罗在内
  • 使用绘制参数的剖析代码参数可以剖析出来全部参数
  • 数据配置上传文件后,可以选择列
  • 数据过滤条件设定后,点击绘制,此时才会过滤数据
  • 代码块现实是返回echarts.options的信息,下面给了多个事例
  • 图表设置现实没有使用,需要后端支持才可以,将编辑好的代码生存到数据库,大概取出
  • 其他的参数,比方绘制参数,建议直接编辑代码完成,而且建议以变量的形式填写在最上方,以提供出来



页面代码 commonChart.vue

  1. <template>
  2.   <div class="app-container" style="height: 100vh;">
  3.     <el-row style="height: 100%;">
  4.       <el-col :span="10" style="height: 100%;">
  5.           <el-tabs type="border-card" style="height: 100%;">
  6.             <el-tab-pane label="图表设置" style="height: 100%;">
  7.               <el-form ref="elForm" :model="chartForm" label-width="80px" style="height: 100%;">
  8.                 <el-form-item label="选择图表" prop="chartType" >
  9.                   <el-select v-model="chartForm.chartType" placeholder="请选择选择图表" clearable
  10.                              :style="{width: '100%'}">
  11.                     <el-option v-for="(item, index) in chartFormOptions" :key="index" :label="item.label"
  12.                                :value="item.value" :disabled="item.disabled"></el-option>
  13.                   </el-select>
  14.                 </el-form-item>
  15.               </el-form>
  16.             </el-tab-pane>
  17.             <el-tab-pane label="代码编辑" style="height: 100%;">
  18.                 <vue-ace-editor v-model="chartForm.customChartCode" ref="aceEditor"
  19.                                 :width="'100%'"
  20.                                 :height="'100%'"
  21.                                 mode='javascript'
  22.                                 theme='github'/>
  23.             </el-tab-pane>
  24.             <el-tab-pane label="数据配置">
  25.               <el-form :model="dataForm" ref="queryForm" :inline="false" label-width="80px">
  26.                 <el-form-item label="上传文件">
  27.                   <el-upload
  28.                     class="upload-demo"
  29.                     action=""
  30.                     :before-upload="handleBeforeUpload"
  31.                     :file-list="dataForm.fileList"
  32.                     :show-file-list="false">
  33.                     <el-button size="mini" slot="trigger" type="primary">XLSX文件</el-button>
  34.                   </el-upload>
  35.                 </el-form-item>
  36.                 <el-form-item label="数据过滤">
  37.                   <el-table :data="dataForm.dataFilter" style="width: 100%">
  38.                     <!-- 选择变量 -->
  39.                     <el-table-column label="选择变量" prop="variable">
  40.                       <template v-slot="{ row, $index }">
  41.                         <el-select v-model="row.variable" placeholder="请选择变量">
  42.                           <el-option
  43.                             v-for="(item, index) in dataHeader"
  44.                             :key="index"
  45.                             :label="item"
  46.                             :value="index"
  47.                           ></el-option>
  48.                         </el-select>
  49.                       </template>
  50.                     </el-table-column>
  51.                     <!-- 选择判断关系 -->
  52.                     <el-table-column label="选择判断关系" prop="relation">
  53.                       <template v-slot="{ row, $index }">
  54.                         <el-select v-model="row.relation" placeholder="请选择关系">
  55.                           <el-option label="等于" value="equals"></el-option>
  56.                           <el-option label="不等于" value="not_equals"></el-option>
  57.                           <el-option label="大于" value="greater_than"></el-option>
  58.                           <el-option label="小于" value="less_than"></el-option>
  59.                         </el-select>
  60.                       </template>
  61.                     </el-table-column>
  62.                     <!-- 选择判断值 -->
  63.                     <el-table-column label="选择判断值" prop="value">
  64.                       <template v-slot="{ row, $index }">
  65.                         <el-select v-if="uniqueData[row.variable] && uniqueData[row.variable].length<10"
  66.                                    v-model="row.value"
  67.                                    placeholder="请选择值">
  68.                           <el-option
  69.                             v-for="(item, index) in uniqueData[row.variable]"
  70.                             :key="index"
  71.                             :label="item"
  72.                             :value="item"
  73.                           ></el-option>
  74.                         </el-select>
  75.                         <el-input v-else v-model="row.value">
  76.                         </el-input>
  77.                       </template>
  78.                     </el-table-column>
  79.                     <el-table-column label="操作" >
  80.                       <template v-slot="scope">
  81.                         <el-button type="primary" @click="addRow" size="small">+</el-button>
  82.                         <el-button type="danger" @click="deleteRow(scope.$index)" size="small">x</el-button>
  83.                       </template>
  84.                     </el-table-column>
  85.                   </el-table>
  86.                 </el-form-item>
  87.               </el-form>
  88.             </el-tab-pane>
  89.             <el-tab-pane label="绘制参数">
  90.               <el-form ref="elForm" :model="drawForm" label-width="180px">
  91.                 <el-form-item label="操作">
  92.                   <el-button type="primary" icon="el-icon-search" size="mini" @click="analyzeCode()">解析代码参数
  93.                   </el-button>
  94.                 </el-form-item>
  95.                 <el-form-item
  96.                   v-for="(item, index) in customStatisticalDataColumnName"
  97.                   :key="index"
  98.                   :label="`统计参数:${item}`">
  99.                   <el-select
  100.                     v-model="drawForm.statisticalDataColumnCustom[index]"
  101.                     placeholder="请选择统计数据列"
  102.                   >
  103.                     <el-option
  104.                       v-for="(item, index) in dataHeader"
  105.                       :key="index"
  106.                       :label="item"
  107.                       :value="index"
  108.                     ></el-option>
  109.                   </el-select>
  110.                 </el-form-item>
  111.               </el-form>
  112.             </el-tab-pane>
  113.           </el-tabs>
  114.       </el-col>
  115.       <el-col :span="14" style="height: 100%;">
  116.         <el-card style="height: 100%;">
  117.           <div slot="header" class="clearfix">
  118.             <el-button type="primary" icon="el-icon-search" size="medium" @click="redrawChart()">绘制</el-button>
  119.           </div>
  120.           <div id="chart" style="height: 100%;width: 100%"/>
  121.         </el-card>
  122.       </el-col>
  123.     </el-row>
  124.   </div>
  125. </template>
  126. <script>
  127. import * as echarts from "echarts";
  128. import * as XLSX from 'xlsx';
  129. import VueAceEditor from 'vue2-ace-editor';
  130. import 'brace/mode/javascript'; // 引入 JavaScript 语言模式
  131. import 'brace/theme/chrome';
  132. export default {
  133.   components: {
  134.     VueAceEditor,
  135.   },
  136.   data() {
  137.     return {
  138.       dialogVisible: true,
  139.       // 图表配置参数
  140.       chartForm: {
  141.         //图表类型
  142.         chartType: "",
  143.         //自定义图表-代码块
  144.         customChartCode: null,
  145.       },
  146.       // 数据配置参数
  147.       dataForm: {
  148.         fileList: [],   // 存储上传的文件列表
  149.         //过滤条件
  150.         dataFilter: [
  151.           {
  152.             variable: "",
  153.             relation: "",
  154.             value: ""
  155.           }
  156.         ]
  157.       },
  158.       // 绘制参数
  159.       drawForm: {
  160.         statisticalDataColumnCustom: []
  161.       },
  162.       //自定义图表的配置参数列表
  163.       customStatisticalDataColumnName: [],
  164.       chartFormOptions: [
  165.         {
  166.           "label": "自定义图表",
  167.           "value": 0
  168.         },
  169.         {
  170.           "label": "正态分布图",
  171.           "value": 1
  172.         }, {
  173.           "label": "散点图",
  174.           "value": 2
  175.         }
  176.       ],
  177.       dataHeader: [],
  178.       dataBody: [],
  179.       uniqueData: [],
  180.       filterData: [],
  181.       validConditions: [],
  182.       chart: null
  183.     };
  184.   },
  185.   mounted() {
  186.     this.initChart();
  187.     this.$nextTick(() => {
  188.       const aceEditor = this.$refs.aceEditor.editor;
  189.       if (aceEditor) {
  190.         console.log('Editor Loaded:', aceEditor); // 确认编辑器加载成功
  191.         aceEditor.getSession().setMode('ace/mode/javascript');  // 强制设置语言模式
  192.         aceEditor.setTheme('ace/theme/chrome');  // 强制设置主题
  193.         aceEditor.setFontSize('14px');  // 设置字体大小
  194.         aceEditor.setHighlightActiveLine(true);  // 设置是否高亮活动行
  195.       }
  196.     });
  197.   },
  198.   methods: {
  199.     onEditorLoaded(editor) {
  200.       console.log('Editor Loaded:', editor); // 检查 editor 对象
  201.       if (editor) {
  202.         console.log('Ace Mode:', editor.getSession().getMode().$id); // 确认是否加载了 JavaScript 模式
  203.         console.log('Ace Theme:', editor.getTheme()); // 确认主题
  204.       }
  205.     },
  206.     analyzeCode() {
  207.       //提取含{{}}的字符列表["{{d1}}", "{{d2}}"]
  208.       let matchesName = this.chartForm.customChartCode.match(/\{\{(.*?)\}\}/g);
  209.       let matchesNameLabel = []
  210.       if (matchesName) {
  211.         // 去除 {{ 和 }}列表
  212.         matchesNameLabel = matchesName.map(match => match.slice(2, -2));
  213.       }
  214.       this.customStatisticalDataColumnName = matchesNameLabel;
  215.       this.$message({message: '解析成功,提取自定义统计参数' + matchesNameLabel, type: 'warning'})
  216.     },
  217.     addRow() {
  218.       // 添加一行数据到表单中
  219.       this.dataForm.dataFilter.push({variable: '', relation: '', value: ''});
  220.     },
  221.     deleteRow(index) {
  222.       // 删除对应的行
  223.       this.dataForm.dataFilter.splice(index, 1);
  224.     },
  225.     handleBeforeUpload(file) {
  226.       const reader = new FileReader()
  227.       reader.onload = (e) => {
  228.         const data = e.target.result;
  229.         // 解析xlsx文件
  230.         const workbook = XLSX.read(data, {type: 'binary'});
  231.         // 获取第一个工作表
  232.         const sheetName = workbook.SheetNames[0];
  233.         const sheet = workbook.Sheets[sheetName];
  234.         // 原始
  235.         let data_json = XLSX.utils.sheet_to_json(sheet, {header: 1, defval: null});
  236.         // 取出第一行作为表头
  237.         this.dataHeader = data_json.shift();  // 删除并返回数组的第一个元素
  238.         // 剩余的行作为表体
  239.         this.dataBody = data_json;
  240.         this.buildDynamicForms();
  241.         this.$message({message: '解析文件成功,获取记录:' + this.dataBody.length + "条", type: 'warning'})
  242.         // this.drawChart();
  243.       };
  244.       // 读取文件为二进制字符串
  245.       reader.readAsBinaryString(file);
  246.       return false; // 阻止默认的上传行为
  247.     },
  248.     buildDynamicForms() {
  249.       //获取每列的distance值
  250.       let headLength = this.dataHeader.length;
  251.       for (let i = 0; i < headLength; i++) {
  252.         this.uniqueData[i] = this.getUniqueColumn(this.dataBody, i);
  253.       }
  254.     },
  255.     getUniqueColumn(data, index) {
  256.       // 检查数据是否为空
  257.       if (!data || !Array.isArray(data) || data.length === 0) {
  258.         return [];
  259.       }
  260.       // 如果数据是二维数组
  261.       if (Array.isArray(data[0])) {
  262.         // 提取指定列并去重
  263.         const column = data.map(row => row[index]);
  264.         return [...new Set(column)];
  265.       }
  266.       // 如果数据是对象数组
  267.       if (typeof data[0] === 'object') {
  268.         // 提取指定列(即对象的属性)并去重
  269.         const column = data.map(item => item[index]);
  270.         return [...new Set(column)];
  271.       }
  272.       // 如果数据格式不匹配
  273.       return [];
  274.     },
  275.     redrawChart() {
  276.       this.filterDataByConditions();
  277.       let opt = this.chartForm.customChartCode;
  278.       let mapping = this.drawForm.statisticalDataColumnCustom;
  279.       for (let i = 0; i < mapping.length; i++) {
  280.         let data = this.filterData.map(row => row[mapping[i]]);
  281.         opt = opt.replace("{{" + this.customStatisticalDataColumnName[i] + "}}", JSON.stringify(data));
  282.       }
  283.       let rx = (new Function(opt))();
  284.       console.log(rx)
  285.       this.chart.clear()
  286.       this.chart.setOption(rx)
  287.     },
  288.     initChart() {
  289.       let chartDom = document.getElementById("chart");
  290.       this.chart = echarts.init(chartDom);
  291.     },
  292.     filterDataByConditions() {
  293.       this.filterData = this.dataBody.filter(item => {
  294.         this.validConditions = this.dataForm.dataFilter.filter(c => c.value !== "");
  295.         return this.validConditions.every(row => {
  296.           let rowKey = row.variable;
  297.           let operator = row.relation;
  298.           let rowValue = row.value;
  299.           switch (operator) {
  300.             case "equals":
  301.               return item[rowKey] == rowValue;
  302.             case "not_equals":
  303.               return item[rowKey] != rowValue;
  304.             case "greater_than":
  305.               return item[rowKey] > rowValue;
  306.             case "less_than":
  307.               return item[rowKey] < rowValue;
  308.             default:
  309.               throw new Error(`Unknown operator: ${operator}`);
  310.           }
  311.         });
  312.       });
  313.     },
  314.   }
  315. }
  316. ;
  317. </script>
  318. <style scoped>
  319. /* 或者使用 ::v-deep */
  320. ::v-deep .el-dialog__wrapper {
  321.   pointer-events: none;
  322. }
  323. ::v-deep .el-dialog__body {
  324.   padding-bottom: 5px
  325. }
  326. ::v-deep .el-dialog {
  327.   pointer-events: auto;
  328. }
  329. ::v-deep .el-card__body{
  330.   height: 100%;
  331. }
  332. ::v-deep .el-tabs__content{
  333.   height: 90% !important;
  334. }
  335. </style>
复制代码
代码事例

事例1 单散点分布 singleScatterDistribution

  1. // 单散点分布 singleScatterDistribution
  2. /*******************配置参数*******************/
  3. //第一组的x,y,和size,都是一维数组
  4. let dx = {{dx}};
  5. let dy = {{dy}};
  6. let dSize = {{dSize}};
  7. /*******************计算实体********************/
  8. let dataX = dx.map((value, index) => [value, dy[index], dSize[index]]);
  9. return {
  10.   toolbox: {
  11.     show: true,
  12.     feature: {
  13.       dataZoom: {
  14.         yAxisIndex: 'none'
  15.       },
  16.       dataView: {readOnly: false},
  17.       restore: {},
  18.       saveAsImage: {}
  19.     }
  20.   },
  21.   xAxis: {},
  22.   yAxis: {},
  23.   legend: {
  24.     data: ['数据名称'] // 图例项,对应 series 中的 name
  25.   },
  26.   dataZoom: [
  27.     {
  28.       type: 'slider',
  29.       show: true,
  30.       yAxisIndex: [0],
  31.       //不过滤数据,只改变数轴范围。
  32.       filterMode: 'none'
  33.     },
  34.     {
  35.       type: 'inside',
  36.       yAxisIndex: [0],
  37.       filterMode: 'none'
  38.     },
  39.     //x缩放轴
  40.     {
  41.       type: 'slider',
  42.       show: true,
  43.       xAxisIndex: [0],
  44.       filterMode: 'none',
  45.       height: 20
  46.     },
  47.     {
  48.       type: 'inside',
  49.       xAxisIndex: [0],
  50.       filterMode: 'none'
  51.     }
  52.   ],
  53.   series: [
  54.     {
  55.       name: '数据名称',
  56.       symbolSize: function (data) {
  57.         //return data[2]/100; // 返回 data 中的第三个值(size)
  58.         return 7;
  59.       },
  60.       data: dataX,
  61.       type: 'scatter',
  62.       itemStyle: {
  63.         color: '#5470C6' // 设置第一组数据的颜色
  64.       }
  65.     }
  66.   ]
  67. }
复制代码
事例2 双散点分布 doubleScatterDistribution

  1. // 双散点分布 doubleScatterDistribution
  2. /*******************配置参数*******************/
  3. //第一组的x,y,和size,都是一维数组
  4. let d1x = {{d1.x}};
  5. let d1y = {{d1.y}};
  6. let d1size = {{d1.size}};
  7. //第二组的x,y,和size,都是一维数组
  8. let d2x = {{d1.x}};
  9. let d2y = {{d1.y}};
  10. let d2size = {{d1.size}};
  11. /*******************计算实体********************/
  12. let d1 = d1x.map((value, index) => [value, d1y[index], d1size[index]]);
  13. let d2 = d2x.map((value, index) => [value, d2y[index], d2size[index]]);
  14. return {
  15.   toolbox: {
  16.     show: true,
  17.     feature: {
  18.       dataZoom: {
  19.         yAxisIndex: 'none'
  20.       },
  21.       dataView: {readOnly: false},
  22.       restore: {},
  23.       saveAsImage: {}
  24.     }
  25.   },
  26.   xAxis: {},
  27.   yAxis: {},
  28.   legend: {
  29.     data: ['新数据', '旧数据'] // 图例项,对应 series 中的 name
  30.   },
  31.   dataZoom: [
  32.     {
  33.       type: 'slider',
  34.       show: true,
  35.       yAxisIndex: [0],
  36.       //不过滤数据,只改变数轴范围。
  37.       filterMode: 'none'
  38.     },
  39.     {
  40.       type: 'inside',
  41.       yAxisIndex: [0],
  42.       filterMode: 'none'
  43.     },
  44.     //x缩放轴
  45.     {
  46.       type: 'slider',
  47.       show: true,
  48.       xAxisIndex: [0],
  49.       filterMode: 'none',
  50.       height: 20
  51.     },
  52.     {
  53.       type: 'inside',
  54.       xAxisIndex: [0],
  55.       filterMode: 'none'
  56.     }
  57.   ],
  58.   series: [
  59.     {
  60.       name: '新数据',
  61.       symbolSize: function (data) {
  62.         //return data[2]/100; // 返回 data 中的第三个值(size)
  63.         return 7;
  64.       },
  65.       data: d1,
  66.       type: 'scatter',
  67.       itemStyle: {
  68.         color: '#5470C6' // 设置第一组数据的颜色
  69.       }
  70.     },
  71.     {
  72.       name: '旧数据',
  73.       symbolSize: function (data) {
  74.         //return data[2] + 5; // 返回 data 中的第三个值(size)
  75.         return 7;
  76.       },
  77.       data: d2,
  78.       type: 'scatter',
  79.       itemStyle: {
  80.         color: '#EE6666' // 设置第二组数据的颜色
  81.       }
  82.     }
  83.   ]
  84. }
复制代码
事例3 单正态分布图 singleNormalDistribution

  1. // 单正态分布图 singleNormalDistribution
  2. /*******************配置参数*******************/
  3. // 组间距
  4. let interval = 0.1;
  5. // 参数实例 [1,2,3,4,5]
  6. let da = {{data}}
  7. // 标题
  8. let title = "这里填写标题"
  9. //图表颜色
  10. let drawColor = "rgba(19,72,206,0.5)"
  11. /*******************计算实体********************/
  12. //计算正态曲线
  13. function fxNormalDistribution(array, std, mean) {
  14.   let valueList = [];
  15.   for (let i = 0; i < array.length; i++) {
  16.     let ND =
  17.       Math.sqrt(2 * Math.PI) *
  18.       std *
  19.       Math.pow(
  20.         Math.E,
  21.         -(Math.pow(array[i] - mean, 2) / (2 * Math.pow(std, 2)))
  22.       );
  23.     valueList.push(ND.toFixed(3));
  24.   }
  25.   return valueList;
  26. }
  27. //计算标准差
  28. function getStd(data, mean) {
  29.   let sumXY = function (x, y) {
  30.     return Number(x) + Number(y);
  31.   };
  32.   let square = function (x) {
  33.     return Number(x) * Number(x);
  34.   };
  35.   let deviations = data.map(function (x) {
  36.     return x - mean;
  37.   });
  38.   return Math.sqrt(deviations.map(square).reduce(sumXY) / (data.length - 1));
  39. }
  40. //对有序数组求中位数
  41. function getMedianSorted(arr) {
  42.   // 获取数组长度
  43.   let len = arr.length;
  44.   // 如果没有元素,返回undefined或你可以返回其他合适的值
  45.   if (len === 0) {
  46.     return undefined;
  47.   }
  48.   // 如果只有一个元素,那么它就是中位数
  49.   if (len === 1) {
  50.     return arr[0];
  51.   }
  52.   // 如果数组长度是奇数,返回中间的数
  53.   if (len % 2 === 1) {
  54.     return arr[Math.floor(len / 2)];
  55.   }
  56.   // 如果数组长度是偶数,返回中间两个数的平均值
  57.   else {
  58.     let mid1 = arr[len / 2 - 1];
  59.     let mid2 = arr[len / 2];
  60.     return (mid1 + mid2) / 2.0;
  61.   }
  62. }
  63. function getUniqueColumn(data, index) {
  64.   // 检查数据是否为空
  65.   if (!data || !Array.isArray(data) || data.length === 0) {
  66.     return [];
  67.   }
  68.   // 如果数据是二维数组
  69.   if (Array.isArray(data[0])) {
  70.     // 提取指定列并去重
  71.     const column = data.map(row => row[index]);
  72.     return [...new Set(column)];
  73.   }
  74.   // 如果数据是对象数组
  75.   if (typeof data[0] === 'object') {
  76.     // 提取指定列(即对象的属性)并去重
  77.     const column = data.map(item => item[index]);
  78.     return [...new Set(column)];
  79.   }
  80.   // 如果数据格式不匹配
  81.   return [];
  82. }
  83. function getInterval(va, xAxisX) {
  84.   for (let i = 0; i < xAxisX.length; i++) {
  85.     if (xAxisX[i] > va) {
  86.       if (i === 0) {
  87.         return xAxisX[0].toString();
  88.       } else {
  89.         return xAxisX[i - 1].toString();
  90.       }
  91.     }
  92.   }
  93.   return xAxisX[xAxisX.length - 1].toString();
  94. }
  95. function extracted(da) {
  96.   //获取参数指定的公差,标准值,组间据
  97.   da.sort((a, b) => a - b);
  98.   let mid = getMedianSorted(da).toFixed(3) * 1.0;
  99.   // 计算各项最大值,最小值,均值,以及cpk值,以及数组长度
  100.   let length = da.length;
  101.   let max = Math.max(...da);
  102.   let min = Math.min(...da);
  103.   let mean = da.reduce((sum, val) => sum + val, 0) / length;
  104.   //依据原始数据重新计算数据X轴
  105.   //x轴最大最小前后范围
  106.   let dataRangeMinOP = 1;
  107.   let dataRangeMaxOP = 1.1;
  108.   // 设定区间起始和结束值,以及间距 ,X轴的步距
  109.   let start = min - dataRangeMinOP;
  110.   let end = max + dataRangeMaxOP;
  111.   start = start.toFixed(0) * 1.0;
  112.   // 计算区间数量
  113.   let numIntervals = Math.ceil((end - start) / interval);
  114.   //获取所有区间,以及初始化区间每个区间的频数为0
  115.   let xAxis = [];
  116.   let barYaxis = new Array(numIntervals).fill(0);
  117.   for (let i = start; i <= end; i = i + interval) {
  118.     let str = i.toFixed(1).toString();
  119.     xAxis.push(str);
  120.   }
  121.   // 遍历数组并计算频数
  122.   da.forEach((value) => {
  123.     if (value >= start && value <= end) {
  124.       // 找到值所在的区间
  125.       let intervalIndex = Math.floor((value - start) / interval);
  126.       // 增加该区间的频数
  127.       barYaxis[intervalIndex]++;
  128.     }
  129.   });
  130.   //正态曲线计算的基本数据和方法
  131.   //计算标准差
  132.   let std = getStd(da, mean);
  133.   //依据x轴,计算正态分布值
  134.   let lineYaxis = fxNormalDistribution(xAxis, std, mean);
  135.   //求得分布曲线最大值,用以绘制纵向线
  136.   let y1Max = Math.max(...lineYaxis);
  137.   let midInterval = getInterval(mid, xAxis);
  138.   //定义Y轴
  139.   //定义实际数据的频数柱状图
  140.   let barDataSet = {
  141.     type: "bar",
  142.     smooth: true,
  143.     xAxisIndex: 0,
  144.     yAxisIndex: 0,
  145.     areaStyle: {
  146.       opacity: 0,
  147.     },
  148.     markLine: {
  149.       silent: true,
  150.       label: {
  151.         fontSize: 10
  152.       },
  153.       lineStyle: {
  154.         color: "rgb(255,0,0)",
  155.       },
  156.       data: [],
  157.     },
  158.     data: barYaxis,
  159.     itemStyle: {
  160.       normal: {
  161.         label: {
  162.           formatter: "{c} %",
  163.           show: false, //默认显示
  164.           position: "top", //在上方显示
  165.           textStyle: {
  166.             //数值样式
  167.             fontSize: 10,
  168.           },
  169.         },
  170.       },
  171.     },
  172.   };
  173.   //计算实际数据的正态分布图
  174.   let lineDataSet = {
  175.     type: "line",
  176.     smooth: true,
  177.     xAxisIndex: 0,
  178.     yAxisIndex: 1,
  179.     areaStyle: {
  180.       opacity: 0,
  181.     },
  182.     markLine: {
  183.       silent: true,
  184.       label: {
  185.         fontSize: 12
  186.       },
  187.       data: [
  188.         [
  189.           {
  190.             name: "中位数:" + mid,
  191.             coord: [midInterval, 0],
  192.           },
  193.           {
  194.             coord: [midInterval, y1Max],
  195.           },
  196.         ],
  197.       ],
  198.     },
  199.     data: lineYaxis,
  200.     itemStyle: {
  201.       normal: {
  202.         label: {
  203.           formatter: "{c} %",
  204.           show: false, //开启显示
  205.           position: "top", //在上方显示
  206.           textStyle: {
  207.             //数值样式
  208.             fontSize: 10,
  209.           },
  210.         },
  211.       },
  212.     },
  213.   };
  214.   return {xAxis, barDataSet, lineDataSet};
  215. }
  216. function getOptions() {
  217.   x = extracted(da);
  218.   return {
  219.     color: drawColor,
  220.     //工具栏。内置有导出图片,数据视图,动态类型切换,数据区域缩放,重置五个工具。
  221.     toolbox: {
  222.       show: true,
  223.       feature: {
  224.         dataZoom: {
  225.           yAxisIndex: "none",
  226.         },
  227.         dataView: {readOnly: false},
  228.         restore: {},
  229.         saveAsImage: {},
  230.       },
  231.     },
  232.     title: {
  233.       text: title,
  234.       left: "center"
  235.     },
  236.     grid: {
  237.       top: 80
  238.     },
  239.     //提示框组件
  240.     tooltip: {
  241.       trigger: "axis",
  242.       axisPointer: {
  243.         type: "shadow",
  244.       },
  245.     },
  246.     //图例
  247.     legend: {
  248.       right: "0%",
  249.       top: "0",
  250.       textStyle:
  251.         {
  252.           fontSize: 12
  253.         }
  254.     },
  255.     xAxis: [
  256.       {boundaryGap: true, type: "category", gridIndex: 0, data: x.xAxis},
  257.     ],
  258.     //定义y轴,2个轴
  259.     yAxis: [
  260.       {
  261.         type: "value", gridIndex: 0, max: function (value) {
  262.           return value.max + 5;
  263.         }
  264.       },
  265.       {
  266.         type: "value", gridIndex: 0, max: function (value) {
  267.           return (value.max + 0.2).toFixed(1);
  268.         }
  269.       }
  270.     ],
  271.     series: [
  272.       x.barDataSet, x.lineDataSet,
  273.     ],
  274.   }
  275. }
  276. return getOptions();
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

水军大提督

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表