text-to-chart.js 53 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649
  1. console.log('text-to-chart');
  2. Chart.register(ChartDataLabels);
  3. var inputField = document.getElementById("keyword_data");
  4. var sendButton = document.getElementById("send_data");
  5. var canvasPng = document.getElementById("textToChart");
  6. var img_box = document.getElementById("img_box");
  7. var sidebar = document.getElementById('style_setting');
  8. var input_text_value;
  9. var chartType = 'line';
  10. var unit = '';
  11. var myChart = null;
  12. var chartColor = '#912B2B';
  13. var displayXaxes = true;
  14. var ctx;
  15. var chartlabels;
  16. var chartdata;
  17. var XfontSizeValue = 18;
  18. var YfontSizeValue = 18;
  19. var TitlefontSizeValue = 32;
  20. var chart_bgimg_url = "url(./img/bg.webp)";
  21. var vocab = [];
  22. var chartDiv = document.getElementById('chartdiv');
  23. document.addEventListener('DOMContentLoaded', function () {
  24. axios.get("https://cmm.ai:8080/vocab")
  25. .then(response => {
  26. // apiHideLoading();
  27. console.log(response);
  28. vocab = response.data;
  29. })
  30. .catch(error => {
  31. console.error('發生錯誤:', error);
  32. });
  33. });
  34. inputField.addEventListener('click', function () {
  35. // 確保輸入框處於焦點狀態
  36. inputField.focus();
  37. // 在控制台中顯示焦點狀態
  38. console.log('Input field focused');
  39. });
  40. document.addEventListener('DOMContentLoaded', function () {
  41. // const input = document.getElementById('stockInput');
  42. const suggestions = document.getElementById('suggestions');
  43. inputField.addEventListener('input', function () {
  44. const query = this.value.trim();
  45. suggestions.innerHTML = ''; // 清空之前的建議
  46. console.log('query', query);
  47. if (query) {
  48. // const filteredVocab = vocab.filter(item => item.toLowerCase().includes(query));
  49. const queryTerms = query.split(/\s+/); // 分割輸入的內容
  50. const lastQueryTerm = queryTerms[queryTerms.length - 1];
  51. const filteredVocab = vocab.filter(item => {
  52. // 對每個分割後的單詞進行匹配,只要其中有一個匹配成功就返回 true
  53. return item.toLowerCase().includes(lastQueryTerm.toLowerCase());
  54. });
  55. if (filteredVocab.length > 0) {
  56. suggestions.style.border = '1px solid #ccc';
  57. suggestions.style.display = 'block'; // 顯示建議容器
  58. } else {
  59. suggestions.style.border = 'none';
  60. suggestions.style.display = 'none'; // 隱藏建議容器
  61. }
  62. console.log(queryTerms[queryTerms.length - 1])
  63. filteredVocab.forEach(item => {
  64. const div = document.createElement('div');
  65. div.classList.add('autocomplete-suggestion');
  66. div.textContent = item;
  67. // div.addEventListener('click', function () {
  68. // inputField.value = item;
  69. // suggestions.innerHTML = ''; // 清空建議
  70. // suggestions.style.border = 'none';
  71. // suggestions.style.display = 'none'; // 隱藏建議容器
  72. // });
  73. console.log('queryTerms', queryTerms);
  74. // console.log('filteredVocab', filteredVocab);
  75. div.addEventListener('click', function () {
  76. queryTerms.forEach((term, index) => {
  77. const regex = new RegExp(term, 'gi');
  78. const match = regex.exec(inputField.value);
  79. // console.log(queryTerms[queryTerms.length - 1]);
  80. // console.log(filteredVocab, queryTerms[queryTerms.length - 1])
  81. if (index === queryTerms.length - 1) {
  82. if (match) {
  83. var start = match.index;
  84. var end = start + match[0].length;
  85. console.log(start, end)
  86. const textBefore = inputField.value.substring(0, start);
  87. const textAfter = inputField.value.substring(end, inputField.value.length);
  88. console.log('start', start, 'end', end, 'textBefore', textBefore, 'textAfter', textAfter);
  89. // 捕獲被選中的部分並替換它
  90. const selectedText = inputField.value.substring(start, end);
  91. console.log('selectedText', selectedText);
  92. const newText = textBefore + item + textAfter.replace(selectedText, '');
  93. console.log('newText', newText);
  94. inputField.value = newText;
  95. // inputField.value = textBefore + item.replace(selectedText, '') + textAfter;
  96. suggestions.innerHTML = ''; // 清空建議
  97. suggestions.style.border = 'none';
  98. }
  99. }
  100. });
  101. // const start = inputField.selectionStart;
  102. // const end = inputField.selectionEnd;
  103. });
  104. suggestions.appendChild(div);
  105. });
  106. } else {
  107. suggestions.style.border = 'none';
  108. suggestions.style.display = 'none'; // 隱藏建議容器
  109. }
  110. });
  111. });
  112. // 監聽輸入框的鍵盤事件
  113. // document.getElementById("keyword_data").addEventListener("keyup", function (event) {
  114. // // 判斷是否按下 Enter 鍵 (key code: 13)
  115. // if (event.keyCode === 13) {
  116. // // 觸發送出按鈕的點擊事件
  117. // document.getElementById("send_data").click();
  118. // }
  119. // });
  120. // 定義按鈕點擊事件處理函數
  121. function sendButtonClickHandler() {
  122. console.log(inputField.value);
  123. var input_text_value = inputField.value;
  124. $('#chartdiv').hide();
  125. sidebar.classList.remove('show');
  126. sidebar.classList.add('hidden');
  127. // 在這裡添加你希望在按下按鈕時執行的其他代碼
  128. get_data(input_text_value);
  129. }
  130. sendButton.addEventListener("click", sendButtonClickHandler);
  131. // sendButton.addEventListener("click", function () {
  132. // console.log(inputField.value);
  133. // input_text_value = inputField.value;
  134. // // if (myChart) {
  135. // // console.log('已存在')
  136. // // data = [];
  137. // // labels = [];
  138. // // myChart.removePlugin(Chart.pluginService.getPlugin('afterDraw'));
  139. // // myChart.destroy();
  140. // // }
  141. // get_data(input_text_value);
  142. // });
  143. var lastKeyPressTime = 0;
  144. var enterCount = 0;
  145. var ENTER_THRESHOLD = 500; // 設定連續按下 Enter 的時間閾值(毫秒)
  146. inputField.addEventListener("keyup", function (event) {
  147. // 判斷是否按下 Enter 鍵 (key code: 13)
  148. if (event.key === "Enter") {
  149. var currentTime = new Date().getTime();
  150. // 計算與上一次按鍵按下時間的差值
  151. var timeDiff = currentTime - lastKeyPressTime;
  152. lastKeyPressTime = currentTime;
  153. // 如果兩次 Enter 鍵按下的時間差小於閾值,則增加計數器
  154. if (timeDiff <= ENTER_THRESHOLD) {
  155. enterCount++;
  156. // 如果計數器為2,則觸發 API 請求並重置計數器
  157. if (enterCount === 2) {
  158. sendButtonClickHandler();
  159. enterCount = 0;
  160. }
  161. } else {
  162. // 如果時間差大於閾值,則重置計數器
  163. enterCount = 0;
  164. }
  165. } else {
  166. // 如果按下的不是 Enter 鍵,則重置計數器
  167. enterCount = 0;
  168. }
  169. });
  170. function number_format(number, decimals, dec_point, thousands_sep) {
  171. // * example: number_format(1234.56, 2, ',', ' ');
  172. // * return: '1 234,56'
  173. number = (number + '').replace(',', '').replace(' ', '');
  174. var n = !isFinite(+number) ? 0 : +number,
  175. prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
  176. sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,
  177. dec = (typeof dec_point === 'undefined') ? '.' : dec_point,
  178. s = '',
  179. toFixedFix = function (n, prec) {
  180. var k = Math.pow(10, prec);
  181. return '' + Math.round(n * k) / k;
  182. };
  183. // Fix for IE parseFloat(0.55).toFixed(0) = 0;
  184. s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.');
  185. if (s[0].length > 3) {
  186. s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
  187. }
  188. if ((s[1] || '').length < prec) {
  189. s[1] = s[1] || '';
  190. s[1] += new Array(prec - s[1].length + 1).join('0');
  191. }
  192. return s.join(dec);
  193. }
  194. var labels = [];
  195. var data = [];
  196. function apiLoading() {
  197. document.getElementById('chartDataLoading').style.display = 'block';
  198. }
  199. function apiHideLoading() {
  200. document.getElementById('chartDataLoading').style.display = 'none';
  201. }
  202. const DISPLAY = true;
  203. const BORDER = true;
  204. const CHART_AREA = true;
  205. const TICKS = true;
  206. var labels = [];
  207. var data = [];
  208. var dataArray;
  209. function generateChart(dataArray) {
  210. // 创建一个空数组来存储 labels 和 data
  211. console.log(dataArray)
  212. // 遍历数据数组
  213. for (var i = 0; i < dataArray.length; i++) {
  214. var item = dataArray[i];
  215. // 遍历当前项的属性
  216. for (var key in item) {
  217. // 如果属性名不在 labels 数组中,并且属性值不是对象,则将属性名添加到 labels 数组中
  218. if (typeof item[key] === 'string') {
  219. labels.push(item[key]);
  220. }
  221. // 如果属性值是数值类型,则将其添加到 data 数组中
  222. if (typeof item[key] === 'number') {
  223. data.push(item[key]);
  224. }
  225. }
  226. }
  227. console.log(data);
  228. if (myChart) {
  229. console.log('已存在')
  230. myChart.destroy();
  231. }
  232. if (chartType === "doughnut") {
  233. // createChartDoughnut(chartType, data, labels);
  234. // createChartDoughnut2(data, labels)
  235. } else {
  236. createChart(chartType, data, labels);
  237. }
  238. // console.log(data);
  239. console.log(labels);
  240. }
  241. var amChartInstance;
  242. function extractAndGenerateChart(dataArray) {
  243. for (var i = 0; i < dataArray.length; i++) {
  244. var item = dataArray[i];
  245. // 遍历当前项的属性
  246. for (var key in item) {
  247. // 如果属性名不在 labels 数组中,并且属性值不是对象,则将属性名添加到 labels 数组中
  248. if (typeof item[key] === 'string') {
  249. labels.push(item[key]);
  250. }
  251. // 如果属性值是数值类型,则将其添加到 data 数组中
  252. if (typeof item[key] === 'number') {
  253. data.push(item[key]);
  254. }
  255. }
  256. }
  257. // console.log('key', key);
  258. generateBarChart(key, dataArray);
  259. }
  260. // 圓餅圖
  261. function generatePieChart(dataArray) {
  262. $('#chartdiv').show();
  263. bgImgelement.style.backgroundImage = chart_bgimg_url;
  264. // chartDiv.style.width = "100%"
  265. chartWhitelement.style.background = "rgba(255,255,255,0.5)"
  266. // Themes begin
  267. am4core.useTheme(am4themes_animated);
  268. // Themes end
  269. // Create chart instance
  270. var chart = am4core.create("chartdiv", am4charts.PieChart);
  271. chart.data = dataArray;
  272. chart.innerRadius = am4core.percent(50);
  273. // Add and configure Series
  274. var pieSeries = chart.series.push(new am4charts.PieSeries());
  275. pieSeries.dataFields.value = "y";
  276. pieSeries.dataFields.category = "x";
  277. pieSeries.slices.template.stroke = am4core.color("#fff");
  278. pieSeries.slices.template.strokeWidth = 2;
  279. pieSeries.slices.template.strokeOpacity = 1;
  280. // Configure labels
  281. pieSeries.labels.template.wrap = true;
  282. pieSeries.labels.template.maxWidth = 100;
  283. pieSeries.labels.template.truncate = false;
  284. pieSeries.labels.template.fontSize = 14;
  285. // Configure label text to wrap and show percentages
  286. pieSeries.labels.template.adapter.add("textOutput", function (text, target) {
  287. if (target.dataItem && target.dataItem.values.value.percent) {
  288. return "[font-size: 14px]" + target.dataItem.category + ": " + target.dataItem.values.value.percent.toFixed(1) + "%";
  289. }
  290. return text;
  291. });
  292. pieSeries.colors.list = [
  293. am4core.color('rgb(171, 51, 49)'),
  294. am4core.color('rgb(34, 83, 149)'),
  295. am4core.color('rgb(79, 148, 65)'),
  296. am4core.color('rgb(217, 195, 105)'),
  297. am4core.color('rgb(142, 124, 180)'),
  298. am4core.color('rgb(211, 183, 144)'),
  299. am4core.color('rgb(83, 84, 84)'),
  300. am4core.color('rgb(229, 147, 152)')
  301. ];
  302. // Ensure labels have background
  303. // pieSeries.labels.template.background.fillOpacity = 1;
  304. console.log(pieSeries.labels.template)
  305. // Set label background color to match corresponding slice color
  306. pieSeries.labels.template.adapter.add("background.fill", function (fill, target) {
  307. return target.dataItem.slice.fill;
  308. });
  309. // This creates initial animation
  310. pieSeries.hiddenState.properties.opacity = 1;
  311. pieSeries.hiddenState.properties.endAngle = -90;
  312. pieSeries.hiddenState.properties.startAngle = -90;
  313. // console.log('調位置')
  314. downloadButton.style.display = "inline-block";
  315. }
  316. // 柱狀圖
  317. function generateBarChart(key, dataArray) {
  318. $('#chartdiv').show();
  319. // var colorEven = document.getElementById('colorEven').value;
  320. // var colorOdd = document.getElementById('colorOdd').value;
  321. chartDiv.style.fontFamily = "Arial, sans-serif";
  322. chartDiv.style.fontWeight = "900";
  323. bgImgelement.style.backgroundImage = chart_bgimg_url;
  324. chartWhitelement.style.background = "rgba(255,255,255,0.5)"
  325. console.log('labelDependent', labelDependent);
  326. // Themes begin
  327. am4core.useTheme(am4themes_animated);
  328. // Themes end
  329. // Create chart instance
  330. var chart = am4core.create("chartdiv", am4charts.XYChart3D);
  331. console.log(dataArray);
  332. chart.data = dataArray;
  333. chart.angle = 30; // 圖表角度
  334. chart.depth = 25; // 圖表深度
  335. let categoryAxis = chart.xAxes.push(new am4charts.CategoryAxis());
  336. categoryAxis.dataFields.category = "x";
  337. categoryAxis.renderer.labels.template.rotation = 0;
  338. categoryAxis.renderer.labels.template.hideOversized = false;
  339. categoryAxis.renderer.minGridDistance = 20; // 間距
  340. // categoryAxis.renderer.labels.template.horizontalCenter = "left";
  341. // categoryAxis.renderer.labels.template.verticalCenter = "middle";
  342. // categoryAxis.tooltip.label.rotation = 90;
  343. // categoryAxis.tooltip.label.horizontalCenter = "right";
  344. // categoryAxis.tooltip.label.verticalCenter = "middle";
  345. // label 換行
  346. let label = categoryAxis.renderer.labels.template;
  347. label.wrap = true;
  348. label.maxWidth = 100;
  349. categoryAxis.renderer.cellEndLocation = 0.5; // 減少值可以增加間距
  350. let valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
  351. valueAxis.title.text = labelDependent; // Y軸
  352. valueAxis.title.fontWeight = "bold";
  353. // Create series
  354. var series = chart.series.push(new am4charts.ColumnSeries3D());
  355. series.dataFields.valueY = 'y';
  356. series.dataFields.categoryX = "x";
  357. series.name = "y";
  358. series.tooltipText = "{categoryX}: [bold]{valueY}[/]";
  359. series.columns.template.fillOpacity = .8;
  360. let columnTemplate = series.columns.template;
  361. columnTemplate.strokeWidth = 2;
  362. columnTemplate.strokeOpacity = 1;
  363. columnTemplate.stroke = am4core.color("#FFFFFF");
  364. // columnTemplate.adapter.add("fill", function (fill, target) {
  365. // return chart.colors.getIndex(target.dataItem.index);
  366. // })
  367. // 設置基數和偶數顏色
  368. columnTemplate.adapter.add("fill", function (fill, target) {
  369. return target.dataItem.index % 2 === 0 ? am4core.color("#288D97") : am4core.color("#427D7E");
  370. });
  371. columnTemplate.adapter.add("stroke", function (stroke, target) {
  372. return chart.colors.getIndex(target.dataItem.index);
  373. })
  374. // // 加上白色線條
  375. // series.columns.template.events.on("validated", function (event) {
  376. // let column = event.target;
  377. // let whiteLine = column.createChild(am4core.Line);
  378. // whiteLine.stroke = am4core.color("#ffffff");
  379. // whiteLine.strokeWidth = 1.3; // 線條寬度
  380. // whiteLine.strokeOpacity = 0.5;// 透明度
  381. // whiteLine.x1 = column.pixelWidth / 1;
  382. // whiteLine.y1 = 0;
  383. // whiteLine.x2 = column.pixelWidth / 1;
  384. // whiteLine.y2 = column.pixelHeight;
  385. // });
  386. chart.cursor = new am4charts.XYCursor();
  387. chart.cursor.lineX.strokeOpacity = 0;
  388. chart.cursor.lineY.strokeOpacity = 0;
  389. categoryAxis.renderer.grid.template.strokeOpacity = 0; // 隱藏 X 軸
  390. // valueAxis.renderer.grid.template.strokeOpacity = 0; // 隱藏 Y 軸
  391. // valueAxis.renderer.line.strokeOpacity = 0;
  392. // LineSeries 底部線條
  393. var lineSeries = chart.series.push(new am4charts.LineSeries());
  394. lineSeries.dataFields.valueY = "bottom";
  395. lineSeries.dataFields.categoryX = "0";
  396. lineSeries.stroke = am4core.color("#FFFFFF")
  397. lineSeries.strokeWidth = 2;
  398. lineSeries.strokeOpacity = 1
  399. var bottomData = [];
  400. for (var i = 0; i < dataArray.length; i++) {
  401. bottomData.push({ "x": dataArray[i].x, "bottom": 0 });
  402. }
  403. lineSeries.data = bottomData;
  404. downloadButton.style.display = "inline-block";
  405. // 底部線條
  406. // let rectElements = document.querySelectorAll("rect");
  407. // // let widthValue = 0;
  408. // let fifthRectElement = rectElements[3];
  409. // // fifthRectElement.style.position = "relative";
  410. // setTimeout(() => {
  411. // let width = fifthRectElement.getAttribute("width");
  412. // // widthValue = parseFloat(width);
  413. // console.log('rectElements', rectElements);
  414. // console.log('fifthRectElement', fifthRectElement);
  415. // console.log('width', width);
  416. // let line = document.createElement("div");
  417. // line.style.position = "absolute";
  418. // line.style.bottom = "162px";
  419. // line.style.right = "40px";
  420. // line.style.width = `${parseFloat(width)}px`;
  421. // line.style.height = "2px";
  422. // line.style.backgroundColor = "#000000";
  423. // document.getElementById("chartdiv").appendChild(line);
  424. // }, 10)
  425. // end am4core.ready()
  426. }
  427. var downloadButton = document.getElementById("downloadButton");
  428. // downloadButton.style.display = 'none';
  429. // 添加點擊事件監聽器
  430. downloadButton.addEventListener('click', function () {
  431. setTimeout(function () {
  432. html2canvas(document.getElementById('data_chart_box')).then(function (canvas) {
  433. // // 獲取圖片資料 URL
  434. // var imageData = canvasPng.toDataURL("image/png");
  435. // // 創建下載連結
  436. // var link = document.createElement('a');
  437. // link.download = 'chart.png'; // 下載的檔案名稱
  438. // link.href = imageData; // 圖片資料 URL
  439. // // 模擬點擊下載連結
  440. // link.click();
  441. // 創建一個&lt;a&gt;元素
  442. const link = document.createElement('a');
  443. // 將 Canvas 轉換為 Data URL
  444. link.href = canvas.toDataURL('image/png');
  445. // 設置下載文件名
  446. link.download = 'chart.png';
  447. // 模擬點擊下載
  448. link.click();
  449. });
  450. }, 1000); // 等待 1 秒钟
  451. });
  452. var pieChartColors = [
  453. 'rgb(171, 51, 49)',
  454. 'rgb(34, 83, 149)',
  455. 'rgb(79, 148, 65)',
  456. 'rgb(217, 195, 105)',
  457. 'rgb(142, 124, 180)',
  458. 'rgb(211, 183, 144)',
  459. 'rgb(83, 84, 84)',
  460. 'rgb(229, 147, 152)'
  461. ];
  462. function createChartDoughnut2(data, labels) {
  463. const chartData = {
  464. type: 'outlabeledPie',
  465. data: {
  466. labels: labels,
  467. datasets: [
  468. {
  469. data: data,
  470. borderWidth: borderWidthValue,
  471. fill: false,
  472. backgroundColor: pieChartColors,
  473. },
  474. ],
  475. },
  476. options: {
  477. plugins: {
  478. legend: false,
  479. outlabels: {
  480. text: '%l %p',
  481. color: 'white',
  482. stretch: 35,
  483. font: {
  484. resizable: true,
  485. family: 'Arial',
  486. size: 48,
  487. weight: 'bold',
  488. style: 'italic',
  489. },
  490. },
  491. },
  492. },
  493. };
  494. const devicePixelRatio = 4;
  495. var chartUrl = `https://quickchart.io/chart?c=${encodeURIComponent(JSON.stringify(chartData))}&devicePixelRatio=${devicePixelRatio}&f=png&fontsize=20`;
  496. // 获取目标 div 元素
  497. const targetDiv = document.getElementById('data_chartJs_box');
  498. // 创建一个 img 元素来显示图表
  499. const chartImg = document.createElement('img');
  500. chartImg.src = chartUrl;
  501. chartImg.classList.add('outlabeled_img');
  502. // 清空目标 div 元素
  503. targetDiv.innerHTML = '';
  504. // 将图表 img 元素插入到目标 div 中
  505. targetDiv.appendChild(chartImg);
  506. console.log(chart_bgimg_url);
  507. bgImgelement.style.backgroundImage = chart_bgimg_url;
  508. chartWhitelement.style.background = "rgba(255,255,255,0.5)"
  509. }
  510. // 版型二源餅圖
  511. // // 创建 Chart.js 图表
  512. function createChartDoughnut(chartType, data, labels) {
  513. $('#textToChart').show();
  514. canvasPng.style.maxWidth = '450px';
  515. canvasPng.style.maxHeight = '450px';
  516. var windowWidth = window.innerWidth || document.documentElement.clientWidth;
  517. var canvasWidth = Math.min(500, windowWidth); // 限制最大宽度为 500px
  518. canvasPng.style.width = canvasWidth + 'px'; // 设置 canvas 宽度
  519. canvasPng.style.marginLeft = 'auto'; // 左外边距自动计算
  520. canvasPng.style.marginRight = 'auto'; // 右外边距自动计算
  521. var ctx = document.getElementById("textToChart").getContext('2d');
  522. myChart = new Chart(ctx, {
  523. type: chartType,
  524. data: {
  525. labels: labels,
  526. datasets: [{
  527. strokeColor: "rgba(220,220,220,1)",
  528. StrokeWidth: 5,
  529. data: data,
  530. borderWidth: borderWidthValue,
  531. pointRadius: 0,
  532. pointBorderColor: '#fff',
  533. pointBorderWidth: 3,
  534. pointHoverRadius: 0,
  535. fill: false,
  536. backgroundColor: pieChartColors,
  537. // barPercentage: 0.5,
  538. // categoryPercentage: 0.5
  539. }]
  540. },
  541. options: {
  542. // responsive: true, // 啟用響應式
  543. maintainAspectRatio: true,
  544. responsive: true,
  545. aspectRatio: 1,
  546. plugins: {
  547. legend: {
  548. display: false,
  549. },
  550. datalabels: {
  551. color: '#fff', // 数据标签的颜色
  552. anchor: 'end', // 数据标签的位置
  553. align: 'start', // 数据标签的对齐方式
  554. font: {
  555. size: 14, // 数据标签的字体大小
  556. },
  557. }
  558. },
  559. scales: {
  560. x: {
  561. display: false, // 显示 x 轴
  562. grid: {
  563. display: false,
  564. lineWidth: 5,
  565. color: '#584B3D'
  566. },
  567. ticks: {
  568. textStrokeColor: '#fff',
  569. textStrokeWidth: 5,
  570. font: {
  571. display: false,
  572. family: 'Arial', // 设置字体
  573. size: XfontSizeValue, // 设置字体大小
  574. weight: 'bold', // 设置字体粗细
  575. fontColor: 'rgba(255,255,255,0.8)', // X-axis font color
  576. shadowColor: 'rgba(0, 0, 0, 0.5)', // Shadow color
  577. shadowBlur: 10, // Shadow blur level
  578. shadowOffsetX: 5, // Horizontal shadow offset
  579. shadowOffsetY: 5
  580. },
  581. },
  582. },
  583. y: {
  584. display: false,
  585. beginAtZero: false,
  586. grid: {
  587. display: false,
  588. lineWidth: 5,
  589. color: '#584B3D'
  590. },
  591. ticks: {
  592. textStrokeColor: '#fff',
  593. textStrokeWidth: 5,
  594. font: {
  595. family: 'Arial', // 設置字體
  596. size: XfontSizeValue, // 設置字體大小
  597. weight: 'bold', // 設置字體粗細
  598. color: 'rgba(255,255,255,0.8)', // Y-axis 字體顏色
  599. shadowColor: 'rgba(0, 0, 0, 0.5)', // 陰影顏色
  600. shadowBlur: 10, // 陰影模糊級別
  601. shadowOffsetX: 5, // 水平陰影偏移
  602. shadowOffsetY: 5 // 垂直陰影偏移
  603. },
  604. }
  605. }
  606. },
  607. layout: {
  608. padding: {
  609. left: 50, // 调整图表左边距
  610. right: 50, // 调整图表右边距
  611. top: 10,
  612. bottom: 10,
  613. }
  614. },
  615. },
  616. });
  617. console.log(chart_bgimg_url);
  618. bgImgelement.style.backgroundImage = chart_bgimg_url;
  619. chartWhitelement.style.background = "rgba(255,255,255,0.5)"
  620. }
  621. var chartJsBox = document.getElementById('data_chartJs_box');
  622. function createTable(dataArray, unit, Label_dependent_variable, Label_independent_variable,) {
  623. $('#chartdiv').hide();
  624. $('#textToChart').hide();
  625. var table = document.createElement('table');
  626. table.classList.add('table', 'table_template', 'dynamic-table'); // 添加 Bootstrap 的 table 样式,如果你在使用 Bootstrap
  627. // 创建表头
  628. var thead = table.createTHead();
  629. var headerRow = thead.insertRow();
  630. // Object.keys(dataArray[0]).forEach(function (key) {
  631. // var header = headerRow.insertCell();
  632. // header.textContent = key;
  633. // });
  634. var yearHeader = headerRow.insertCell();
  635. yearHeader.textContent = Label_independent_variable;
  636. var avgPriceHeader = headerRow.insertCell();
  637. avgPriceHeader.textContent = Label_dependent_variable;
  638. // 创建表格主体
  639. var tbody = table.createTBody();
  640. dataArray.forEach(function (item) {
  641. console.log(item)
  642. var row = tbody.insertRow();
  643. // var cell1 = row.insertCell();
  644. // cell1.textContent = item.year;
  645. // cell1.classList.add('year-class'); // 为年份单元格添加类
  646. // var cell2 = row.insertCell();
  647. Object.keys(item).forEach(function (key, index) {
  648. var cell = row.insertCell();
  649. if (index === 0) { // If it's the first cell, add 'year-class'
  650. cell.textContent = item[key];
  651. cell.classList.add('year-class');
  652. } else { // Otherwise, add 'average-class'
  653. if (key === 'Average_Close') {
  654. cell.textContent = item[key].toFixed(2) + unit;
  655. } else {
  656. // cell.textContent = item[key];
  657. cell.textContent = item[key].toFixed(2) + unit;
  658. }
  659. cell.classList.add('average-class');
  660. }
  661. });
  662. // console.log(item.avg_price.toFixed(2))
  663. // cell.textContent = item[key].toFixed(2) + unit;
  664. // cell2.classList.add('average-class'); // 为年份单元格添加类
  665. });
  666. // 获取包含表格的 div 元素
  667. bgImgelement.style.backgroundImage = chart_bgimg_url;
  668. img_box.style.bottom = '60px';
  669. img_box.style.right = '5px';
  670. document.getElementById('img_box_url').style.width = "180px";
  671. // chartWhitelement.style.background = "rgba(255,255,255,0.5)"
  672. // 将表格添加到指定的 div 元素中
  673. chartJsBox.appendChild(table);
  674. }
  675. // 版型一折線圖
  676. // // 创建 Chart.js 图表
  677. function createChart(chartType, data, labels) {
  678. $('#textToChart').show();
  679. canvasPng.style.maxWidth = '';
  680. canvasPng.style.maxHeight = '';
  681. ctx = document.getElementById("textToChart");
  682. myChart = new Chart(ctx, {
  683. type: chartType,
  684. data: {
  685. labels: labels,
  686. datasets: [{
  687. strokeColor: "rgba(220,220,220,1)",
  688. StrokeWidth: 5,
  689. data: data,
  690. borderWidth: borderWidthValue,
  691. pointRadius: 0,
  692. pointBorderColor: '#fff',
  693. pointBorderWidth: 3,
  694. pointHoverRadius: 0,
  695. fill: false,
  696. backgroundColor: chartColor,
  697. borderColor: chartColor,
  698. // barPercentage: 0.5,
  699. // categoryPercentage: 0.5
  700. }]
  701. },
  702. options: {
  703. // responsive: true, // 啟用響應式
  704. maintainAspectRatio: false,
  705. plugins: {
  706. chart3d: {
  707. enabled: true, // 啟用 3D 插件
  708. alpha: 25, // 圖表繞 x 軸的旋轉角度
  709. beta: 25, // 圖表繞 y 軸的旋轉角度
  710. depth: 15 // 圖表的深度
  711. },
  712. // datalabels: {
  713. // formatter: function (value, context) {
  714. // // 添加单位
  715. // return value + ' ' + unit;
  716. // },
  717. // textStrokeColor: '#fff',
  718. // textStrokeWidth: 5,
  719. // color: '#584B3D',
  720. // font: {
  721. // size: YfontSizeValue,
  722. // },
  723. // anchor: 'end',
  724. // align: 'end',
  725. // },
  726. datalabels: null,
  727. // datalabels: data.length <= 10 ? {
  728. // formatter: function (value, context) {
  729. // // 添加单位
  730. // return value + ' ' + unit;
  731. // },
  732. // textStrokeColor: '#fff',
  733. // textStrokeWidth: 5,
  734. // color: '#584B3D',
  735. // font: {
  736. // size: YfontSizeValue,
  737. // },
  738. // anchor: 'end',
  739. // align: 'end',
  740. // } : null,
  741. customLabels: null,
  742. legend: {
  743. display: false,
  744. },
  745. // subtitle: {
  746. // display: true,
  747. // align: 'left',
  748. // position: 'top',
  749. // text: 'Custom Chart Subtitle'
  750. // },
  751. // afterDatasetsDraw(chart) {
  752. // var ctx = chart.ctx;
  753. // var xAxis = chart.scales.x;
  754. // var yAxis = chart.scales.y;
  755. // var dataj = myChart.data.datasets[0].data;
  756. // console.log('after', dataj)
  757. // ctx.save();
  758. // ctx.strokeStyle = '#000'; // 虚线颜色
  759. // ctx.lineWidth = 1; // 虚线宽度
  760. // ctx.setLineDash([5, 5]); // 设置虚线样式,[虚线段长度, 间隔长度]
  761. // dataj.forEach(function (value, index) {
  762. // var xPos = xAxis.getPixelForValue(labels[index]); // 获取 x 轴位置
  763. // var yPos = yAxis.getPixelForValue(value); // 获取 y 轴位置
  764. // // console.log(xPos)
  765. // // 绘制虚线
  766. // // ctx.beginPath();
  767. // // ctx.moveTo(xPos, yPos);
  768. // // ctx.lineTo(xPos, xAxis.bottom);
  769. // // ctx.stroke();
  770. // var xLineEnd = Math.min(yPos, yAxis.bottom);
  771. // // console.log('第' + index + '條線', xPos, yPos, 'xLineEnd', xLineEnd, 'yAxis.getPixelForValue(value)', yAxis.getPixelForValue(value));
  772. // // console.log('yAxis.getPixelForValue(value)', yAxis.getPixelForValue(value))
  773. // // 绘制虚线
  774. // ctx.beginPath();
  775. // ctx.moveTo(xPos, yAxis.getPixelForValue(value));
  776. // ctx.lineTo(xPos, xAxis.top);
  777. // ctx.stroke();
  778. // // 添加日期标签
  779. // ctx.fillStyle = '#000'; // 文字颜色
  780. // ctx.textAlign = 'center';
  781. // // ctx.fillText(labels[index], xPos, yAxis.bottom + 20); // 将日期标签绘制在虚线下方
  782. // });
  783. // ctx.restore();
  784. // }
  785. },
  786. scales: {
  787. x: {
  788. display: displayXaxes, // 显示 x 轴
  789. grid: {
  790. display: false,
  791. lineWidth: 5,
  792. color: '#584B3D'
  793. },
  794. ticks: {
  795. textStrokeColor: '#fff',
  796. textStrokeWidth: 5,
  797. font: {
  798. display: false,
  799. family: 'Arial', // 设置字体
  800. size: XfontSizeValue, // 设置字体大小
  801. weight: 'bold', // 设置字体粗细
  802. fontColor: 'rgba(255,255,255,0.8)', // X-axis font color
  803. shadowColor: 'rgba(0, 0, 0, 0.5)', // Shadow color
  804. shadowBlur: 10, // Shadow blur level
  805. shadowOffsetX: 5, // Horizontal shadow offset
  806. shadowOffsetY: 5
  807. },
  808. },
  809. },
  810. y: {
  811. display: true,
  812. beginAtZero: false,
  813. grid: {
  814. grid: {
  815. display: true, // 显示 y 轴网格线
  816. lineWidth: 1, // 网格线宽度
  817. color: '#C0C5CC' // 网格线颜色
  818. },
  819. },
  820. ticks: {
  821. textStrokeColor: '#fff',
  822. textStrokeWidth: 5,
  823. font: {
  824. family: 'Arial', // 設置字體
  825. size: XfontSizeValue, // 設置字體大小
  826. weight: 'bold', // 設置字體粗細
  827. color: 'rgba(255,255,255,0.8)', // Y-axis 字體顏色
  828. shadowColor: 'rgba(0, 0, 0, 0.5)', // 陰影顏色
  829. shadowBlur: 10, // 陰影模糊級別
  830. shadowOffsetX: 5, // 水平陰影偏移
  831. shadowOffsetY: 5 // 垂直陰影偏移
  832. },
  833. }
  834. }
  835. },
  836. layout: {
  837. padding: {
  838. left: 50, // 调整图表左边距
  839. right: 50, // 调整图表右边距
  840. top: 40,
  841. bottom: 10,
  842. }
  843. },
  844. },
  845. });
  846. // 注册 afterDraw 事件
  847. // Chart.register({
  848. // id: 'afterDraw',
  849. // afterDraw: function (chart) {
  850. // // console.log('處發', chart)
  851. // // 在这里添加你的绘制代码
  852. // var ctx = chart.ctx;
  853. // var xAxis = chart.scales.x;
  854. // var yAxis = chart.scales.y;
  855. // var dataj = myChart.data.datasets[0].data;
  856. // console.log('after', dataj)
  857. // ctx.save();
  858. // ctx.strokeStyle = '#000'; // 虚线颜色
  859. // ctx.lineWidth = 1; // 虚线宽度
  860. // ctx.setLineDash([5, 5]); // 设置虚线样式,[虚线段长度, 间隔长度]
  861. // dataj.forEach(function (value, index) {
  862. // var xPos = xAxis.getPixelForValue(labels[index]); // 获取 x 轴位置
  863. // var yPos = yAxis.getPixelForValue(value); // 获取 y 轴位置
  864. // // console.log(xPos)
  865. // // 绘制虚线
  866. // // ctx.beginPath();
  867. // // ctx.moveTo(xPos, yPos);
  868. // // ctx.lineTo(xPos, xAxis.bottom);
  869. // // ctx.stroke();
  870. // var xLineEnd = Math.min(yPos, yAxis.bottom);
  871. // // console.log('第' + index + '條線', xPos, yPos, 'xLineEnd', xLineEnd, 'yAxis.getPixelForValue(value)', yAxis.getPixelForValue(value));
  872. // // console.log('yAxis.getPixelForValue(value)', yAxis.getPixelForValue(value))
  873. // // 绘制虚线
  874. // ctx.beginPath();
  875. // ctx.moveTo(xPos, yAxis.getPixelForValue(value));
  876. // ctx.lineTo(xPos, xAxis.top);
  877. // ctx.stroke();
  878. // // 添加日期标签
  879. // ctx.fillStyle = '#000'; // 文字颜色
  880. // ctx.textAlign = 'center';
  881. // // ctx.fillText(labels[index], xPos, yAxis.bottom + 20); // 将日期标签绘制在虚线下方
  882. // });
  883. // ctx.restore();
  884. // }
  885. // });
  886. console.log(chart_bgimg_url);
  887. bgImgelement.style.backgroundImage = chart_bgimg_url;
  888. chartWhitelement.style.background = "rgba(255,255,255,0.5)";
  889. downloadButton.style.display = "inline-block";
  890. }
  891. // createChart(chartType);
  892. // createChart(chartType)
  893. const ChartOptions = document.querySelectorAll('input[name="ChartOptions"]');
  894. ChartOptions.forEach(button => {
  895. button.addEventListener('click', function () {
  896. // console.log(this.value);
  897. chartType = this.value;
  898. console.log(chartType);
  899. if (myChart !== null) {
  900. myChart.destroy();
  901. data = [];
  902. labels = [];
  903. }
  904. if (chartType === 'line') {
  905. $('#chartdiv').hide();
  906. generateChart(dataArray);
  907. } else {
  908. $('#textToChart').hide();
  909. extractAndGenerateChart(dataArray);
  910. }
  911. // createChart(chartType, data, labels);
  912. });
  913. });
  914. // 表格字體
  915. var fontSizeInput = document.getElementById('table_fontSize');
  916. // 添加事件监听器
  917. fontSizeInput.addEventListener('input', function () {
  918. // 获取输入框的值
  919. var fontSize = fontSizeInput.value;
  920. // 获取动态创建的表格元素
  921. var dynamicTable = document.querySelector('.dynamic-table');
  922. // 如果表格存在,则调整其字体大小
  923. if (dynamicTable) {
  924. dynamicTable.style.fontSize = fontSize + 'px';
  925. }
  926. });
  927. // 是否顯示point
  928. var togglePoints = document.getElementById('togglePoints');
  929. togglePoints.addEventListener('change', function () {
  930. console.log('checked')
  931. if (this.checked) {
  932. myChart.data.datasets[0].pointRadius = 5;
  933. myChart.data.datasets[0].pointHoverRadius = 8;
  934. } else {
  935. myChart.data.datasets[0].pointRadius = 0;
  936. myChart.data.datasets[0].pointHoverRadius = 0;
  937. }
  938. myChart.update();
  939. });
  940. // 單位標題
  941. // =========================
  942. var unitInput = document.getElementById('unit_data');
  943. unitInput.addEventListener('input', function () {
  944. unit = unitInput.value;
  945. // 重新渲染图表
  946. myChart.update();
  947. });
  948. // ==========================
  949. // y軸字體大小
  950. // ==========================
  951. var YfontSize = document.getElementById('YfontSize');
  952. YfontSize.addEventListener('input', function () {
  953. YfontSizeValue = YfontSize.value;
  954. if (myChart) {
  955. myChart.destroy();
  956. }
  957. createChart(chartType, data, labels);
  958. });
  959. // ==========================
  960. // x軸字體大小
  961. // ==========================
  962. var XfontSize = document.getElementById('XfontSize');
  963. XfontSize.addEventListener('input', function () {
  964. XfontSizeValue = XfontSize.value;
  965. console.log(XfontSizeValue)
  966. if (myChart) {
  967. myChart.destroy();
  968. }
  969. createChart(chartType, data, labels);
  970. });
  971. // ==========================
  972. // 線條粗細
  973. // =========================
  974. var rangeInput = document.getElementById('borderWidthRange');
  975. var rangeInputSpan = document.getElementById('borderWidthRangeValue');
  976. var borderWidthValue;
  977. rangeInputSpan.textContent = rangeInput.value;
  978. // 添加事件监听器,当滑动条的值发生改变时更新显示的值
  979. rangeInput.addEventListener('input', function () {
  980. // 获取滑动条的当前值
  981. borderWidthValue = rangeInput.value;
  982. console.log(borderWidthValue);
  983. rangeInputSpan.textContent = borderWidthValue;
  984. if (myChart) {
  985. myChart.destroy();
  986. }
  987. createChart(chartType, data, labels);
  988. // myChart.data.datasets[0].borderWidth = borderWidthValue;
  989. });
  990. // =========================
  991. // 線條顏色
  992. // =========================
  993. const colorInput = document.getElementById('borderColorInput');
  994. // 添加事件监听器,当颜色选择发生变化时触发
  995. colorInput.addEventListener('input', function () {
  996. // 获取当前选择的颜色值
  997. chartColor = colorInput.value;
  998. if (myChart) {
  999. myChart.destroy();
  1000. }
  1001. console.log(chartColor);
  1002. createChart(chartType, data, labels);
  1003. });
  1004. // =========================
  1005. // 模板樣式
  1006. // =========================
  1007. // JavaScript
  1008. document.addEventListener("DOMContentLoaded", function () {
  1009. // 獲取所有帶有 templateImg class 的圖像元素
  1010. var templateImgs = document.querySelectorAll('.templateImg');
  1011. // 為每個圖像元素添加點擊事件監聽器
  1012. templateImgs.forEach(function (img) {
  1013. img.addEventListener('click', function () {
  1014. // 在點擊時印出圖像元素的 value 屬性值
  1015. console.log(this.getAttribute('value'));
  1016. });
  1017. });
  1018. });
  1019. // =========================
  1020. var bgImgelement = document.getElementById('data_chart_box');
  1021. var chartWhitelement = document.getElementById('data_chartJs_box');
  1022. // 背景樣式
  1023. // =========================
  1024. // JavaScript
  1025. document.addEventListener("DOMContentLoaded", function () {
  1026. // 獲取所有帶有 templateImg class 的圖像元素
  1027. var bgImgs = document.querySelectorAll('.bgImg');
  1028. // 為每個圖像元素添加點擊事件監聽器
  1029. bgImgs.forEach(function (img) {
  1030. img.addEventListener('click', function () {
  1031. // 在點擊時印出圖像元素的 value 屬性值
  1032. console.log(this.getAttribute('value'));
  1033. var bgImgUrl = this.getAttribute('value');
  1034. chart_bgimg_url = 'url(' + bgImgUrl + ')';
  1035. bgImgelement.style.backgroundImage = chart_bgimg_url;
  1036. // bgImgelement.style.backgroundSize = 'cover'; // 調整背景圖片大小
  1037. // bgImgelement.style.backgroundPosition = 'center'; // 調整背景圖片位置
  1038. // bgImgelement.style.backgroundRepeat = 'no-repeat'; // 調整背景圖片重複
  1039. });
  1040. });
  1041. });
  1042. // =========================
  1043. const radioButtons = document.querySelectorAll('input[name="inlineRadioOptions"]');
  1044. var chartTitle = document.querySelector('.chart_title');
  1045. radioButtons.forEach(button => {
  1046. button.addEventListener('click', function () {
  1047. if (this.value === '0') {
  1048. chartTitle.style.textAlign = 'left';
  1049. } else if (this.value === '1') {
  1050. chartTitle.style.textAlign = 'center';
  1051. } else if (this.value === '2') {
  1052. chartTitle.style.textAlign = 'right';
  1053. }
  1054. });
  1055. });
  1056. var keywordInput = document.getElementById('title_data');
  1057. // 初始时将输入框的值设置为标题的文本内容
  1058. keywordInput.value = chartTitle.textContent;
  1059. // 监听输入框的输入事件,实现内容同步更新
  1060. keywordInput.addEventListener('input', function () {
  1061. chartTitle.textContent = this.value;
  1062. });
  1063. // 標題字體大小
  1064. // ==========================
  1065. var TitlefontSize = document.getElementById('TitlefontSize');
  1066. TitlefontSize.addEventListener('input', function () {
  1067. var TitlefontSizeValue = TitlefontSize.value;
  1068. chartTitle.style.fontSize = TitlefontSizeValue + 'px';;
  1069. });
  1070. // ==========================
  1071. let labelDependent = ""; // 圖表左側 Label
  1072. function get_data(input_text_value) {
  1073. inputField.value = "";
  1074. apiLoading();
  1075. var existingTable = chartJsBox.querySelector('table');
  1076. if (chartDiv.childElementCount != 0) {
  1077. data = [];
  1078. labels = [];
  1079. console.log('已存在')
  1080. chartTitle.textContent = "";
  1081. bgImgelement.style.backgroundImage = "";
  1082. chartWhitelement.style.background = "";
  1083. document.getElementById('img_box_url').src = "";
  1084. }
  1085. if (existingTable) {
  1086. chartJsBox.removeChild(existingTable);
  1087. chartTitle.textContent = "";
  1088. bgImgelement.style.backgroundImage = "";
  1089. chartWhitelement.style.background = "";
  1090. document.getElementById('img_box_url').src = "";
  1091. }
  1092. if (myChart) {
  1093. data = [];
  1094. labels = [];
  1095. chartTitle.textContent = "";
  1096. bgImgelement.style.backgroundImage = "";
  1097. chartWhitelement.style.background = "";
  1098. myChart.destroy();
  1099. document.getElementById('img_box_url').src = "";
  1100. }
  1101. axios.get('https://cmm.ai:8080/answer?question=' + input_text_value)
  1102. .then(response => {
  1103. apiHideLoading();
  1104. // 在這裡處理成功獲取 JSON 的情況
  1105. console.log(response);
  1106. var chart_info = response.data.chart_info.Title;
  1107. chartType = response.data.chart_info.Chart_type;
  1108. var finance_img_url = response.data.imageUrl_info.imageUrl;
  1109. if (response.data.imageUrl_info != null) {
  1110. console.log(finance_img_url);
  1111. document.getElementById('img_box_url').src = finance_img_url;
  1112. }
  1113. // switch (chartType) {
  1114. // case "line":
  1115. // document.getElementById("inlineRadio4").checked = true; // 折线图
  1116. // break;
  1117. // case "bar":
  1118. // document.getElementById("inlineRadio5").checked = true; // 柱状图
  1119. // labelDependent = response.data.chart_info.Label_dependent_variable;
  1120. // break;
  1121. // case "pie":
  1122. // document.getElementById("inlineRadio6").checked = true; // 圆饼图
  1123. // break;
  1124. // case "table":
  1125. // document.getElementById("inlineRadio7").checked = true; // 表格
  1126. // break;
  1127. // default:
  1128. // // 默认情况
  1129. // }
  1130. keywordInput.value = chart_info;
  1131. chartTitle.textContent = chart_info;
  1132. unit = response.data.chart_info.Unit_of_dependent_variable;
  1133. var Label_dependent_variable = response.data.chart_info.Label_dependent_variable;
  1134. var Label_independent_variable = response.data.chart_info.Label_independent_variable;
  1135. unit_data.value = response.data.chart_info.Unit_of_dependent_variable;
  1136. dataArray = response.data.data;
  1137. if (chartType === "table") {
  1138. createTable(dataArray, unit, Label_dependent_variable, Label_independent_variable);
  1139. // document.getElementById('img_box_url').src = "";
  1140. } else if (chartType === "bar") {
  1141. console.log('圖表類型bar')
  1142. $('#textToChart').hide();
  1143. extractAndGenerateChart(dataArray);
  1144. } else if (chartType === "doughnut") {
  1145. $('#textToChart').hide();
  1146. generatePieChart(dataArray)
  1147. } else {
  1148. $('#chartdiv').hide();
  1149. generateChart(dataArray);
  1150. }
  1151. // generateChart(dataArray);
  1152. })
  1153. .catch(error => {
  1154. apiHideLoading();
  1155. // 在這裡處理請求失敗的情況
  1156. console.error('發生錯誤:', error);
  1157. });
  1158. }
  1159. $(document).ready(function () {
  1160. $('#dataTable').DataTable();
  1161. });
  1162. function resizeChart() {
  1163. if (myChart) {
  1164. myChart.resize();
  1165. }
  1166. }
  1167. document.addEventListener('visibilitychange', function () {
  1168. console.log('Visibility changed:', document.visibilityState);
  1169. if (document.visibilityState === 'visible') {
  1170. resizeChart();
  1171. }
  1172. });
  1173. // 监听窗口resize事件
  1174. window.addEventListener('resize', resizeChart);
  1175. var seeting_button = document.getElementById('chart_seeting_button');
  1176. var closeButton = document.getElementById('style_setting_close');
  1177. var closeButton_table = document.getElementById('style_setting_close_table');
  1178. // var borderSetting = document.getElementById('borderSetting');
  1179. var lineChartSetting = document.getElementById('lineChartSetting');
  1180. var table_setting = document.getElementById('table_setting');
  1181. var chart_category = document.getElementById('chart_category');
  1182. // 获取 chartDiv 元素
  1183. seeting_button.addEventListener('click', () => {
  1184. console.log('setting_button')
  1185. if (myChart === null && !chartJsBox.querySelector('table') && chartDiv.childElementCount === 0) {
  1186. alert('請先生成圖表');
  1187. return
  1188. }
  1189. if (chartType === 'table') {
  1190. console.log('表格');
  1191. sidebar.classList.toggle('show');
  1192. sidebar.classList.toggle('hidden');
  1193. lineChartSetting.style.display = 'none';
  1194. table_setting.style.display = 'block';
  1195. chart_category.style.display = 'none';
  1196. } else if (chartType === "bar") {
  1197. console.log('柱狀圖')
  1198. sidebar.classList.toggle('show');
  1199. sidebar.classList.toggle('hidden');
  1200. lineChartSetting.style.display = 'none';
  1201. table_setting.style.display = 'none';
  1202. } else if (chartType === "doughnut") {
  1203. console.log('快捷功能圓餅圖')
  1204. sidebar.classList.toggle('show');
  1205. sidebar.classList.toggle('hidden');
  1206. lineChartSetting.style.display = 'none';
  1207. table_setting.style.display = 'none';
  1208. chart_category.style.display = 'none';
  1209. } else {
  1210. sidebar.classList.toggle('show');
  1211. sidebar.classList.toggle('hidden');
  1212. table_setting.style.display = 'none';
  1213. lineChartSetting.style.display = 'block';
  1214. }
  1215. });
  1216. closeButton.addEventListener('click', () => {
  1217. sidebar.classList.remove('show');
  1218. sidebar.classList.add('hidden');
  1219. });
  1220. const finance_options = [
  1221. { name: "原油油桶", imageUrl: "./img/finance/01.webp" },
  1222. { name: "黃金", imageUrl: "./img/finance/02.webp" },
  1223. { name: "房屋", imageUrl: "./img/finance/03.webp" },
  1224. { name: "車", imageUrl: "./img/finance/04.webp" },
  1225. { name: "股市", imageUrl: "./img/finance/05.webp" },
  1226. { name: "晶圓", imageUrl: "./img/finance/06.webp" },
  1227. { name: "TSMC 台積電", imageUrl: "./img/finance/07.webp" },
  1228. { name: "台幣", imageUrl: "./img/finance/08.webp" },
  1229. { name: "美金", imageUrl: "./img/finance/09.webp" },
  1230. { name: "購物車", imageUrl: "./img/finance/10.webp" },
  1231. { name: "美中貿易", imageUrl: "./img/finance/11.webp" },
  1232. { name: "世界地圖", imageUrl: "./img/finance/12.webp" },
  1233. { name: "小麥", imageUrl: "./img/finance/13.webp" },
  1234. { name: "玉米", imageUrl: "./img/finance/14.webp" },
  1235. { name: "智慧產線", imageUrl: "./img/finance/15.webp" }
  1236. ];
  1237. const selectOptions = document.getElementById('finance_options');
  1238. const selectOptions_table = document.getElementById('finance_options_table');
  1239. finance_options.forEach((option, index) => {
  1240. const optionElement = document.createElement('option');
  1241. optionElement.value = index + 1; // 值从 1 开始
  1242. optionElement.textContent = option.name;
  1243. optionElement.setAttribute('data-image-url', option.imageUrl); // 存储图片 URL
  1244. selectOptions.appendChild(optionElement);
  1245. });
  1246. selectOptions.addEventListener('change', function () {
  1247. const selectedOption = selectOptions.options[selectOptions.selectedIndex];
  1248. const imageUrl = selectedOption.getAttribute('data-image-url');
  1249. document.getElementById('img_box_url').src = imageUrl;
  1250. });
  1251. // finance_options.forEach((option, index) => {
  1252. // const optionElement = document.createElement('option');
  1253. // optionElement.value = index + 1; // 值从 1 开始
  1254. // optionElement.textContent = option.name;
  1255. // optionElement.setAttribute('data-image-url', option.imageUrl); // 存储图片 URL
  1256. // selectOptions_table.appendChild(optionElement);
  1257. // });
  1258. // selectOptions_table.addEventListener('change', function () {
  1259. // const selectedOption = selectOptions_table.options[selectOptions_table.selectedIndex];
  1260. // const imageUrl = selectedOption.getAttribute('data-image-url');
  1261. // document.getElementById('img_box_url').src = imageUrl;
  1262. // });
  1263. document.querySelectorAll('input[name="ChartOptions"]').forEach(function (radio) {
  1264. radio.addEventListener('change', function () {
  1265. // 檢查哪個單選按鈕被選中
  1266. if (this.value === 'line') {
  1267. // 如果選擇了折線圖,執行相應的操作
  1268. console.log("選擇了折線圖");
  1269. // 在這裡執行顯示折線圖的相關代碼
  1270. } else if (this.value === 'doughnut') {
  1271. // 如果選擇了柱狀圖,執行相應的操作
  1272. console.log("選擇了柱狀圖");
  1273. // 在這裡執行顯示柱狀圖的相關代碼
  1274. }
  1275. });
  1276. });