|
@@ -2,19 +2,6 @@ import * as echarts from '../../components/ec-canvas/echarts';
|
|
|
|
|
|
Page({
|
|
|
data: {
|
|
|
- ecBox: {
|
|
|
- onInit: function (canvas, width, height, dpr) {
|
|
|
- const boxChart = echarts.init(canvas, null, {
|
|
|
- width: width,
|
|
|
- height: height,
|
|
|
- devicePixelRatio: dpr // new
|
|
|
- });
|
|
|
- canvas.setChart(boxChart);
|
|
|
- boxChart.setOption(getBoxOption());
|
|
|
-
|
|
|
- return boxChart;
|
|
|
- }
|
|
|
- },
|
|
|
ecLine: {
|
|
|
onInit: function (canvas, width, height, dpr) {
|
|
|
const lineChart = echarts.init(canvas, null, {
|
|
@@ -28,44 +15,45 @@ Page({
|
|
|
return lineChart;
|
|
|
}
|
|
|
},
|
|
|
- ecScatter: {
|
|
|
+ ecInitScatter: {
|
|
|
onInit: function (canvas, width, height, dpr) {
|
|
|
- const scatterChart = echarts.init(canvas, null, {
|
|
|
+ const initScatter = echarts.init(canvas, null, {
|
|
|
width: width,
|
|
|
height: height,
|
|
|
devicePixelRatio: dpr // new
|
|
|
});
|
|
|
- canvas.setChart(scatterChart);
|
|
|
- scatterChart.setOption(getScatterOption());
|
|
|
+ canvas.setChart(initScatter);
|
|
|
+ initScatter.setOption(getInitScatterOption());
|
|
|
|
|
|
- return scatterChart;
|
|
|
+ return initScatter;
|
|
|
}
|
|
|
},
|
|
|
- ecBar: {
|
|
|
- onInit: function (canvas, width, height, dpr) {
|
|
|
- const barChart = echarts.init(canvas, null, {
|
|
|
- width: width,
|
|
|
- height: height,
|
|
|
- devicePixelRatio: dpr
|
|
|
- });
|
|
|
- canvas.setChart(barChart);
|
|
|
- barChart.setOption(getBarOption());
|
|
|
- return barChart;
|
|
|
- }
|
|
|
- },
|
|
|
- ecPie: {
|
|
|
+ ecMidScatter: {
|
|
|
+ onInit: function (canvas, width, height, dpr) {
|
|
|
+ const midScatter = echarts.init(canvas, null, {
|
|
|
+ width: width,
|
|
|
+ height: height,
|
|
|
+ devicePixelRatio: dpr // new
|
|
|
+ });
|
|
|
+ canvas.setChart(midScatter);
|
|
|
+ midScatter.setOption(getMidScatterOption());
|
|
|
+
|
|
|
+ return midScatter;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ ecFinalScatter: {
|
|
|
onInit: function (canvas, width, height, dpr) {
|
|
|
- const pieChart = echarts.init(canvas, null, {
|
|
|
+ const finalScatter = echarts.init(canvas, null, {
|
|
|
width: width,
|
|
|
height: height,
|
|
|
devicePixelRatio: dpr // new
|
|
|
});
|
|
|
- canvas.setChart(pieChart);
|
|
|
- pieChart.setOption(getPieOption());
|
|
|
+ canvas.setChart(finalScatter);
|
|
|
+ finalScatter.setOption(getFinalScatterOption());
|
|
|
|
|
|
- return pieChart;
|
|
|
+ return finalScatter;
|
|
|
}
|
|
|
- }
|
|
|
+ },
|
|
|
},
|
|
|
|
|
|
onReady() {
|
|
@@ -73,19 +61,45 @@ Page({
|
|
|
}
|
|
|
});
|
|
|
|
|
|
-function getBarOption() {
|
|
|
+// 反酸模型 初代 散点图
|
|
|
+function getInitScatterOption() {
|
|
|
+ /**
|
|
|
+ * 计算数据的最大最小值
|
|
|
+ * @param {Array} data - 散点数据数组
|
|
|
+ * @returns {Object} 包含 xMin, xMax, yMin, yMax 的对象
|
|
|
+ */
|
|
|
+ const calculateDataRange = (data) => {
|
|
|
+ let xValues = data.map(item => item[0]);
|
|
|
+ let yValues = data.map(item => item[1]);
|
|
|
+
|
|
|
+ return {
|
|
|
+ xMin: Math.min(...xValues),
|
|
|
+ xMax: Math.max(...xValues),
|
|
|
+ yMin: Math.min(...yValues),
|
|
|
+ yMax: Math.max(...yValues)
|
|
|
+ };
|
|
|
+ };
|
|
|
+
|
|
|
+ const scatterData = [[-0.003333333333333854, -0.4181333333333324], [-0.1733333333333329, -0.26733333333333265], [-0.6233333333333331, -0.3718666666666661], [-0.7088888888888892, -0.3854666666666661], [-0.3366666666666669, -0.3998666666666657], [-0.8888888888888887, -0.36439999999999934], [-0.5633333333333326, -0.6207999999999997], [-0.7333333333333325, -0.36026666666666607], [-0.3366666666666663, -0.29213333333333275], [-1.176666666666666, -0.6095999999999993], [-0.7122222222222225, -0.3807999999999989], [-0.7699999999999996, -0.3718666666666661]];
|
|
|
+
|
|
|
+ const range = calculateDataRange(scatterData);
|
|
|
+ const padding = 0.1;
|
|
|
+ const xMin = range.xMin - Math.abs(range.xMin * padding);
|
|
|
+ const xMax = range.xMax + Math.abs(range.xMax * padding);
|
|
|
+ const yMin = range.yMin - Math.abs(range.yMin * padding);
|
|
|
+ const yMax = range.yMax + Math.abs(range.yMax * padding);
|
|
|
+ const min = Math.min(xMin, yMin)
|
|
|
+ const max = Math.max(xMax, yMax)
|
|
|
+
|
|
|
return {
|
|
|
- title: {
|
|
|
- text: 'Basic Bar Chart'
|
|
|
- },
|
|
|
tooltip: {
|
|
|
trigger: 'axis',
|
|
|
axisPointer: {
|
|
|
- type: 'shadow'
|
|
|
+ type: 'cross'
|
|
|
}
|
|
|
},
|
|
|
legend: {
|
|
|
- data: ['Sales']
|
|
|
+ data: ['True vs Predicted']
|
|
|
},
|
|
|
grid: {
|
|
|
left: '3%',
|
|
@@ -94,162 +108,218 @@ function getBarOption() {
|
|
|
containLabel: true
|
|
|
},
|
|
|
xAxis: {
|
|
|
- type: 'category',
|
|
|
- data: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul']
|
|
|
+ name: 'True Values',
|
|
|
+ type: 'value',
|
|
|
+ min: min,
|
|
|
+ max: max
|
|
|
},
|
|
|
yAxis: {
|
|
|
- type: 'value'
|
|
|
+ name: 'Predicted Values',
|
|
|
+ type: 'value',
|
|
|
+ min: parseFloat(min).toFixed(2),
|
|
|
+ max: parseFloat(max).toFixed(2)
|
|
|
},
|
|
|
series: [
|
|
|
{
|
|
|
- name: 'Sales',
|
|
|
- type: 'bar',
|
|
|
- data: [5, 20, 36, 10, 10, 20, 30],
|
|
|
+ name: 'True vs Predicted',
|
|
|
+ type: 'scatter',
|
|
|
+ data: scatterData,
|
|
|
+ symbolSize: 10,
|
|
|
itemStyle: {
|
|
|
- color: '#c23531'
|
|
|
+ color: '#1f77b4',
|
|
|
+ opacity: 0.7
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'Trendline',
|
|
|
+ type: 'line',
|
|
|
+ data: [
|
|
|
+ [min, min],
|
|
|
+ [max, max]
|
|
|
+ ],
|
|
|
+ lineStyle: {
|
|
|
+ type: 'dashed',
|
|
|
+ color: '#ff7f0e',
|
|
|
+ width: 2
|
|
|
}
|
|
|
}
|
|
|
]
|
|
|
- }
|
|
|
+ };
|
|
|
}
|
|
|
-function getBoxOption() {
|
|
|
+
|
|
|
+// 反酸模型 中间代 散点图
|
|
|
+function getMidScatterOption() {
|
|
|
+ /**
|
|
|
+ * 计算数据的最大最小值
|
|
|
+ * @param {Array} data - 散点数据数组
|
|
|
+ * @returns {Object} 包含 xMin, xMax, yMin, yMax 的对象
|
|
|
+ */
|
|
|
+ const calculateDataRange = (data) => {
|
|
|
+ let xValues = data.map(item => item[0]);
|
|
|
+ let yValues = data.map(item => item[1]);
|
|
|
+
|
|
|
+ return {
|
|
|
+ xMin: Math.min(...xValues),
|
|
|
+ xMax: Math.max(...xValues),
|
|
|
+ yMin: Math.min(...yValues),
|
|
|
+ yMax: Math.max(...yValues)
|
|
|
+ };
|
|
|
+ };
|
|
|
+
|
|
|
+ const scatterData = [[-0.003333333333333854, -0.5483999999999993], [-0.1733333333333329, -0.2093333333333331], [-0.6233333333333331, -0.5090000000000002], [-0.7088888888888892, -0.4281333333333331], [-0.3366666666666669, -0.4691333333333336], [-0.8888888888888887, -0.49643333333333267], [-0.5633333333333326, -0.7191999999999996], [-0.7333333333333325, -0.5024666666666666], [-0.3366666666666663, -0.37796666666666623], [-1.176666666666666, -0.6415666666666656], [-0.7122222222222225, -0.43299999999999966], [-0.7699999999999996, -0.499966666666667]];
|
|
|
+
|
|
|
+ const range = calculateDataRange(scatterData);
|
|
|
+ const padding = 0.1;
|
|
|
+ const xMin = range.xMin - Math.abs(range.xMin * padding);
|
|
|
+ const xMax = range.xMax + Math.abs(range.xMax * padding);
|
|
|
+ const yMin = range.yMin - Math.abs(range.yMin * padding);
|
|
|
+ const yMax = range.yMax + Math.abs(range.yMax * padding);
|
|
|
+ const min = Math.min(xMin, yMin)
|
|
|
+ const max = Math.max(xMax, yMax)
|
|
|
return {
|
|
|
- title: {
|
|
|
- text: 'Sample ΔpH'
|
|
|
- },
|
|
|
- tooltip: {
|
|
|
- trigger: 'item',
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'axis',
|
|
|
axisPointer: {
|
|
|
- type: 'shadow'
|
|
|
+ type: 'cross'
|
|
|
}
|
|
|
- },
|
|
|
- grid: {
|
|
|
+ },
|
|
|
+ legend: {
|
|
|
+ data: ['True vs Predicted']
|
|
|
+ },
|
|
|
+ grid: {
|
|
|
left: '3%',
|
|
|
right: '4%',
|
|
|
bottom: '3%',
|
|
|
containLabel: true
|
|
|
- },
|
|
|
- xAxis: {
|
|
|
- type: 'category',
|
|
|
- data: Array.from({length: 27}, (_, i) => i + 1) // 生成 1 到 27 的样本编号
|
|
|
- },
|
|
|
- yAxis: {
|
|
|
+ },
|
|
|
+ xAxis: {
|
|
|
+ name: 'True Values',
|
|
|
type: 'value',
|
|
|
- name: 'ΔpH',
|
|
|
- min: -1.5,
|
|
|
- max: 0.5
|
|
|
- },
|
|
|
- series: [
|
|
|
+ min: min,
|
|
|
+ max: max
|
|
|
+ },
|
|
|
+ yAxis: {
|
|
|
+ name: 'Predicted Values',
|
|
|
+ type: 'value',
|
|
|
+ min: parseFloat(min).toFixed(2),
|
|
|
+ max: parseFloat(max).toFixed(2)
|
|
|
+ },
|
|
|
+ series: [
|
|
|
{
|
|
|
- name: 'ΔpH',
|
|
|
- type: 'boxplot',
|
|
|
- data: [
|
|
|
- // 每个数组代表一个样本的箱型图数据
|
|
|
- // 格式为 [min, Q1, median, Q3, max],可以包含异常值作为单独的数组元素
|
|
|
- [-0.8, -0.6, -0.5, -0.3, 0.0],
|
|
|
- [-0.7, -0.5, -0.4, -0.2, 0.1],
|
|
|
- [-0.9, -0.7, -0.6, -0.4, -0.1],
|
|
|
- [-1.0, -0.8, -0.7, -0.5, -0.3],
|
|
|
- [-1.1, -0.9, -0.8, -0.6, -0.4],
|
|
|
- [-1.2, -1.0, -0.9, -0.7, -0.5],
|
|
|
- [-1.3, -1.1, -1.0, -0.8, -0.6],
|
|
|
- [-1.4, -1.2, -1.1, -0.9, -0.7],
|
|
|
- [-1.5, -1.3, -1.2, -1.0, -0.8],
|
|
|
- [-1.4, -1.2, -1.1, -0.9, -0.7],
|
|
|
- [-1.3, -1.1, -1.0, -0.8, -0.6],
|
|
|
- [-1.2, -1.0, -0.9, -0.7, -0.5],
|
|
|
- [-1.1, -0.9, -0.8, -0.6, -0.4],
|
|
|
- [-1.0, -0.8, -0.7, -0.5, -0.3],
|
|
|
- [-0.9, -0.7, -0.6, -0.4, -0.1],
|
|
|
- [-0.8, -0.6, -0.5, -0.3, 0.0],
|
|
|
- [-0.7, -0.5, -0.4, -0.2, 0.1],
|
|
|
- [-0.6, -0.4, -0.3, -0.1, 0.2],
|
|
|
- [-0.5, -0.3, -0.2, 0.0, 0.3],
|
|
|
- [-0.4, -0.2, -0.1, 0.1, 0.4],
|
|
|
- [-0.3, -0.1, 0.0, 0.2, 0.5],
|
|
|
- [-0.2, 0.0, 0.1, 0.3, 0.6],
|
|
|
- [-0.1, 0.1, 0.2, 0.4, 0.7],
|
|
|
- [0.0, 0.2, -0.3, 0.5, 0.8],
|
|
|
- [-0.1, 0.3, -0.4, 0.6, 0.9],
|
|
|
- [-0.2, 0.4, -0.5, 0.7, 1.0],
|
|
|
- [-0.3, 0.5, -0.6, 0.8, 1.1]
|
|
|
- ],
|
|
|
- tooltip: {
|
|
|
- formatter: function (param) {
|
|
|
- return [
|
|
|
- 'Experiment ' + param.name + ': ',
|
|
|
- 'upper: ' + param.data[5],
|
|
|
- 'Q3: ' + param.data[4],
|
|
|
- 'median: ' + param.data[3],
|
|
|
- 'Q1: ' + param.data[2],
|
|
|
- 'lower: ' + param.data[1]
|
|
|
- ].join(' ');
|
|
|
- }
|
|
|
- }
|
|
|
+ name: 'True vs Predicted',
|
|
|
+ type: 'scatter',
|
|
|
+ data: scatterData,
|
|
|
+ symbolSize: 10,
|
|
|
+ itemStyle: {
|
|
|
+ color: '#1f77b4',
|
|
|
+ opacity: 0.7
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'Trendline',
|
|
|
+ type: 'line',
|
|
|
+ data: [
|
|
|
+ [min, min],
|
|
|
+ [max, max]
|
|
|
+ ],
|
|
|
+ lineStyle: {
|
|
|
+ type: 'dashed',
|
|
|
+ color: '#ff7f0e',
|
|
|
+ width: 2
|
|
|
+ }
|
|
|
}
|
|
|
- ]
|
|
|
+ ]
|
|
|
};
|
|
|
}
|
|
|
+// 反酸模型 最终代 散点图
|
|
|
+function getFinalScatterOption() {
|
|
|
+ /**
|
|
|
+ * 计算数据的最大最小值
|
|
|
+ * @param {Array} data - 散点数据数组
|
|
|
+ * @returns {Object} 包含 xMin, xMax, yMin, yMax 的对象
|
|
|
+ */
|
|
|
+ const calculateDataRange = (data) => {
|
|
|
+ let xValues = data.map(item => item[0]);
|
|
|
+ let yValues = data.map(item => item[1]);
|
|
|
+
|
|
|
+ return {
|
|
|
+ xMin: Math.min(...xValues),
|
|
|
+ xMax: Math.max(...xValues),
|
|
|
+ yMin: Math.min(...yValues),
|
|
|
+ yMax: Math.max(...yValues)
|
|
|
+ };
|
|
|
+ };
|
|
|
+
|
|
|
+ const scatterData = [[-0.003333333333333854, -0.45726666666666654], [-0.1733333333333329, -0.1726333333333331],
|
|
|
+ [-0.6233333333333331, -0.5226666666666667], [-0.7088888888888892, -0.4791888888888889],
|
|
|
+ [-0.3366666666666669, -0.3630666666666673], [-0.8888888888888887, -0.48272222222222183],
|
|
|
+ [-0.5633333333333326, -0.7492444444444444], [-0.7333333333333325, -0.5572666666666672],
|
|
|
+ [-0.3366666666666663, -0.29379999999999984], [-1.176666666666666, -0.8544111111111106],
|
|
|
+ [-0.7122222222222225, -0.4959777777777775], [-0.7699999999999996, -0.6149666666666669]];
|
|
|
+
|
|
|
+ const range = calculateDataRange(scatterData);
|
|
|
+ const padding = 0.1;
|
|
|
+ const xMin = range.xMin - Math.abs(range.xMin * padding);
|
|
|
+ const xMax = range.xMax + Math.abs(range.xMax * padding);
|
|
|
+ const yMin = range.yMin - Math.abs(range.yMin * padding);
|
|
|
+ const yMax = range.yMax + Math.abs(range.yMax * padding);
|
|
|
+ const min = Math.min(xMin, yMin)
|
|
|
+ const max = Math.max(xMax, yMax)
|
|
|
|
|
|
-function getScatterOption() {
|
|
|
return {
|
|
|
- tooltip: {
|
|
|
- trigger: 'axis',
|
|
|
- axisPointer: {
|
|
|
- type: 'cross'
|
|
|
- }
|
|
|
- },
|
|
|
- legend: {
|
|
|
- data: ['True vs Predicted']
|
|
|
- },
|
|
|
- grid: {
|
|
|
- left: '3%',
|
|
|
- right: '4%',
|
|
|
- bottom: '3%',
|
|
|
- containLabel: true
|
|
|
- },
|
|
|
- xAxis: {
|
|
|
- name: 'True Values', // 对应 Python 中的 Ytest
|
|
|
- type: 'value',
|
|
|
- boundaryGap: [0, 0.01]
|
|
|
- },
|
|
|
- yAxis: {
|
|
|
- name: 'Predicted Values', // 对应 Python 中的 y_pred
|
|
|
- type: 'value',
|
|
|
- boundaryGap: [0, 0.01]
|
|
|
- },
|
|
|
- series: [
|
|
|
- {
|
|
|
- name: 'True vs Predicted',
|
|
|
- type: 'scatter',
|
|
|
- data: [
|
|
|
- [-0.003333333333333854, -0.45726666666666654], [-0.1733333333333329, -0.1726333333333331],
|
|
|
- [-0.6233333333333331, -0.5226666666666667], [-0.7088888888888892, -0.4791888888888889],
|
|
|
- [-0.3366666666666669, -0.3630666666666673], [-0.8888888888888887, -0.48272222222222183],
|
|
|
- [-0.5633333333333326, -0.7492444444444444], [-0.7333333333333325, -0.5572666666666672],
|
|
|
- [-0.3366666666666663, -0.29379999999999984], [-1.176666666666666, -0.8544111111111106],
|
|
|
- [-0.7122222222222225, -0.4959777777777775], [-0.7699999999999996, -0.6149666666666669]
|
|
|
- ],
|
|
|
- symbolSize: 10,
|
|
|
- itemStyle: {
|
|
|
-
|
|
|
- }
|
|
|
- },
|
|
|
- {
|
|
|
- name: 'Trendline',
|
|
|
- type: 'line',
|
|
|
- data: [
|
|
|
- // 绘制对角线 y = x (这就是理想情况下 True 和 Predicted 的值相等)
|
|
|
- [-1.2,-1.2], // 最小值
|
|
|
- [-0.0034, -0.0034] // 最大值
|
|
|
- ],
|
|
|
- lineStyle: {
|
|
|
- type: 'dashed',
|
|
|
-
|
|
|
- }
|
|
|
- }
|
|
|
- ]
|
|
|
- };
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'axis',
|
|
|
+ axisPointer: {
|
|
|
+ type: 'cross'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ legend: {
|
|
|
+ data: ['True vs Predicted']
|
|
|
+ },
|
|
|
+ grid: {
|
|
|
+ left: '3%',
|
|
|
+ right: '4%',
|
|
|
+ bottom: '3%',
|
|
|
+ containLabel: true
|
|
|
+ },
|
|
|
+ xAxis: {
|
|
|
+ name: 'True Values',
|
|
|
+ type: 'value',
|
|
|
+ min: min,
|
|
|
+ max: max
|
|
|
+ },
|
|
|
+ yAxis: {
|
|
|
+ name: 'Predicted Values',
|
|
|
+ type: 'value',
|
|
|
+ min: parseFloat(min).toFixed(2),
|
|
|
+ max: parseFloat(max).toFixed(2)
|
|
|
+ },
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ name: 'True vs Predicted',
|
|
|
+ type: 'scatter',
|
|
|
+ data: scatterData,
|
|
|
+ symbolSize: 10,
|
|
|
+ itemStyle: {
|
|
|
+ color: '#1f77b4',
|
|
|
+ opacity: 0.7
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'Trendline',
|
|
|
+ type: 'line',
|
|
|
+ data: [
|
|
|
+ [min, min],
|
|
|
+ [max, max]
|
|
|
+ ],
|
|
|
+ lineStyle: {
|
|
|
+ type: 'dashed',
|
|
|
+ color: '#ff7f0e',
|
|
|
+ width: 2
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ };
|
|
|
}
|
|
|
|
|
|
function getLineOption() {
|
|
@@ -293,37 +363,3 @@ function getLineOption() {
|
|
|
]
|
|
|
};
|
|
|
}
|
|
|
-
|
|
|
-function getPieOption() {
|
|
|
- return {
|
|
|
- tooltip: {
|
|
|
- trigger: 'item',
|
|
|
- formatter: '{a} <br/>{b} : {c} ({d}%)'
|
|
|
- },
|
|
|
- legend: {
|
|
|
- orient: 'vertical',
|
|
|
- left: 'left',
|
|
|
- data: ['示例1', '示例2', '示例3']
|
|
|
- },
|
|
|
- series: [
|
|
|
- {
|
|
|
- name: '访问来源',
|
|
|
- type: 'pie',
|
|
|
- radius: '55%',
|
|
|
- center: ['50%', '60%'],
|
|
|
- data: [
|
|
|
- { value: 335, name: '示例1' },
|
|
|
- { value: 310, name: '示例2' },
|
|
|
- { value: 234, name: '示例3' },
|
|
|
- ],
|
|
|
- emphasis: {
|
|
|
- itemStyle: {
|
|
|
- shadowBlur: 10,
|
|
|
- shadowOffsetX: 0,
|
|
|
- shadowColor: 'rgba(0, 0, 0, 0.5)'
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- ]
|
|
|
- };
|
|
|
-}
|