123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626 |
- <template>
- <!-- littlegreen - 月度预测数据 - 补充form-label-->
- <div :class="className" :style="{ height: height, width: width }">
- <div class="select-container">
- <el-form
- style="
- display: grid;
- grid-template-columns: 1fr 1fr 1fr;
- align-items: center;
- grid-gap: 20px;
- "
- label-width="120px"
- >
- <el-form-item label="企业" style="margin-bottom: 0">
- <el-select v-model="selectedEnterprise" style="width: 100%">
- <el-option
- v-for="item in uniqueEnterprises"
- :key="item.enterpriseName"
- :value="item.enterpriseName"
- >
- {{ item.enterpriseName }}
- </el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="评估指标" style="margin-bottom: 0">
- <el-select v-model="selectedDataKey" style="width: 100%">
- <el-option
- v-for="key in dataKeys"
- :key="key"
- :value="key"
- :label="keyToChinese[key]"
- >
- {{ keyToChinese[key] }}
- </el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="年度" style="margin-bottom: 0">
- <el-select v-model="selectedYear" style="width: 100%">
- <el-option v-for="year in availableYears" :key="year" :value="year">
- {{ year }}
- </el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="报警阈值" style="margin-bottom: 0">
- <el-input
- v-model="errorVal"
- placeholder="报警阈值"
- clearable
- style="width: 100%"
- />
- </el-form-item>
- <el-form-item label="预测模型" style="margin-bottom: 0">
- <el-select v-model="selectedModel" style="width: 100%">
- <el-option
- v-for="model in availableModels"
- :key="model"
- :value="model"
- >
- {{ model }}
- </el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="采用预测模型" style="margin-bottom: 0">
- <div style="display: inline; padding-left: 10px">
- {{ selectedModel }}
- </div>
- </el-form-item>
- <el-form-item style="margin-bottom: 0">
- <el-button
- type="primary"
- @click="updateChart"
- size="mini"
- >计算</el-button
- >
- </el-form-item>
- </el-form>
- </div>
- <div ref="chart" :style="{ height: height, width: width }"></div>
- </div>
- </template>
- <script>
- import * as echarts from "echarts";
- import { listPredict } from "@/api/predict/predict";
- import { listBase_data_month } from "@/api/base_data_month/base_data_month";
- require("echarts/theme/macarons");
- import resize from "./mixins/resize";
- import { Decimal } from "decimal.js";
- export default {
- mixins: [resize],
- props: {
- className: {
- type: String,
- default: "chart",
- },
- width: {
- type: String,
- default: "100%",
- },
- height: {
- type: String,
- default: "400px",
- },
- },
- data() {
- return {
- errorVal: null,
- chart: null,
- chartData: [],
- base_data_monthData: [],
- selectedDataKey: "totalIndustrialValuePredict", // 默认第一个
- dataKeys: [
- "totalIndustrialValuePredict",
- // 'taxableIncomePredict',
- // 'paidTaxPredict',
- // 'energyConsumePredict',
- "powerConsumePredict",
- ],
- keyToChinese: {
- totalIndustrialValuePredict: "工业总产值预测",
- // 'taxableIncomePredict': '应税收入预测',
- // 'paidTaxPredict': '实缴税金预测',
- // 'energyConsumePredict': '能源消费量预测'
- powerConsumePredict: "电力消费预测",
- },
- keyToChineseTruth: {
- totalIndustrialValuePredict: "工业总产值实际数据",
- taxableIncomePredict: "应税收入实际数据",
- paidTaxPredict: "实缴税金实际数据",
- energyConsumePredict: "能源消费量实际数据",
- powerConsumePredict: "电力消费实际数据",
- },
- selectedYear: null,
- selectedEnterprise: null,
- selectedModel: null,
- queryParams: {
- pageNum: 1,
- pageSize: 2000000,
- enterpriseName: this.selectedEnterprise,
- location: null,
- code: null,
- mainBusiness: null,
- landArea: null,
- totalIndustrialValue: null,
- gdp: null,
- taxableIncome: null,
- paidTax: null,
- mainBusinessIncome: null,
- employeeNumber: null,
- profit: null,
- ownerEquity: null,
- funding: null,
- energyConsume: null,
- year: this.selectedYear,
- month: null,
- model: null,
- },
- availableYears: [],
- uniqueEnterprises: [],
- availableModels: [],
- };
- },
- mounted() {
- this.$nextTick(() => {
- this.fetchData();
- });
- },
- beforeDestroy() {
- if (this.chart) {
- this.chart.dispose();
- }
- },
- methods: {
- fetchData() {
- listPredict(this.queryParams)
- .then((response) => {
- this.chartData = response.rows;
- // console.log(this.chartData);
- this.availableYears = [
- ...new Set(this.chartData.map((item) => item.year)),
- ];
- this.selectedYear = this.availableYears[0] || null;
- this.uniqueEnterprises = [
- ...new Set(
- this.chartData.map((item) => ({
- enterpriseName: item.enterpriseName,
- }))
- ),
- ];
- this.uniqueEnterprises = Array.from(
- new Set(this.chartData.map((item) => item.enterpriseName))
- ).map((name) => ({ enterpriseName: name }));
- this.selectedEnterprise =
- this.uniqueEnterprises.length > 0
- ? this.uniqueEnterprises[0].enterpriseName
- : null;
- this.availableModels = [
- ...new Set(this.chartData.map((item) => item.model)),
- ];
- this.selectedModel = this.availableModels[0] || null;
- // 获取实际数据
- listBase_data_month(this.queryParams).then((response) => {
- this.base_data_monthData = response.rows;
- // console.log("vvv" + this.base_data_monthData.length); // 10
- this.initChart();
- });
- })
- .catch((error) => {
- console.error("Error fetching data:", error);
- });
- },
- initChart() {
- if (this.chart) {
- this.chart.dispose();
- }
- this.chart = echarts.init(this.$refs.chart, "macarons");
- this.updateChart();
- },
- // littlegreen 检验是否正确填写预警值
- checkErrorVal(number) {
- let val = parseFloat(number);
- let flag;
- if (!number) {
- return (flag = 0);
- }
- if (isNaN(val)) {
- this.$message({
- message: "请输入有效的数字。",
- type: "error",
- });
- return (flag = 2);
- }
- return (flag = 1);
- },
- updateChart() {
- const that = this;
- let flag = that.checkErrorVal(that.errorVal);
- if (flag == 2) {
- return;
- }
- if (!this.chart) {
- return;
- }
- let filteredData = this.chartData.filter(
- (item) =>
- item.year === this.selectedYear &&
- item.enterpriseName === this.selectedEnterprise &&
- item.model === this.selectedModel
- );
- // console.log(filteredData,"filteredData")
- //const xValues = filteredData.map(item => item.month + '月');
- const xValues = [
- "1月",
- "2月",
- "3月",
- "4月",
- "5月",
- "6月",
- "7月",
- "8月",
- "9月",
- "10月",
- "11月",
- "12月",
- ];
- let yValues;
- // 根据选择的不同预测数据 key 获取对应的值
- switch (this.selectedDataKey) {
- case "totalIndustrialValuePredict":
- yValues = filteredData.map((item) => [
- item.totalIndustrialValuePredict,
- item.month,
- ]);
- break;
- case "taxableIncomePredict":
- yValues = filteredData.map((item) => [
- item.taxableIncomePredict,
- item.month,
- ]);
- break;
- case "paidTaxPredict":
- yValues = filteredData.map((item) => [
- item.paidTaxPredict,
- item.month,
- ]);
- break;
- case "energyConsumePredict":
- yValues = filteredData.map((item) => [
- item.energyConsumePredict,
- item.month,
- ]);
- break;
- case "powerConsumePredict":
- yValues = filteredData.map((item) => [
- item.powerConsumePredict,
- item.month,
- ]);
- break;
- case "fundingConsumePredict":
- yValues = filteredData.map((item) => [
- item.fundingConsumePredict,
- item.month,
- ]);
- break;
- }
- // console.log(yValues, "yValues"); // 预测数据
- // // 处理实际数据
- // console.log(this.base_data_monthData, "初始过往数据");
- // console.log(filteredData, "过滤好的预测数据");
- const base_data_monthFiltered = this.base_data_monthData.filter(
- (item) =>
- item.year === this.selectedYear &&
- item.enterpriseName === this.selectedEnterprise
- );
- // console.log(base_data_monthFiltered, "base_data_monthFiltered"); //往期数据
- const base_data_monthXValues = base_data_monthFiltered.map(
- (item) => item.month + "月"
- );
- let base_data_monthYValues;
- switch (this.selectedDataKey) {
- case "totalIndustrialValuePredict":
- base_data_monthYValues = base_data_monthFiltered.map((item) => [
- item.totalIndustrialValue,
- item.month,
- ]);
- break;
- case "taxableIncomePredict":
- base_data_monthYValues = base_data_monthFiltered.map((item) => [
- item.taxableIncome,
- item.month,
- ]);
- break;
- case "paidTaxPredict":
- base_data_monthYValues = base_data_monthFiltered.map((item) => [
- item.paidTax,
- item.month,
- ]);
- break;
- case "powerConsumePredict":
- base_data_monthYValues = base_data_monthFiltered.map((item) => [
- item.powerConsume,
- item.month,
- ]);
- break;
- case "energyConsumePredict":
- base_data_monthYValues = base_data_monthFiltered.map((item) => [
- item.energyConsume,
- item.month,
- ]);
- break;
- }
- // littlegreen - 获取预警的markArea
- function getErrorArray(flag, yValues, monthYValues, xValues) {
- if (flag == 0) {
- return [];
- }
- const errorArray = [];
- const error = new Decimal(that.errorVal);
- yValues.forEach((yValue) => {
- const yVal = new Decimal(yValue[0]);
- const month = yValue[1];
- // 在 base_data_monthYValues 中找到相应的月
- const baseData = monthYValues.find((base) => base[1] === month);
- if (baseData) {
- const baseVal = new Decimal(baseData[0]);
- // 计算差值
- const difference = yVal.minus(baseVal);
- // 如果差值大于10,添加该月到新数组
- if (difference.gt(error)) {
- // 10-90 80分成xValues.length份
- errorArray.push([
- {
- x:
- 10 +
- (80 / xValues.length) * xValues.indexOf(month + "月") +
- "%",
- },
- {
- x:
- 10 +
- (80 / xValues.length) *
- (xValues.indexOf(month + "月") + 1) +
- "%",
- },
- ]);
- }
- }
- });
- return errorArray;
- }
- // console.log(yValues, base_data_monthYValues, xValues);
- yValues.sort((a, b) => {
- let aValue = new Decimal(a[1]);
- let bValue = new Decimal(b[1]);
- return aValue.cmp(bValue); // cmp方法用于比较两个Decimal对象
- });
- base_data_monthYValues.sort((a, b) => {
- let aValue = new Decimal(a[1]);
- let bValue = new Decimal(b[1]);
- return aValue.cmp(bValue); // cmp方法用于比较两个Decimal对象
- });
- this.chart.setOption(
- {
- legend: {
- data: [
- this.selectedEnterprise +
- " " +
- this.selectedYear +
- "年" +
- this.keyToChineseTruth[this.selectedDataKey],
- this.selectedEnterprise +
- " " +
- this.selectedYear +
- "年" +
- this.keyToChinese[this.selectedDataKey],
- ],
- },
- tooltip: {
- trigger: "axis",
- },
- toolbox: {
- show: false,
- feature: {
- saveAsImage: {},
- },
- },
- xAxis: {
- type: "category",
- data: xValues,
- },
- yAxis: {
- type: "value",
- },
- series: [
- {
- name:
- this.selectedEnterprise +
- " " +
- this.selectedYear +
- "年" +
- this.keyToChineseTruth[this.selectedDataKey],
- // + this.keyToChinese[this.selectedDataKey],
- type: "line",
- smooth: true,
- data: base_data_monthYValues.map((value) => [
- xValues[value[1] - 1],
- value[0],
- ]),
- color: "#4CAF50",
- markArea: {
- itemStyle: {
- color: "rgba(255, 173, 177, 0.4)",
- },
- data: getErrorArray(
- flag,
- base_data_monthYValues,
- yValues,
- xValues
- ),
- },
- },
- {
- name:
- this.selectedEnterprise +
- " " +
- this.selectedYear +
- "年" +
- this.keyToChinese[this.selectedDataKey],
- type: "line",
- smooth: true,
- color: "#FF5722",
- data: yValues.map((value) => [
- xValues[Number(value[1]) - 1],
- value[0],
- ]),
- },
- ],
- }
- // {
- // tooltip: {
- // trigger: "axis",
- // axisPointer: {
- // type: "shadow",
- // },
- // },
- // legend: {
- // data: [
- // this.selectedEnterprise +
- // " " +
- // this.selectedYear +
- // "年" +
- // this.keyToChinese[this.selectedDataKey],
- // this.selectedEnterprise +
- // " " +
- // this.selectedYear +
- // "年" +
- // this.keyToChineseTruth[this.selectedDataKey],
- // ],
- // },
- // grid: {
- // left: "3%",
- // right: "4%",
- // bottom: "3%",
- // containLabel: true,
- // },
- // xAxis: {
- // type: "category",
- // data: xValues,
- // boundaryGap: true,
- // axisLabel: {
- // fontSize: 12,
- // },
- // },
- // yAxis: {
- // type: "value",
- // },
- // series: [
- // {
- // name:
- // this.selectedEnterprise +
- // " " +
- // this.selectedYear +
- // "年" +
- // this.keyToChinese[this.selectedDataKey],
- // type: "line",
- // data: yValues.map((value) => [
- // xValues[Number(value[1]) - 1],
- // value[0],
- // ]), // 根据多少月去获取对应的数据
- // // color: "#4CAF50",
- // itemStyle: {
- // normal: {
- // color: function (params) {
- // const value = params.data[1];
- // if (flag == 1) {
- // if (value >= that.errorVal)
- // //预警值有值
- // return "blue";
- // }
- // return "#4CAF50";
- // },
- // },
- // },
- // },
- // {
- // name:
- // this.selectedEnterprise +
- // " " +
- // this.selectedYear +
- // "年" +
- // this.keyToChineseTruth[this.selectedDataKey],
- // // + this.keyToChinese[this.selectedDataKey],
- // type: "line",
- // // data: base_data_monthYValues.map((value, index) => [base_data_monthXValues[index], value]),
- // data: base_data_monthYValues.map((value) => [
- // xValues[value[1] - 1],
- // value[0],
- // ]),
- // color: "#FF5722",
- // markArea: {
- // itemStyle: {
- // color: "rgba(255, 173, 177, 0.4)",
- // },
- // data: [
- // [
- // {
- // name: "Morning Peak",
- // x: "10%",
- // },
- // {
- // x: 10 + (80 / 12) * 5 + "%",
- // },
- // ],
- // ],
- // },
- // },
- // ],
- // }
- );
- },
- },
- watch: {
- // selectedDataKey() {
- // this.updateChart();
- // },
- // selectedYear() {
- // this.updateChart();
- // },
- // selectedEnterprise() {
- // this.updateChart();
- // },
- },
- };
- </script>
- <style scoped>
- .select-container {
- margin: 10px 5px;
- font-size: 16px;
- }
- .select-container select {
- padding: 10px 20px;
- margin-right: 10px;
- border: 1px solid #121315;
- border-radius: 4px;
- background-color: white;
- color: #121315;
- font-size: 16px;
- cursor: pointer;
- outline: none;
- }
- .select-container select:hover {
- border-color: #1a7cc8;
- }
- .select-container select:focus {
- border-color: #121315;
- box-shadow: 0 0 0 2px rgba(64, 159, 255, 0.2);
- }
- </style>
|