Công Cụ Chuyển Đổi Tiếng Nhật Trên Máy Tính
Nhập văn bản tiếng Việt hoặc tiếng Nhật để chuyển đổi nhanh chóng và chính xác
Kết quả chuyển đổi:
Phiên âm (Romaji):
Số ký tự:
Thời gian xử lý:
Hướng Dẫn Toàn Diện: Cách Đổi Tiếng Nhật Trên Máy Tính (2024)
Việc chuyển đổi giữa tiếng Việt và tiếng Nhật trên máy tính không chỉ đơn thuần là công cụ hỗ trợ học tập mà còn là cầu nối văn hóa quan trọng. Bài viết này sẽ cung cấp cho bạn hướng dẫn chi tiết từ cơ bản đến nâng cao, cùng với các phương pháp chuyển đổi hiệu quả nhất hiện nay.
1. Các Phương Pháp Chuyển Đổi Tiếng Nhật Trên Máy Tính
- Sử dụng bộ gõ tiếng Nhật tích hợp sẵn
- Windows: Bộ gõ Microsoft IME (Input Method Editor) hỗ trợ đầy đủ Hiragana, Katakana, Kanji và Romaji.
- MacOS: Bộ gõ Kotoeri tích hợp sẵn với tính năng chuyển đổi tự động.
- Linux: Sử dụng IBUS hoặc FCITX với các gói ngôn ngữ tiếng Nhật.
- Công cụ chuyển đổi trực tuyến
- Google Translate (translate.google.com)
- DeepL (deepl.com) – chính xác hơn 40% so với Google đối với ngữ cảnh phức tạp
- Rikaikun (tiện ích mở rộng Chrome) – hỗ trợ đọc Kanji khi di chuột
- Phần mềm chuyên dụng
- ATOK – phần mềm gõ tiếng Nhật chuyên nghiệp với từ điển 300,000 từ
- WXG Editor – hỗ trợ chuyển đổi giữa Hiragana/Katakana/Kanji
- JWPce – công cụ miễn phí cho người học tiếng Nhật
2. Hướng Dẫn Cài Đặt Bộ Gõ Tiếng Nhật Trên Windows 10/11
- Mở Settings → Time & Language → Language & Region
- Chọn Add a language và tìm “Japanese”
- Sau khi cài đặt, nhấn Windows + Space để chuyển đổi bộ gõ
- Sử dụng phím F6 để chuyển đổi giữa Hiragana/Katakana/Kanji
- Nhấn F7 để chuyển sang bán width Katakana (dùng cho mật khẩu)
| Phím tắt | Chức năng | Ví dụ |
|---|---|---|
| F6 | Chuyển đổi Hiragana ↔ Katakana | こんにちは → コンニチハ |
| F7 | Chuyển sang bán width Katakana | コンニチハ → パソコン |
| F8 | Chuyển đổi bán width ↔ toàn width | 123 → 123 |
| F9 | Chuyển Romaji sang Hiragana | konnichiwa → こんにちは |
| F10 | Chuyển Hiragana sang Kanji | はな → 花 |
3. So Sánh Các Công Cụ Chuyển Đổi Phổ Biến
| Công cụ | Độ chính xác | Tốc độ | Tính năng đặc biệt | Giá |
|---|---|---|---|---|
| Google Translate | 85% | Nhanh | Hỗ trợ 100+ ngôn ngữ, phát âm | Miễn phí |
| DeepL | 92% | Trung bình | Xử lý ngữ cảnh tốt, hỗ trợ file | Miễn phí (giới hạn) |
| ATOK | 95% | Nhanh | Từ điển chuyên ngành, dự đoán từ | Trả phí (~$50) |
| Microsoft IME | 88% | Nhanh | Tích hợp Windows, hỗ trợ handwriting | Miễn phí |
| Rikaikun | 90% | Tức thì | Di chuột đọc Kanji, từ điển tích hợp | Miễn phí |
4. Mẹo Chuyển Đổi Hiệu Quả Cho Người Mới Bắt Đầu
- Sử dụng Romaji làm cầu nối: Khi chuyển từ tiếng Việt sang tiếng Nhật, nên chuyển thành Romaji trước rồi mới chuyển sang Hiragana/Kanji.
- Kiểm tra ngữ pháp: Sử dụng Bunpro để kiểm tra cấu trúc câu.
- Luyện tập hàng ngày: Dành 15 phút mỗi ngày sử dụng bộ gõ tiếng Nhật để làm quen với các phím tắt.
- Sử dụng từ điển chuyên ngành: Đối với các thuật ngữ kỹ thuật, sử dụng Weblio để tìm kiếm chính xác.
- Kiểm tra độ trang trọng: Nhớ chọn mức độ lịch sự phù hợp với ngữ cảnh (casual/polite/formal).
5. Các Lỗi Thường Gặp Khi Chuyển Đổi Và Cách Khắc Phục
- Lỗi chuyển đổi Kanji sai nghĩa:
- Nguyên nhân: Một từ tiếng Việt có thể tương ứng với nhiều Kanji khác nhau.
- Giải pháp: Sử dụng từ điển Jisho để kiểm tra nghĩa của Kanji.
- Lỗi chuyển đổi ngữ pháp:
- Nguyên nhân: Cấu trúc câu tiếng Việt và tiếng Nhật khác biệt hoàn toàn.
- Giải pháp: Học các mẫu câu cơ bản trước khi chuyển đổi.
- Lỗi chuyển đổi tên riêng:
- Nguyên nhân: Tên người Việt không có Kanji tương ứng.
- Giải pháp: Sử dụng Katakana để phiên âm (ví dụ: “Nguyễn” → ヺ帯’, ‘nhà’: ‘家’, ‘trường học’: ‘学校’, ‘công việc’: ‘仕事’, ‘thức ăn’: ‘食べ物’, ‘nước’: ‘水’, ‘trà’: ‘お茶’, ‘cà phê’: ‘コーヒー’, ‘hôm nay’: ‘今日’, ‘ngày mai’: ‘明日’, ‘hôm qua’: ‘昨日’, ‘sáng’: ‘朝’, ‘tối’: ‘夜’ }, // Japanese to Vietnamese ‘ja-to-vi’: { ‘こんにちは’: ‘xin chào’, ‘ありがとうございます’: ‘cảm ơn’, ‘さようなら’: ‘tạm biệt’, ‘私’: ‘tôi’, ‘あなた’: ‘bạn’, ‘愛’: ‘yêu’, ‘コンピューター’: ‘máy tính’, ‘携帯’: ‘điện thoại’, ‘家’: ‘nhà’, ‘学校’: ‘trường học’, ‘仕事’: ‘công việc’, ‘食べ物’: ‘thức ăn’, ‘水’: ‘nước’, ‘お茶’: ‘trà’, ‘コーヒー’: ‘cà phê’, ‘今日’: ‘hôm nay’, ‘明日’: ‘ngày mai’, ‘昨日’: ‘hôm qua’, ‘朝’: ‘sáng’, ‘夜’: ‘tối’, ‘大好き’: ‘rất thích’, ‘友達’: ‘bạn bè’, ‘家族’: ‘gia đình’, ‘仕事’: ‘công việc’, ‘勉強’: ‘học tập’ }, // Hiragana to Katakana ‘hiragana-to-katakana’: { ‘あ’: ‘ア’, ‘い’: ‘イ’, ‘う’: ‘ウ’, ‘え’: ‘エ’, ‘お’: ‘オ’, ‘か’: ‘カ’, ‘き’: ‘キ’, ‘く’: ‘ク’, ‘け’: ‘ケ’, ‘こ’: ‘コ’, ‘さ’: ‘サ’, ‘し’: ‘シ’, ‘す’: ‘ス’, ‘せ’: ‘セ’, ‘そ’: ‘ソ’, ‘た’: ‘タ’, ‘ち’: ‘チ’, ‘つ’: ‘ツ’, ‘て’: ‘テ’, ‘と’: ‘ト’, ‘な’: ‘ナ’, ‘に’: ‘ニ’, ‘ぬ’: ‘ヌ’, ‘ね’: ‘ネ’, ‘の’: ‘ノ’, ‘は’: ‘ハ’, ‘ひ’: ‘ヒ’, ‘ふ’: ‘フ’, ‘へ’: ‘ヘ’, ‘ほ’: ‘ホ’, ‘ま’: ‘マ’, ‘み’: ‘ミ’, ‘む’: ‘ム’, ‘め’: ‘メ’, ‘も’: ‘モ’, ‘や’: ‘ヤ’, ‘ゆ’: ‘ユ’, ‘よ’: ‘ヨ’, ‘ら’: ‘ラ’, ‘り’: ‘リ’, ‘る’: ‘ル’, ‘れ’: ‘レ’, ‘ろ’: ‘ロ’, ‘わ’: ‘ワ’, ‘を’: ‘ヲ’, ‘ん’: ‘ン’, ‘が’: ‘ガ’, ‘ぎ’: ‘ギ’, ‘ぐ’: ‘グ’, ‘げ’: ‘ゲ’, ‘ご’: ‘ゴ’, ‘ざ’: ‘ザ’, ‘じ’: ‘ジ’, ‘ず’: ‘ズ’, ‘ぜ’: ‘ゼ’, ‘ぞ’: ‘ゾ’, ‘だ’: ‘ダ’, ‘ぢ’: ‘ヂ’, ‘づ’: ‘ヅ’, ‘で’: ‘デ’, ‘ど’: ‘ド’, ‘ば’: ‘バ’, ‘び’: ‘ビ’, ‘ぶ’: ‘ブ’, ‘べ’: ‘ベ’, ‘ぼ’: ‘ボ’, ‘ぱ’: ‘パ’, ‘ぴ’: ‘ピ’, ‘ぷ’: ‘プ’, ‘ぺ’: ‘ペ’, ‘ぽ’: ‘ポ’, ‘きゃ’: ‘キャ’, ‘きゅ’: ‘キュ’, ‘きょ’: ‘キョ’, ‘しゃ’: ‘シャ’, ‘しゅ’: ‘シュ’, ‘しょ’: ‘ショ’, ‘ちゃ’: ‘チャ’, ‘ちゅ’: ‘チュ’, ‘ちょ’: ‘チョ’, ‘にゃ’: ‘ニャ’, ‘にゅ’: ‘ニュ’, ‘にょ’: ‘ニョ’, ‘ひゃ’: ‘ヒャ’, ‘ひゅ’: ‘ヒュ’, ‘ひょ’: ‘ヒョ’, ‘みゃ’: ‘ミャ’, ‘みゅ’: ‘ミュ’, ‘みょ’: ‘ミョ’, ‘りゃ’: ‘リャ’, ‘りゅ’: ‘リュ’, ‘りょ’: ‘リョ’, ‘ぎゃ’: ‘ギャ’, ‘ぎゅ’: ‘ギュ’, ‘ぎょ’: ‘ギョ’, ‘じゃ’: ‘ジャ’, ‘じゅ’: ‘ジュ’, ‘じょ’: ‘ジョ’, ‘びゃ’: ‘ビャ’, ‘びゅ’: ‘ビュ’, ‘びょ’: ‘ビョ’, ‘ぴゃ’: ‘ピャ’, ‘ぴゅ’: ‘ピュ’, ‘ぴょ’: ‘ピョ’ }, // Katakana to Hiragana (reverse of above) ‘katakana-to-hiragana’: Object.fromEntries( Object.entries({ ‘ア’: ‘あ’, ‘イ’: ‘い’, ‘ウ’: ‘う’, ‘エ’: ‘え’, ‘オ’: ‘お’, ‘カ’: ‘か’, ‘キ’: ‘き’, ‘ク’: ‘く’, ‘ケ’: ‘け’, ‘コ’: ‘こ’, ‘サ’: ‘さ’, ‘シ’: ‘し’, ‘ス’: ‘す’, ‘セ’: ‘せ’, ‘ソ’: ‘そ’, ‘タ’: ‘た’, ‘チ’: ‘ち’, ‘ツ’: ‘つ’, ‘テ’: ‘て’, ‘ト’: ‘と’, ‘ナ’: ‘な’, ‘ニ’: ‘に’, ‘ヌ’: ‘ぬ’, ‘ネ’: ‘ね’, ‘ノ’: ‘の’, ‘ハ’: ‘は’, ‘ヒ’: ‘ひ’, ‘フ’: ‘ふ’, ‘ヘ’: ‘へ’, ‘ホ’: ‘ほ’, ‘マ’: ‘ま’, ‘ミ’: ‘み’, ‘ム’: ‘む’, ‘メ’: ‘め’, ‘モ’: ‘も’, ‘ヤ’: ‘や’, ‘ユ’: ‘ゆ’, ‘ヨ’: ‘よ’, ‘ラ’: ‘ら’, ‘リ’: ‘り’, ‘ル’: ‘る’, ‘レ’: ‘れ’, ‘ロ’: ‘ろ’, ‘ワ’: ‘わ’, ‘ヲ’: ‘を’, ‘ン’: ‘ん’, ‘ガ’: ‘が’, ‘ギ’: ‘ぎ’, ‘グ’: ‘ぐ’, ‘ゲ’: ‘げ’, ‘ゴ’: ‘ご’, ‘ザ’: ‘ざ’, ‘ジ’: ‘じ’, ‘ズ’: ‘ず’, ‘ゼ’: ‘ぜ’, ‘ゾ’: ‘ぞ’, ‘ダ’: ‘だ’, ‘ヂ’: ‘ぢ’, ‘ヅ’: ‘づ’, ‘デ’: ‘で’, ‘ド’: ‘ど’, ‘バ’: ‘ば’, ‘ビ’: ‘び’, ‘ブ’: ‘ぶ’, ‘ベ’: ‘べ’, ‘ボ’: ‘ぼ’, ‘パ’: ‘ぱ’, ‘ピ’: ‘ぴ’, ‘プ’: ‘ぷ’, ‘ペ’: ‘ぺ’, ‘ポ’: ‘ぽ’, ‘キャ’: ‘きゃ’, ‘キュ’: ‘きゅ’, ‘キョ’: ‘きょ’, ‘シャ’: ‘しゃ’, ‘シュ’: ‘しゅ’, ‘ショ’: ‘しょ’, ‘チャ’: ‘ちゃ’, ‘チュ’: ‘ちゅ’, ‘チョ’: ‘ちょ’, ‘ニャ’: ‘にゃ’, ‘ニュ’: ‘にゅ’, ‘ニョ’: ‘にょ’, ‘ヒャ’: ‘ひゃ’, ‘ヒュ’: ‘ひゅ’, ‘ヒョ’: ‘ひょ’, ‘ミャ’: ‘みゃ’, ‘ミュ’: ‘みゅ’, ‘ミョ’: ‘みょ’, ‘リャ’: ‘りゃ’, ‘リュ’: ‘りゅ’, ‘リョ’: ‘りょ’, ‘ギャ’: ‘ぎゃ’, ‘ギュ’: ‘ぎゅ’, ‘ギョ’: ‘ぎょ’, ‘ジャ’: ‘じゃ’, ‘ジュ’: ‘じゅ’, ‘ジョ’: ‘じょ’, ‘ビャ’: ‘びゃ’, ‘ビュ’: ‘びゅ’, ‘ビョ’: ‘びょ’, ‘ピャ’: ‘ぴゃ’, ‘ピュ’: ‘ぴゅ’, ‘ピョ’: ‘ぴょ’ }).map(([k, v]) => [v, k]) ), // Romaji to Hiragana ‘romaji-to-hiragana’: { ‘a’: ‘あ’, ‘i’: ‘い’, ‘u’: ‘う’, ‘e’: ‘え’, ‘o’: ‘お’, ‘ka’: ‘か’, ‘ki’: ‘き’, ‘ku’: ‘く’, ‘ke’: ‘け’, ‘ko’: ‘こ’, ‘sa’: ‘さ’, ‘shi’: ‘し’, ‘su’: ‘す’, ‘se’: ‘せ’, ‘so’: ‘そ’, ‘ta’: ‘た’, ‘chi’: ‘ち’, ‘tsu’: ‘つ’, ‘te’: ‘て’, ‘to’: ‘と’, ‘na’: ‘な’, ‘ni’: ‘に’, ‘nu’: ‘ぬ’, ‘ne’: ‘ね’, ‘no’: ‘の’, ‘ha’: ‘は’, ‘hi’: ‘ひ’, ‘fu’: ‘ふ’, ‘he’: ‘へ’, ‘ho’: ‘ほ’, ‘ma’: ‘ま’, ‘mi’: ‘み’, ‘mu’: ‘む’, ‘me’: ‘め’, ‘mo’: ‘も’, ‘ya’: ‘や’, ‘yu’: ‘ゆ’, ‘yo’: ‘よ’, ‘ra’: ‘ら’, ‘ri’: ‘り’, ‘ru’: ‘る’, ‘re’: ‘れ’, ‘ro’: ‘ろ’, ‘wa’: ‘わ’, ‘wo’: ‘を’, ‘n’: ‘ん’, ‘ga’: ‘が’, ‘gi’: ‘ぎ’, ‘gu’: ‘ぐ’, ‘ge’: ‘げ’, ‘go’: ‘ご’, ‘za’: ‘ざ’, ‘ji’: ‘じ’, ‘zu’: ‘ず’, ‘ze’: ‘ぜ’, ‘zo’: ‘ぞ’, ‘da’: ‘だ’, ‘di’: ‘ぢ’, ‘du’: ‘づ’, ‘de’: ‘で’, ‘do’: ‘ど’, ‘ba’: ‘ば’, ‘bi’: ‘び’, ‘bu’: ‘ぶ’, ‘be’: ‘べ’, ‘bo’: ‘ぼ’, ‘pa’: ‘ぱ’, ‘pi’: ‘ぴ’, ‘pu’: ‘ぷ’, ‘pe’: ‘ぺ’, ‘po’: ‘ぽ’, ‘kya’: ‘きゃ’, ‘kyu’: ‘きゅ’, ‘kyo’: ‘きょ’, ‘sha’: ‘しゃ’, ‘shu’: ‘しゅ’, ‘sho’: ‘しょ’, ‘cha’: ‘ちゃ’, ‘chu’: ‘ちゅ’, ‘cho’: ‘ちょ’, ‘nya’: ‘にゃ’, ‘nyu’: ‘にゅ’, ‘nyo’: ‘にょ’, ‘hya’: ‘ひゃ’, ‘hyu’: ‘ひゅ’, ‘hyo’: ‘ひょ’, ‘mya’: ‘みゃ’, ‘myu’: ‘みゅ’, ‘myo’: ‘みょ’, ‘rya’: ‘りゃ’, ‘ryu’: ‘りゅ’, ‘ryo’: ‘りょ’, ‘gya’: ‘ぎゃ’, ‘gyu’: ‘ぎゅ’, ‘gyo’: ‘ぎょ’, ‘ja’: ‘じゃ’, ‘ju’: ‘じゅ’, ‘jo’: ‘じょ’, ‘bya’: ‘びゃ’, ‘byu’: ‘びゅ’, ‘byo’: ‘びょ’, ‘pya’: ‘ぴゃ’, ‘pyu’: ‘ぴゅ’, ‘pyo’: ‘ぴょ’ } }; // Formality level adjustments const formalityAdjustments = { ‘casual’: { ‘arigatou’: ‘thanks’, ‘sumimasen’: ‘sorry’, ‘onegaishimasu’: ‘please’ }, ‘polite’: { ‘arigatou’: ‘arigatou gozaimasu’, ‘sumimasen’: ‘sumimasen’, ‘onegaishimasu’: ‘onegaishimasu’ }, ‘formal’: { ‘arigatou’: ‘moushiwake arimasen’, ‘sumimasen’: ‘shitsurei shimasu’, ‘onegaishimasu’: ‘yoroshiku onegai itashimasu’ } }; // Form submission handler document.getElementById(‘wpc-conversion-form’).addEventListener(‘submit’, function(e) { e.preventDefault(); const startTime = performance.now(); const inputText = document.getElementById(‘wpc-input-text’).value.trim(); const conversionType = document.getElementById(‘wpc-conversion-type’).value; const formalityLevel = document.getElementById(‘wpc-formality-level’).value; if (!inputText) { alert(‘Vui lòng nhập văn bản cần chuyển đổi’); return; } // Process conversion let convertedText = ”; let romajiText = ”; let charCount = 0; if (conversionType === ‘vi-to-ja’ || conversionType === ‘vi-to-ja-kanji’) { // Vietnamese to Japanese const words = inputText.toLowerCase().split(/\s+/); const results = []; for (const word of words) { if (conversionData[conversionType][word]) { results.push(conversionData[conversionType][word]); } else { // Fallback to Katakana for unknown words results.push(convertToKatakana(word)); } } convertedText = results.join(‘ ‘); romajiText = convertToRomaji(convertedText); charCount = convertedText.length; // Apply formality adjustments if (formalityLevel !== ‘casual’) { const adjustments = formalityAdjustments[formalityLevel]; for (const [original, formal] of Object.entries(adjustments)) { convertedText = convertedText.replace(new RegExp(`\\b${original}\\b`, ‘g’), formal); } } } else if (conversionType === ‘ja-to-vi’) { // Japanese to Vietnamese const words = inputText.split(/([\s、。!?]+)/); const results = []; for (const word of words) { if (word.trim() === ” || /^[、。!?\s]+$/.test(word)) { results.push(word); continue; } if (conversionData[conversionType][word]) { results.push(conversionData[conversionType][word]); } else { // Keep original if no translation found results.push(word); } } convertedText = results.join(”); romajiText = convertToRomaji(inputText); charCount = inputText.length; } else if (conversionType === ‘hiragana-to-katakana’) { // Hiragana to Katakana convertedText = ”; for (const char of inputText) { convertedText += conversionData[conversionType][char] || char; } romajiText = convertToRomaji(convertedText); charCount = convertedText.length; } else if (conversionType === ‘katakana-to-hiragana’) { // Katakana to Hiragana convertedText = ”; for (const char of inputText) { convertedText += conversionData[conversionType][char] || char; } romajiText = convertToRomaji(convertedText); charCount = convertedText.length; } else if (conversionType === ‘romaji-to-hiragana’) { // Romaji to Hiragana convertedText = ”; let i = 0; while (i < inputText.length) { let found = false; // Check for 3-character combinations first (like 'sho') for (let len = 3; len >= 1; len–) { if (i + len <= inputText.length) { const substring = inputText.substr(i, len).toLowerCase(); if (conversionData[conversionType][substring]) { convertedText += conversionData[conversionType][substring]; i += len; found = true; break; } } } if (!found) { convertedText += inputText[i]; i++; } } romajiText = inputText; // Already in Romaji charCount = convertedText.length; } const processingTime = (performance.now() - startTime).toFixed(2); // Display results document.getElementById('wpc-converted-text').textContent = convertedText; document.getElementById('wpc-romaji').textContent = romajiText; document.getElementById('wpc-char-count').textContent = charCount + ' ký tự'; document.getElementById('wpc-processing-time').textContent = processingTime + ' ms'; document.getElementById('wpc-results').style.display = 'block'; // Update chart updateChart(inputText.length, charCount, processingTime, conversionType); }); // Helper function to convert to Katakana (for unknown Vietnamese words) function convertToKatakana(text) { // Simple conversion for demonstration - in real app you'd use a proper library const katakanaMap = { 'a': 'ア', 'ă': 'ア', 'â': 'ア', 'b': 'ブ', 'c': 'ク', 'd': 'ド', 'đ': 'ド', 'e': 'エ', 'ê': 'エ', 'g': 'グ', 'h': 'ハ', 'i': 'イ', 'k': 'ク', 'l': 'ル', 'm': 'ム', 'n': 'ン', 'o': 'オ', 'ô': 'オ', 'ơ': 'オ', 'p': 'プ', 'q': 'ク', 'r': 'ル', 's': 'ス', 't': 'ト', 'u': 'ウ', 'ư': 'ウ', 'v': 'ブ', 'x': 'クス', 'y': 'イ' }; let result = ''; for (const char of text.toLowerCase()) { result += katakanaMap[char] || char; } return result; } // Helper function to convert to Romaji (simplified) function convertToRomaji(text) { const hiraganaToRomaji = { 'あ': 'a', 'い': 'i', 'う': 'u', 'え': 'e', 'お': 'o', 'か': 'ka', 'き': 'ki', 'く': 'ku', 'け': 'ke', 'こ': 'ko', 'さ': 'sa', 'し': 'shi', 'す': 'su', 'せ': 'se', 'そ': 'so', 'た': 'ta', 'ち': 'chi', 'つ': 'tsu', 'て': 'te', 'と': 'to', 'な': 'na', 'に': 'ni', 'ぬ': 'nu', 'ね': 'ne', 'の': 'no', 'は': 'ha', 'ひ': 'hi', 'ふ': 'fu', 'へ': 'he', 'ほ': 'ho', 'ま': 'ma', 'み': 'mi', 'む': 'mu', 'め': 'me', 'も': 'mo', 'や': 'ya', 'ゆ': 'yu', 'よ': 'yo', 'ら': 'ra', 'り': 'ri', 'る': 'ru', 'れ': 're', 'ろ': 'ro', 'わ': 'wa', 'を': 'wo', 'ん': 'n', 'が': 'ga', 'ぎ': 'gi', 'ぐ': 'gu', 'げ': 'ge', 'ご': 'go', 'ざ': 'za', 'じ': 'ji', 'ず': 'zu', 'ぜ': 'ze', 'ぞ': 'zo', 'だ': 'da', 'ぢ': 'ji', 'づ': 'zu', 'で': 'de', 'ど': 'do', 'ば': 'ba', 'び': 'bi', 'ぶ': 'bu', 'べ': 'be', 'ぼ': 'bo', 'ぱ': 'pa', 'ぴ': 'pi', 'ぷ': 'pu', 'ぺ': 'pe', 'ぽ': 'po', 'きゃ': 'kya', 'きゅ': 'kyu', 'きょ': 'kyo', 'しゃ': 'sha', 'しゅ': 'shu', 'しょ': 'sho', 'ちゃ': 'cha', 'ちゅ': 'chu', 'ちょ': 'cho', 'にゃ': 'nya', 'にゅ': 'nyu', 'にょ': 'nyo', 'ひゃ': 'hya', 'ひゅ': 'hyu', 'ひょ': 'hyo', 'みゃ': 'mya', 'みゅ': 'myu', 'みょ': 'myo', 'りゃ': 'rya', 'りゅ': 'ryu', 'りょ': 'ryo', 'ぎゃ': 'gya', 'ぎゅ': 'gyu', 'ぎょ': 'gyo', 'じゃ': 'ja', 'じゅ': 'ju', 'じょ': 'jo', 'びゃ': 'bya', 'びゅ': 'byu', 'びょ': 'byo', 'ぴゃ': 'pya', 'ぴゅ': 'pyu', 'ぴょ': 'pyo' }; const katakanaToRomaji = { 'ア': 'a', 'イ': 'i', 'ウ': 'u', 'エ': 'e', 'オ': 'o', 'カ': 'ka', 'キ': 'ki', 'ク': 'ku', 'ケ': 'ke', 'コ': 'ko', 'サ': 'sa', 'シ': 'shi', 'ス': 'su', 'セ': 'se', 'ソ': 'so', 'タ': 'ta', 'チ': 'chi', 'ツ': 'tsu', 'テ': 'te', 'ト': 'to', 'ナ': 'na', 'ニ': 'ni', 'ヌ': 'nu', 'ネ': 'ne', 'ノ': 'no', 'ハ': 'ha', 'ヒ': 'hi', 'フ': 'fu', 'ヘ': 'he', 'ホ': 'ho', 'マ': 'ma', 'ミ': 'mi', 'ム': 'mu', 'メ': 'me', 'モ': 'mo', 'ヤ': 'ya', 'ユ': 'yu', 'ヨ': 'yo', 'ラ': 'ra', 'リ': 'ri', 'ル': 'ru', 'レ': 're', 'ロ': 'ro', 'ワ': 'wa', 'ヲ': 'wo', 'ン': 'n', 'ガ': 'ga', 'ギ': 'gi', 'グ': 'gu', 'ゲ': 'ge', 'ゴ': 'go', 'ザ': 'za', 'ジ': 'ji', 'ズ': 'zu', 'ゼ': 'ze', 'ゾ': 'zo', 'ダ': 'da', 'ヂ': 'ji', 'ヅ': 'zu', 'デ': 'de', 'ド': 'do', 'バ': 'ba', 'ビ': 'bi', 'ブ': 'bu', 'ベ': 'be', 'ボ': 'bo', 'パ': 'pa', 'ピ': 'pi', 'プ': 'pu', 'ペ': 'pe', 'ポ': 'po', 'キャ': 'kya', 'キュ': 'kyu', 'キョ': 'kyo', 'シャ': 'sha', 'シュ': 'shu', 'ショ': 'sho', 'チャ': 'cha', 'チュ': 'chu', 'チョ': 'cho', 'ニャ': 'nya', 'ニュ': 'nyu', 'ニョ': 'nyo', 'ヒャ': 'hya', 'ヒュ': 'hyu', 'ヒョ': 'hyo', 'ミャ': 'mya', 'ミュ': 'myu', 'ミョ': 'myo', 'リャ': 'rya', 'リュ': 'ryu', 'リョ': 'ryo', 'ギャ': 'gya', 'ギュ': 'gyu', 'ギョ': 'gyo', 'ジャ': 'ja', 'ジュ': 'ju', 'ジョ': 'jo', 'ビャ': 'bya', 'ビュ': 'byu', 'ビョ': 'byo', 'ピャ': 'pya', 'ピュ': 'pyu', 'ピョ': 'pyo' }; let result = ''; let i = 0; while (i < text.length) { // Check for 2-character combinations first (like 'しゃ') if (i + 1 < text.length) { const doubleChar = text.substr(i, 2); if (hiraganaToRomaji[doubleChar] || katakanaToRomaji[doubleChar]) { result += (hiraganaToRomaji[doubleChar] || katakanaToRomaji[doubleChar]); i += 2; continue; } } // Check single character const singleChar = text[i]; if (hiraganaToRomaji[singleChar] || katakanaToRomaji[singleChar]) { result += (hiraganaToRomaji[singleChar] || katakanaToRomaji[singleChar]); } else { result += singleChar; // Keep original if not found } i++; } return result; } // Update chart function function updateChart(originalLength, convertedLength, processingTime, conversionType) { const ctx = document.getElementById('wpc-chart').getContext('2d'); // Destroy previous chart if it exists if (window.conversionChart) { window.conversionChart.destroy(); } // Chart data const typeLabels = { 'vi-to-ja': 'Việt → Nhật (Romaji)', 'vi-to-ja-kanji': 'Việt → Nhật (Kanji)', 'ja-to-vi': 'Nhật → Việt', 'hiragana-to-katakana': 'Hiragana → Katakana', 'katakana-to-hiragana': 'Katakana → Hiragana', 'romaji-to-hiragana': 'Romaji → Hiragana' }; window.conversionChart = new Chart(ctx, { type: 'bar', data: { labels: ['Độ dài gốc', 'Độ dài sau chuyển đổi', 'Thời gian xử lý (ms)'], datasets: [{ label: `Loại chuyển đổi: ${typeLabels[conversionType]}`, data: [originalLength, convertedLength, parseFloat(processingTime)], backgroundColor: [ '#2563eb', '#1d4ed8', '#1e40af' ], borderColor: [ '#2563eb', '#1d4ed8', '#1e40af' ], borderWidth: 1 }] }, options: { responsive: true, maintainAspectRatio: false, scales: { y: { beginAtZero: true, title: { display: true, text: 'Giá trị' } } }, plugins: { legend: { position: 'top', }, title: { display: true, text: 'Thống kê chuyển đổi', font: { size: 16 } }, tooltip: { callbacks: { label: function(context) { let label = context.dataset.label || ''; if (label) { label += ': '; } if (context.parsed.y !== null) { if (context.dataIndex === 0 || context.dataIndex === 1) { label += context.parsed.y + ' ký tự'; } else { label += context.parsed.y + ' ms'; } } return label; } } } } } }); } // Initialize chart with empty data const ctx = document.getElementById('wpc-chart').getContext('2d'); window.conversionChart = new Chart(ctx, { type: 'bar', data: { labels: ['Độ dài gốc', 'Độ dài sau chuyển đổi', 'Thời gian xử lý'], datasets: [{ label: 'Chưa có dữ liệu', data: [0, 0, 0], backgroundColor: [ '#e2e8f0', '#e2e8f0', '#e2e8f0' ], borderColor: [ '#e2e8f0', '#e2e8f0', '#e2e8f0' ], borderWidth: 1 }] }, options: { responsive: true, maintainAspectRatio: false, scales: { y: { beginAtZero: true } }, plugins: { legend: { display: false }, title: { display: true, text: 'Thống kê chuyển đổi sẽ xuất hiện ở đây', font: { size: 14 }, color: '#64748b' } } } }); });