cormort commited on
Commit
1f9e5c3
·
verified ·
1 Parent(s): 3ef0667

Update static/index.html

Browse files
Files changed (1) hide show
  1. static/index.html +67 -15
static/index.html CHANGED
@@ -1097,21 +1097,73 @@ function renderChartPage(){
1097
  const info=document.createElement('span');info.className='page-info';info.textContent=`第${currentChartPage+1}/${totalPgs}頁,共${total}種方法`;pag.appendChild(info);
1098
  }
1099
  }
1100
- function renderSingleChart(canvas,hist,predVal,nextYear,methodName,color){
1101
- const labels=[...hist.map(d=>d.year)];const hv=[...hist.map(d=>d.value)];const hasP=!isNaN(predVal);
1102
- const allLabels=hasP?[...labels,nextYear]:[...labels];
1103
- const barData=hasP?[...hv,null]:[...hv];
1104
- const predBar=new Array(allLabels.length).fill(null);if(hasP)predBar[predBar.length-1]=predVal;
1105
- const lineData=[...hv];if(hasP)lineData.push(predVal);
1106
- return new Chart(canvas,{
1107
- data:{labels:allLabels,datasets:[
1108
- {type:'bar',label:'歷史數值',data:barData,backgroundColor:color.bar,borderColor:color.line,borderWidth:1,order:2},
1109
- {type:'bar',label:`預測值 (${methodName})`,data:predBar,backgroundColor:'rgba(230,180,80,0.5)',borderColor:'rgba(230,180,80,0.9)',borderWidth:2,order:2},
1110
- {type:'line',label:'趨勢線',data:lineData,borderColor:color.line,backgroundColor:color.bar.replace('.4','.08'),borderWidth:2,fill:true,tension:.3,
1111
- pointRadius:allLabels.map((_,i)=>i===allLabels.length-1&&hasP?7:4),
1112
- pointBackgroundColor:allLabels.map((_,i)=>i===allLabels.length-1&&hasP?'rgba(230,180,80,1)':color.line),order:1}
1113
- ]},
1114
- options:chartOptions()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1115
  });
1116
  }
1117
  function chartOptions(){
 
1097
  const info=document.createElement('span');info.className='page-info';info.textContent=`第${currentChartPage+1}/${totalPgs}頁,共${total}種方法`;pag.appendChild(info);
1098
  }
1099
  }
1100
+ function renderSingleChart(canvas, hist, predVal, nextYear, methodName, color) {
1101
+ // 取得使用者選擇的圖形類型,預設為複合圖
1102
+ const chartStyle = document.getElementById('chartStyleSelect').value || 'mixed';
1103
+
1104
+ const labels = [...hist.map(d=>d.year)];
1105
+ const hv = [...hist.map(d=>d.value)];
1106
+ const hasP = !isNaN(predVal);
1107
+ const allLabels = hasP ? [...labels, nextYear] : [...labels];
1108
+
1109
+ // 【複合圖專用】將歷史與預測分離成不同長條
1110
+ const barData = hasP ? [...hv, null] : [...hv];
1111
+ const predBar = new Array(allLabels.length).fill(null);
1112
+ if(hasP) predBar[predBar.length-1] = predVal;
1113
+
1114
+ // 【連續圖專用】將歷史與預測接在一起
1115
+ const lineData = [...hv];
1116
+ if(hasP) lineData.push(predVal);
1117
+
1118
+ // 動態判定最後一個預測點的顏色與大小
1119
+ const pointColors = allLabels.map((_,i) => i===allLabels.length-1 && hasP ? 'rgba(230,180,80,1)' : color.line);
1120
+ const bgColors = allLabels.map((_,i) => i===allLabels.length-1 && hasP ? 'rgba(230,180,80,0.5)' : color.bar);
1121
+ const borderColors = allLabels.map((_,i) => i===allLabels.length-1 && hasP ? 'rgba(230,180,80,0.9)' : color.line);
1122
+ const pointRadii = allLabels.map((_,i) => i===allLabels.length-1 && hasP ? 7 : 4);
1123
+
1124
+ let datasets = [];
1125
+
1126
+ // 根據下拉選單決定要丟給 Chart.js 什麼資料結構
1127
+ if (chartStyle === 'mixed') {
1128
+ datasets = [
1129
+ {type:'bar', label:'歷史數值', data:barData, backgroundColor:color.bar, borderColor:color.line, borderWidth:1, order:2},
1130
+ {type:'bar', label:`預測值 (${methodName})`, data:predBar, backgroundColor:'rgba(230,180,80,0.5)', borderColor:'rgba(230,180,80,0.9)', borderWidth:2, order:2},
1131
+ {type:'line', label:'趨勢線', data:lineData, borderColor:color.line, backgroundColor:color.bar.replace('.4','.08'), borderWidth:2, fill:true, tension:0.3,
1132
+ pointRadius:pointRadii, pointBackgroundColor:pointColors, order:1}
1133
+ ];
1134
+ } else if (chartStyle === 'line' || chartStyle === 'area') {
1135
+ datasets = [{
1136
+ type: 'line',
1137
+ label: '數值',
1138
+ data: lineData,
1139
+ borderColor: color.line,
1140
+ backgroundColor: color.bar.replace('.4', chartStyle === 'area' ? '.2' : '.0'), // 面積圖調整透明度
1141
+ borderWidth: 2,
1142
+ fill: chartStyle === 'area',
1143
+ tension: 0.3,
1144
+ pointRadius: pointRadii,
1145
+ pointBackgroundColor: pointColors,
1146
+ pointBorderColor: pointColors,
1147
+ segment: {
1148
+ // ★ 魔法在這裡:讓最後一段連接預測值的線段變成金色與虛線
1149
+ borderColor: ctx => ctx.p0DataIndex === allLabels.length - 2 ? 'rgba(230,180,80,1)' : color.line,
1150
+ borderDash: ctx => ctx.p0DataIndex === allLabels.length - 2 ? [5, 5] : undefined
1151
+ }
1152
+ }];
1153
+ } else if (chartStyle === 'bar') {
1154
+ datasets = [{
1155
+ type: 'bar',
1156
+ label: '數值',
1157
+ data: lineData,
1158
+ backgroundColor: bgColors,
1159
+ borderColor: borderColors,
1160
+ borderWidth: 1
1161
+ }];
1162
+ }
1163
+
1164
+ return new Chart(canvas, {
1165
+ data: { labels: allLabels, datasets: datasets },
1166
+ options: chartOptions()
1167
  });
1168
  }
1169
  function chartOptions(){