JavaScript

Last-modified: 2026-04-01 (水) 00:32:43

JavaScript

サンプル

ミニブログ(indexedDBに登録する)自分のChromeやEdgeのみ保存・閲覧できる

let db;
// DBオープン
const request = indexedDB.open("miniBlogDB", 1);
request.onupgradeneeded = e => {
 db = e.target.result;
 db.createObjectStore("blogs", {
   keyPath: "id",
   autoIncrement: true
 });
};
request.onsuccess = e => {
 db = e.target.result;
 // 今日の日付を自動セット
 setTodayDate();
 showAll();
};
// 今日の日付をセットする共通処理
function setTodayDate() {
 const today = new Date();
 const yyyy = today.getFullYear();
 const mm = String(today.getMonth() + 1).padStart(2, "0");
 const dd = String(today.getDate()).padStart(2, "0");
 document.getElementById("blogDate").value = `${yyyy}-${mm}-${dd}`;
}
// 登録処理
document.getElementById("saveBtn").onclick = () => {
 const date = document.getElementById("blogDate").value;
 const content = document.getElementById("blogContent").value;
 if (!date || !content) {
   alert("日付と内容を入力してください");
   return;
 }
 const tx = db.transaction("blogs", "readwrite");
 const store = tx.objectStore("blogs");
 store.add({
   date: date,
   content: content,
   createdAt: new Date()
 });
 tx.oncomplete = () => {
   document.getElementById("blogContent").value = "";
   setTodayDate();
   showAll();
 };
};
// 検索処理
document.getElementById("searchBtn").onclick = () => {
 const word = document.getElementById("searchWord").value;
 search(word);
};
// 全件表示(新しい順)
function showAll() {
 const result = document.getElementById("result");
 result.innerHTML = "";
 const tx = db.transaction("blogs", "readonly");
 const store = tx.objectStore("blogs");
 store.openCursor(null, "prev").onsuccess = e => {
   const cursor = e.target.result;
   if (cursor) {
     render(cursor.value);
     cursor.continue();
   }
 };
}
// 検索表示(新しい順)
function search(word) {
 const result = document.getElementById("result");
 result.innerHTML = "";
 const tx = db.transaction("blogs", "readonly");
 const store = tx.objectStore("blogs");
 store.openCursor(null, "prev").onsuccess = e => {
   const cursor = e.target.result;
   if (cursor) {
     const v = cursor.value;
     if (v.date.includes(word) || v.content.includes(word)) {
       render(v);
     }
     cursor.continue();
   }
 };
}
// 表示用(日付を除外して内容のみをコピー)
function render(data) {
 const div = document.createElement("div");
 div.className = "blog-item";
 // レイアウト用のスタイル(JavaScriptで直接指定)
 div.style.display = "flex";
 div.style.alignItems = "flex-start";
 div.style.marginBottom = "15px";
 div.style.padding = "10px";
 div.style.borderBottom = "1px solid #eee";
 // コピーボタンの作成
 const copyBtn = document.createElement("button");
 copyBtn.innerText = "コピー";
 copyBtn.style.marginRight = "15px";
 copyBtn.style.padding = "5px 10px";
 copyBtn.style.cursor = "pointer";
 // クリックイベント:日付を除外して「内容」のみコピー
 copyBtn.onclick = () => {
   const textToCopy = data.content; // 内容のみ取得
   navigator.clipboard.writeText(textToCopy).then(() => {
     // 成功時のフィードバック
     const originalText = copyBtn.innerText;
     copyBtn.innerText = "完了!";
     copyBtn.style.backgroundColor = "#d4edda";
     setTimeout(() => {
       copyBtn.innerText = originalText;
       copyBtn.style.backgroundColor = "";
     }, 1000);
   }).catch(err => {
     console.error('コピーに失敗しました', err);
   });
 };
 // テキスト表示部分の作成
 const textDiv = document.createElement("div");
 const formattedContent = data.content.replace(/\n/g, "<br>");
 textDiv.innerHTML = `
   <small style="color: #666;">${data.date}</small><br>
   <div style="margin-top: 5px;">${formattedContent}</div>
 `;
 div.appendChild(copyBtn);
 div.appendChild(textDiv);
 document.getElementById("result").appendChild(div);
}
// CSVエクスポート関連
document.getElementById("exportCsvBtn").onclick = () => {
 exportCsv();
};
function exportCsv() {
 const tx = db.transaction("blogs", "readonly");
 const store = tx.objectStore("blogs");
 const rows = [["日付", "内容", "登録日時"]];
 store.openCursor().onsuccess = e => {
   const cursor = e.target.result;
   if (cursor) {
     const v = cursor.value;
     rows.push([
       v.date,
       v.content.replace(/\n/g, " "),
       new Date(v.createdAt).toLocaleString()
     ]);
     cursor.continue();
   } else {
     downloadCsv(rows);
   }
 };
}
function downloadCsv(rows) {
 const csv = rows.map(r => r.map(v => `"${v}"`).join(",")).join("\n");
 // BOM付きUTF-8で出力(Excelでの文字化け防止)
 const blob = new Blob([new Uint8Array([0xEF, 0xBB, 0xBF]), csv], { type: "text/csv;charset=utf-8;" });
 const url = URL.createObjectURL(blob);
 const a = document.createElement("a");
 a.href = url;
 a.download = "mini_blog.csv";
 a.click();
 URL.revokeObjectURL(url);
}

組み合わせ

GoogleChart ローソク足と出来高を表示させるグラフ

<!DOCTYPE html>
<html>
 <head>
   <title>ローソク足と出来高チャート</title>
   <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
   <script type="text/javascript">
     google.charts.load('current', { packages: ['corechart', 'controls'] });
     google.charts.setOnLoadCallback(drawChart);
     function drawChart() {
       var data = new google.visualization.DataTable();
       data.addColumn('string', '日付');
       data.addColumn('number', 'ローソク足(最低値)');
       data.addColumn('number', 'ローソク足(始値)');
       data.addColumn('number', 'ローソク足(終値)');
       data.addColumn('number', 'ローソク足(最高値)');
       data.addColumn('number', '出来高');
       data.addRows([
         ['900', 800, 850, 870, 890, 50000],
         ['901', 820, 900, 820, 900, 160000],
         ['902', 830, 910, 890, 910, 370000],
         ['903', 840, 880, 900, 920, 80000],
         ['904', 850, 890, 910, 1130, 90000]
       ]);
       var chartDiv = document.getElementById('chart_div');
       var candleChart = new google.visualization.CandlestickChart(chartDiv);
       candleChart.draw(data, {
         title: 'ローソク足と出来高チャート',
         legend: 'none',
         seriesType: 'candlesticks',
         series: {
           0: {type: 'candlesticks'},
           1: {
             type: 'line',
             targetAxisIndex: 1,
             color: 'blue',
             lineWidth: 2
           }
         },
         vAxes: {
           0: {
             title: '価格',
             ticks: [{v:850, f:'¥850'},{v:950, f:'¥950'}, 800, 1100], // 900円の位置に赤い目盛り線を追加
             textStyle: { color: 'red' },
             baselineColor: 'red',
             gridlines: { color: 'transparent' },
             minorGridlines: { color: 'transparent' }
           },
           1: {title: '出来高'}
         },
         hAxis: {
           title: '時刻'
         },
         vAxis: {
           0: {
             format: 'short'
           },
           1: {
             format: 'short'
           }
         }
       });
     }
   </script>
 </head>
 <body>
   <div id="chart_div" style="width: 900px; height: 500px;"></div>
 </body>
</html>

参考

サイト内リンク

マクロ/スクリプト