|
@@ -3,27 +3,40 @@
|
|
console.log('text-to-chart');
|
|
console.log('text-to-chart');
|
|
|
|
|
|
var accessToken = localStorage.getItem("access_token");
|
|
var accessToken = localStorage.getItem("access_token");
|
|
|
|
+console.log(accessToken);
|
|
|
|
+
|
|
|
|
+if (accessToken === null) {
|
|
|
|
+ alert('請先登入')
|
|
|
|
+ window.location.href = "./login.html";
|
|
|
|
+}
|
|
|
|
|
|
var usernameEmail = localStorage.getItem("username");
|
|
var usernameEmail = localStorage.getItem("username");
|
|
|
|
|
|
|
|
+var unit_table_value
|
|
|
|
+
|
|
|
|
|
|
|
|
|
|
let username = usernameEmail.split('@')[0];
|
|
let username = usernameEmail.split('@')[0];
|
|
|
|
|
|
console.log(username);
|
|
console.log(username);
|
|
|
|
|
|
-console.log(accessToken);
|
|
|
|
|
|
|
|
|
|
|
|
Chart.register(ChartDataLabels);
|
|
Chart.register(ChartDataLabels);
|
|
|
|
|
|
var userNameSpan = document.getElementById("userName");
|
|
var userNameSpan = document.getElementById("userName");
|
|
|
|
|
|
|
|
+var lineYfontSize = document.getElementById("lineYfontSize");
|
|
|
|
+
|
|
|
|
+
|
|
|
|
|
|
userNameSpan.textContent = username;
|
|
userNameSpan.textContent = username;
|
|
|
|
|
|
var inputField = document.getElementById("keyword_data");
|
|
var inputField = document.getElementById("keyword_data");
|
|
|
|
|
|
|
|
+var inputField_compare = document.getElementById("keyword_data_compare");
|
|
|
|
+
|
|
|
|
+
|
|
var sendButton = document.getElementById("send_data");
|
|
var sendButton = document.getElementById("send_data");
|
|
|
|
|
|
var canvasPng = document.getElementById("textToChart");
|
|
var canvasPng = document.getElementById("textToChart");
|
|
@@ -58,6 +71,9 @@ var vocab = [];
|
|
|
|
|
|
var chartDiv = document.getElementById('chartdiv');
|
|
var chartDiv = document.getElementById('chartdiv');
|
|
|
|
|
|
|
|
+$('#chartdiv').hide();
|
|
|
|
+
|
|
|
|
+
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
axios.get("https://cmm.ai:8080/vocab")
|
|
axios.get("https://cmm.ai:8080/vocab")
|
|
.then(response => {
|
|
.then(response => {
|
|
@@ -183,6 +199,108 @@ document.addEventListener('DOMContentLoaded', function () {
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
|
|
|
|
+document.addEventListener('DOMContentLoaded', function () {
|
|
|
|
+ // const input = document.getElementById('stockInput');
|
|
|
|
+ const suggestions_compare = document.getElementById('suggestions_compare');
|
|
|
|
+
|
|
|
|
+ inputField_compare.addEventListener('input', function () {
|
|
|
|
+ const query = this.value.trim();
|
|
|
|
+ suggestions_compare.innerHTML = ''; // 清空之前的建議
|
|
|
|
+
|
|
|
|
+ console.log('query', query);
|
|
|
|
+ if (query) {
|
|
|
|
+ // const filteredVocab = vocab.filter(item => item.toLowerCase().includes(query));
|
|
|
|
+ const queryTerms = query.split(/\s+/); // 分割輸入的內容
|
|
|
|
+ const lastQueryTerm = queryTerms[queryTerms.length - 1];
|
|
|
|
+ const filteredVocab = vocab.filter(item => {
|
|
|
|
+ // 對每個分割後的單詞進行匹配,只要其中有一個匹配成功就返回 true
|
|
|
|
+ return item.toLowerCase().includes(lastQueryTerm.toLowerCase());
|
|
|
|
+
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ if (filteredVocab.length > 0) {
|
|
|
|
+ suggestions_compare.style.border = '1px solid #ccc';
|
|
|
|
+ suggestions_compare.style.display = 'block'; // 顯示建議容器
|
|
|
|
+ } else {
|
|
|
|
+ suggestions_compare.style.border = 'none';
|
|
|
|
+ suggestions_compare.style.display = 'none'; // 隱藏建議容器
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ console.log(queryTerms[queryTerms.length - 1])
|
|
|
|
+
|
|
|
|
+ filteredVocab.forEach(item => {
|
|
|
|
+ const div = document.createElement('div');
|
|
|
|
+ div.classList.add('autocomplete-suggestion');
|
|
|
|
+ div.textContent = item;
|
|
|
|
+ // div.addEventListener('click', function () {
|
|
|
|
+ // inputField.value = item;
|
|
|
|
+ // suggestions.innerHTML = ''; // 清空建議
|
|
|
|
+ // suggestions.style.border = 'none';
|
|
|
|
+ // suggestions.style.display = 'none'; // 隱藏建議容器
|
|
|
|
+
|
|
|
|
+ // });
|
|
|
|
+ console.log('queryTerms', queryTerms);
|
|
|
|
+
|
|
|
|
+ // console.log('filteredVocab', filteredVocab);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ div.addEventListener('click', function () {
|
|
|
|
+ queryTerms.forEach((term, index) => {
|
|
|
|
+ const regex = new RegExp(term, 'gi');
|
|
|
|
+ const match = regex.exec(inputField_compare.value);
|
|
|
|
+ // console.log(queryTerms[queryTerms.length - 1]);
|
|
|
|
+ // console.log(filteredVocab, queryTerms[queryTerms.length - 1])
|
|
|
|
+
|
|
|
|
+ if (index === queryTerms.length - 1) {
|
|
|
|
+
|
|
|
|
+ if (match) {
|
|
|
|
+ var start = match.index;
|
|
|
|
+ var end = start + match[0].length;
|
|
|
|
+
|
|
|
|
+ console.log(start, end)
|
|
|
|
+
|
|
|
|
+ const textBefore = inputField_compare.value.substring(0, start);
|
|
|
|
+ const textAfter = inputField_compare.value.substring(end, inputField_compare.value.length);
|
|
|
|
+
|
|
|
|
+ console.log('start', start, 'end', end, 'textBefore', textBefore, 'textAfter', textAfter);
|
|
|
|
+
|
|
|
|
+ // 捕獲被選中的部分並替換它
|
|
|
|
+ const selectedText = inputField_compare.value.substring(start, end);
|
|
|
|
+
|
|
|
|
+ console.log('selectedText', selectedText);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ const newText = textBefore + item + textAfter.replace(selectedText, '');
|
|
|
|
+
|
|
|
|
+ console.log('newText', newText);
|
|
|
|
+
|
|
|
|
+ inputField_compare.value = newText;
|
|
|
|
+ // inputField.value = textBefore + item.replace(selectedText, '') + textAfter;
|
|
|
|
+
|
|
|
|
+ suggestions_compare.innerHTML = ''; // 清空建議
|
|
|
|
+ suggestions_compare.style.border = 'none';
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ // const start = inputField.selectionStart;
|
|
|
|
+ // const end = inputField.selectionEnd;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ suggestions_compare.appendChild(div);
|
|
|
|
+
|
|
|
|
+ });
|
|
|
|
+ } else {
|
|
|
|
+ suggestions_compare.style.border = 'none';
|
|
|
|
+ suggestions_compare.style.display = 'none'; // 隱藏建議容器
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+});
|
|
|
|
+
|
|
// 監聽輸入框的鍵盤事件
|
|
// 監聽輸入框的鍵盤事件
|
|
// document.getElementById("keyword_data").addEventListener("keyup", function (event) {
|
|
// document.getElementById("keyword_data").addEventListener("keyup", function (event) {
|
|
// // 判斷是否按下 Enter 鍵 (key code: 13)
|
|
// // 判斷是否按下 Enter 鍵 (key code: 13)
|
|
@@ -299,7 +417,14 @@ var data = [];
|
|
|
|
|
|
var dataArray;
|
|
var dataArray;
|
|
|
|
|
|
|
|
+
|
|
|
|
+
|
|
function generateChart(dataArray) {
|
|
function generateChart(dataArray) {
|
|
|
|
+ if (dataArray.length > 10) {
|
|
|
|
+ lineYfontSize.style.display = 'none'
|
|
|
|
+ } else {
|
|
|
|
+ lineYfontSize.style.display = 'block'
|
|
|
|
+ }
|
|
// 创建一个空数组来存储 labels 和 data
|
|
// 创建一个空数组来存储 labels 和 data
|
|
console.log(dataArray)
|
|
console.log(dataArray)
|
|
// 遍历数据数组
|
|
// 遍历数据数组
|
|
@@ -874,7 +999,8 @@ var chartJsBox = document.getElementById('data_chartJs_box');
|
|
function createTable(dataArray, unit, Label_dependent_variable, Label_independent_variable,) {
|
|
function createTable(dataArray, unit, Label_dependent_variable, Label_independent_variable,) {
|
|
$('#chartdiv').hide();
|
|
$('#chartdiv').hide();
|
|
$('#textToChart').hide();
|
|
$('#textToChart').hide();
|
|
-
|
|
|
|
|
|
+ chartTitle.style.padding = "0px 0px 0px 30px";
|
|
|
|
+ bgImgelement.style.paddingTop = "10px";
|
|
var table = document.createElement('table');
|
|
var table = document.createElement('table');
|
|
table.classList.add('table', 'table_template', 'dynamic-table'); // 添加 Bootstrap 的 table 样式,如果你在使用 Bootstrap
|
|
table.classList.add('table', 'table_template', 'dynamic-table'); // 添加 Bootstrap 的 table 样式,如果你在使用 Bootstrap
|
|
|
|
|
|
@@ -909,10 +1035,14 @@ function createTable(dataArray, unit, Label_dependent_variable, Label_independen
|
|
cell.classList.add('year-class');
|
|
cell.classList.add('year-class');
|
|
} else { // Otherwise, add 'average-class'
|
|
} else { // Otherwise, add 'average-class'
|
|
if (key === 'Average_Close') {
|
|
if (key === 'Average_Close') {
|
|
- cell.textContent = item[key].toFixed(2) + unit;
|
|
|
|
|
|
+ // cell.textContent = item[key].toFixed(2) + unit;
|
|
|
|
+ cell.innerHTML = item[key].toFixed(2) + '<span class="unit_table">' + unit + '</span>';
|
|
|
|
+
|
|
} else {
|
|
} else {
|
|
// cell.textContent = item[key];
|
|
// cell.textContent = item[key];
|
|
- cell.textContent = item[key].toFixed(2) + unit;
|
|
|
|
|
|
+ // cell.textContent = item[key].toFixed(2) + unit;
|
|
|
|
+ cell.innerHTML = item[key].toFixed(2) + '<span class="unit_table">' + unit + '</span>';
|
|
|
|
+
|
|
}
|
|
}
|
|
cell.classList.add('average-class');
|
|
cell.classList.add('average-class');
|
|
}
|
|
}
|
|
@@ -938,8 +1068,37 @@ function createTable(dataArray, unit, Label_dependent_variable, Label_independen
|
|
// chartWhitelement.style.background = "rgba(255,255,255,0.5)"
|
|
// chartWhitelement.style.background = "rgba(255,255,255,0.5)"
|
|
// 将表格添加到指定的 div 元素中
|
|
// 将表格添加到指定的 div 元素中
|
|
chartJsBox.appendChild(table);
|
|
chartJsBox.appendChild(table);
|
|
|
|
+
|
|
|
|
+ unit_table_value = document.querySelectorAll('.unit_table');
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ downloadButton.style.display = "inline-block";
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+function getDatalabelsConfig(dataLength) {
|
|
|
|
+
|
|
|
|
+ if (dataLength < 10) {
|
|
|
|
+ return {
|
|
|
|
+ formatter: function (value, context) {
|
|
|
|
+ return value + ' unit'; // Add unit if data length is less than 10
|
|
|
|
+ },
|
|
|
|
+ textStrokeColor: '#fff',
|
|
|
|
+ textStrokeWidth: 5,
|
|
|
|
+ color: '#584B3D',
|
|
|
|
+ font: {
|
|
|
|
+ size: YfontSizeValue,
|
|
|
|
+ },
|
|
|
|
+ anchor: 'end',
|
|
|
|
+ align: 'end',
|
|
|
|
+ };
|
|
|
|
+ } else {
|
|
|
|
+ return null; // No datalabels if data length is 10 or more
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
// 版型一折線圖
|
|
// 版型一折線圖
|
|
// // 创建 Chart.js 图表
|
|
// // 创建 Chart.js 图表
|
|
function createChart(chartType, data, labels) {
|
|
function createChart(chartType, data, labels) {
|
|
@@ -947,6 +1106,22 @@ function createChart(chartType, data, labels) {
|
|
canvasPng.style.maxWidth = '';
|
|
canvasPng.style.maxWidth = '';
|
|
canvasPng.style.maxHeight = '';
|
|
canvasPng.style.maxHeight = '';
|
|
|
|
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ const datalabelsConfig = data.length <= 10 ? {
|
|
|
|
+ formatter: function (value, context) {
|
|
|
|
+ return value;
|
|
|
|
+ },
|
|
|
|
+ textStrokeColor: '#fff',
|
|
|
|
+ textStrokeWidth: 5,
|
|
|
|
+ color: '#584B3D',
|
|
|
|
+ font: {
|
|
|
|
+ size: YfontSizeValue,
|
|
|
|
+ },
|
|
|
|
+ anchor: 'end',
|
|
|
|
+ align: 'right'
|
|
|
|
+ } : null;
|
|
|
|
+
|
|
ctx = document.getElementById("textToChart");
|
|
ctx = document.getElementById("textToChart");
|
|
|
|
|
|
myChart = new Chart(ctx, {
|
|
myChart = new Chart(ctx, {
|
|
@@ -974,16 +1149,18 @@ function createChart(chartType, data, labels) {
|
|
maintainAspectRatio: false,
|
|
maintainAspectRatio: false,
|
|
|
|
|
|
plugins: {
|
|
plugins: {
|
|
|
|
+
|
|
chart3d: {
|
|
chart3d: {
|
|
enabled: true, // 啟用 3D 插件
|
|
enabled: true, // 啟用 3D 插件
|
|
alpha: 25, // 圖表繞 x 軸的旋轉角度
|
|
alpha: 25, // 圖表繞 x 軸的旋轉角度
|
|
beta: 25, // 圖表繞 y 軸的旋轉角度
|
|
beta: 25, // 圖表繞 y 軸的旋轉角度
|
|
depth: 15 // 圖表的深度
|
|
depth: 15 // 圖表的深度
|
|
},
|
|
},
|
|
|
|
+ datalabels: datalabelsConfig,
|
|
// datalabels: {
|
|
// datalabels: {
|
|
// formatter: function (value, context) {
|
|
// formatter: function (value, context) {
|
|
// // 添加单位
|
|
// // 添加单位
|
|
- // return value + ' ' + unit;
|
|
|
|
|
|
+ // return value;
|
|
// },
|
|
// },
|
|
// textStrokeColor: '#fff',
|
|
// textStrokeColor: '#fff',
|
|
// textStrokeWidth: 5,
|
|
// textStrokeWidth: 5,
|
|
@@ -994,7 +1171,8 @@ function createChart(chartType, data, labels) {
|
|
// anchor: 'end',
|
|
// anchor: 'end',
|
|
// align: 'end',
|
|
// align: 'end',
|
|
// },
|
|
// },
|
|
- datalabels: null,
|
|
|
|
|
|
+
|
|
|
|
+ // datalabels: null,
|
|
// datalabels: data.length <= 10 ? {
|
|
// datalabels: data.length <= 10 ? {
|
|
// formatter: function (value, context) {
|
|
// formatter: function (value, context) {
|
|
// // 添加单位
|
|
// // 添加单位
|
|
@@ -1234,17 +1412,34 @@ togglePoints.addEventListener('change', function () {
|
|
});
|
|
});
|
|
|
|
|
|
|
|
|
|
-// 單位標題
|
|
|
|
|
|
+// 單位
|
|
// =========================
|
|
// =========================
|
|
var unitInput = document.getElementById('unit_data');
|
|
var unitInput = document.getElementById('unit_data');
|
|
|
|
|
|
|
|
+var unit_value = document.querySelector('.unit');
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+// console.log('單位', unitInput)
|
|
|
|
+
|
|
unitInput.addEventListener('input', function () {
|
|
unitInput.addEventListener('input', function () {
|
|
- unit = unitInput.value;
|
|
|
|
|
|
+ // unitInput.value = unit_value.textContent;
|
|
|
|
+
|
|
|
|
+ if (chartType === 'table') {
|
|
|
|
+ // unit_table_value.textContent = this.value;
|
|
|
|
+ unit_table_value.forEach(span => {
|
|
|
|
+ span.textContent = this.value;
|
|
|
|
+ });
|
|
|
|
+ } else {
|
|
|
|
+ unit_value.textContent = '單位:' + this.value
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
|
|
- // 重新渲染图表
|
|
|
|
- myChart.update();
|
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
// ==========================
|
|
// ==========================
|
|
|
|
|
|
// y軸字體大小-折線圖
|
|
// y軸字體大小-折線圖
|
|
@@ -1449,6 +1644,8 @@ radioButtons.forEach(button => {
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
|
|
|
|
+// 圖表標題
|
|
|
|
+
|
|
var keywordInput = document.getElementById('title_data');
|
|
var keywordInput = document.getElementById('title_data');
|
|
|
|
|
|
|
|
|
|
@@ -1493,12 +1690,14 @@ function get_data(input_text_value) {
|
|
labels = [];
|
|
labels = [];
|
|
console.log('已存在')
|
|
console.log('已存在')
|
|
chartTitle.textContent = "";
|
|
chartTitle.textContent = "";
|
|
|
|
+ unit_value.textContent = "";
|
|
bgImgelement.style.backgroundImage = "";
|
|
bgImgelement.style.backgroundImage = "";
|
|
chartWhitelement.style.background = "";
|
|
chartWhitelement.style.background = "";
|
|
document.getElementById('img_box_url').src = "";
|
|
document.getElementById('img_box_url').src = "";
|
|
}
|
|
}
|
|
|
|
|
|
if (existingTable) {
|
|
if (existingTable) {
|
|
|
|
+ unit_value.textContent = "";
|
|
chartJsBox.removeChild(existingTable);
|
|
chartJsBox.removeChild(existingTable);
|
|
chartTitle.textContent = "";
|
|
chartTitle.textContent = "";
|
|
bgImgelement.style.backgroundImage = "";
|
|
bgImgelement.style.backgroundImage = "";
|
|
@@ -1507,6 +1706,7 @@ function get_data(input_text_value) {
|
|
|
|
|
|
}
|
|
}
|
|
if (myChart) {
|
|
if (myChart) {
|
|
|
|
+ unit_value.textContent = "";
|
|
data = [];
|
|
data = [];
|
|
labels = [];
|
|
labels = [];
|
|
chartTitle.textContent = "";
|
|
chartTitle.textContent = "";
|
|
@@ -1549,12 +1749,19 @@ function get_data(input_text_value) {
|
|
|
|
|
|
|
|
|
|
unit_data.value = response.data.chart_info.Unit_of_dependent_variable;
|
|
unit_data.value = response.data.chart_info.Unit_of_dependent_variable;
|
|
|
|
+ if (response.data.chart_info.Unit_of_dependent_variable == "") {
|
|
|
|
+ unit_value.textContent = ""
|
|
|
|
+ } else {
|
|
|
|
+ unit_value.textContent = '單位:' + response.data.chart_info.Unit_of_dependent_variable;
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
dataArray = response.data.data;
|
|
dataArray = response.data.data;
|
|
|
|
|
|
|
|
|
|
if (chartType === "table") {
|
|
if (chartType === "table") {
|
|
|
|
+ unit_value.textContent = "";
|
|
createTable(dataArray, unit, Label_dependent_variable, Label_independent_variable);
|
|
createTable(dataArray, unit, Label_dependent_variable, Label_independent_variable);
|
|
// document.getElementById('img_box_url').src = "";
|
|
// document.getElementById('img_box_url').src = "";
|
|
|
|
|
|
@@ -1563,6 +1770,7 @@ function get_data(input_text_value) {
|
|
$('#textToChart').hide();
|
|
$('#textToChart').hide();
|
|
extractAndGenerateChart(dataArray);
|
|
extractAndGenerateChart(dataArray);
|
|
} else if (chartType === "doughnut") {
|
|
} else if (chartType === "doughnut") {
|
|
|
|
+ unit_value.textContent = "";
|
|
$('#textToChart').hide();
|
|
$('#textToChart').hide();
|
|
|
|
|
|
generatePieChart(dataArray)
|
|
generatePieChart(dataArray)
|
|
@@ -2169,7 +2377,7 @@ async function handleAudioToText(file) {
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
- let url = `https://bf18-61-230-0-215.ngrok-free.app/gcp/speech-to-text?language_code=${audioLang}`;
|
|
|
|
|
|
+ let url = `https://9cbe-61-230-36-113.ngrok-free.app/gcp/speech-to-text?language_code=${audioLang}`;
|
|
|
|
|
|
const formData = new FormData();
|
|
const formData = new FormData();
|
|
formData.append("file", file);
|
|
formData.append("file", file);
|
|
@@ -2178,9 +2386,13 @@ async function handleAudioToText(file) {
|
|
const response = await axios.post(url, formData);
|
|
const response = await axios.post(url, formData);
|
|
console.log("response", response);
|
|
console.log("response", response);
|
|
input_text_value = response.data;
|
|
input_text_value = response.data;
|
|
- console.log(input_text_value[0]);
|
|
|
|
recording_block.classList.remove('show');
|
|
recording_block.classList.remove('show');
|
|
recording_block.classList.add('hidden');
|
|
recording_block.classList.add('hidden');
|
|
|
|
+ if (input_text_value.length === 0) {
|
|
|
|
+ alert('請再說一次')
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ console.log(input_text_value[0]);
|
|
get_data(input_text_value);
|
|
get_data(input_text_value);
|
|
|
|
|
|
} catch (error) {
|
|
} catch (error) {
|