「JavaScript で2つの PDF のテキストの差分を検出」を Qiita に投稿しました。
JavaScript で配列を連結する方法のメモ。
以下の3つの方法を試してみます。
- concat()
- [...a, ...b]
- push()
> a = [0, 1, 2, 3]; > b = [4, 5, 6, 7]; # concat() の場合 > c = a.concat(b); [0, 1, 2, 3, 4, 5, 6, 7] > a; [0, 1, 2, 3] # a は変更なし # [...a, ...b] の場合 > c = [...a, ...b]; [0, 1, 2, 3, 4, 5, 6, 7] > a; [0, 1, 2, 3] # a は変更なし # push() の場合 > c = a.push(...b); 8 # 配列の長さが返却される > a; [0, 1, 2, 3, 4, 5, 6, 7] # a に追加される
JavaScript で数値を3桁の,区切りの文字列に変換する方法のメモ。
1. 正規表現を利用
> a = 123456789; > String(a).replace(/\B(?=(\d{3})+(?!\d))/g, ","); '123,456,789'
2. toLocaleString() を利用
> a = 123456789; > a.toLocaleString(); '123,456,789'
Quill でリッチテキストを編集する方法のメモ。
toolbar で表示するメニューを指定することができます。
■HTML
■リッチテキストのデータ形式
getContents() でリッチテキストのデータを取得すできます。
■HTML での表示
getSemanticHTML() で入力内容をHTML化できます。
toolbar で表示するメニューを指定することができます。
■HTML
<!DOCTYPE html><html><head><link href="https://cdn.jsdelivr.net/npm/quill@2.0.1/dist/quill.snow.css" rel="stylesheet" /><script src="https://cdn.jsdelivr.net/npm/quill@2.0.1/dist/quill.js"></script><title>Quill</title></head><body><form></form><button onclick="show_contents()">submit</button>
<script type="text/javascript">function show_contents() {document.getElementById('editor-contents').innerHTML = quill.getSemanticHTML();console.log(JSON.stringify(quill.getContents()));}const options = {theme: 'snow',placeholder: '本文を入力してください',modules: {toolbar: [['bold', 'italic', 'link']],},};const quill = new Quill('#editor', options);</script></body></html>
■リッチテキストのデータ形式
getContents() でリッチテキストのデータを取得すできます。
{"ops": [{"insert":"aaa\n"},{"attributes":{"bold":true},"insert":"bbb"},{"insert":"\n"},{"attributes":{"italic":true,"bold":true}, "insert":"ccc"},{"insert":"\n"},{"attributes":{"link":"https://www.goo.ne.jp/"},"insert":"ddd"},{"insert":"\neee\n"}]}
■HTML での表示
getSemanticHTML() で入力内容をHTML化できます。
JavaScript で画像の各ピクセルの色の取得する方法のメモ。
read_image() で画像を読み込み、画像を読み込み終えたら、
raw_image() でcanvas に画像を描画します。
そして、16 ピクセル x 16 ピクセル単位で色の平均値を計算し、
その色で枠を描画しています。
各ピクセルの r, g, b, a(透明度) は以下で取得することができます。
r = img_data.data[(x + y*w)*4];
g = img_data.data[1 + (x + y*w)*4];
b = img_data.data[2 + (x + y*w)*4];
a = img_data.data[3 + (x + y*w)*4];
read_image() で画像を読み込み、画像を読み込み終えたら、
raw_image() でcanvas に画像を描画します。
そして、16 ピクセル x 16 ピクセル単位で色の平均値を計算し、
その色で枠を描画しています。
各ピクセルの r, g, b, a(透明度) は以下で取得することができます。
r = img_data.data[(x + y*w)*4];
g = img_data.data[1 + (x + y*w)*4];
b = img_data.data[2 + (x + y*w)*4];
a = img_data.data[3 + (x + y*w)*4];
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>image processing</title> </head> <body> 画像処理 <div id="img_area"></div> </body> &;lt;script type="text/javascript"> (() => { function draw_image(params) { const img_area_obj = document.getElementById(params.img_area); const img_obj = params.img_obj; const cv_obj = document.createElement('canvas'); cv_obj.width = img_obj.naturalWidth; cv_obj.height = img_obj.naturalHeight; const ct = cv_obj.getContext('2d'); ct.drawImage(img_obj, 0, 0); img_area_obj.appendChild(cv_obj); const img_data = ct.getImageData(0, 0, img_obj.width, img_obj.height); // 枠 draw_cell_frame(ct, img_data, 16); } function draw_cell_frame(ct, img_data, size) { for (let y = 0; y < img_data.height; y += size) { for (let x = 0; x < img_data.width; x += size) { let avg_col = avg_cell_color(img_data, x, y, size); ct.strokeStyle = `#${avg_col[0]}${avg_col[1]}${avg_col[2]}`; ct.strokeRect(x, y, size, size); } } } function avg_cell_color(img_data, min_x, min_y, size) { const w = img_data.width; const h = img_data.height; const max_x = min_x + size <= w ? min_x + size : w; const max_y = min_y + size <= h ? min_y + size : h; let sum_r = 0, sum_g = 0, sum_b = 0; let pixels = 0; for (let y = min_y; y < max_y; y++) { for (let x = min_x; x < max_x; x++) { pixels++; let r = img_data.data[(x + y*w)*4]; let g = img_data.data[1 + (x + y*w)*4]; let b = img_data.data[2 + (x + y*w)*4]; sum_r += r; sum_g += g; sum_b += b; } } const avg_r = Math.floor(sum_r / pixels); const avg_g = Math.floor(sum_g / pixels); const avg_b = Math.floor(sum_b / pixels); return [avg_r.toString(16), avg_g.toString(16), avg_b.toString(16)]; } function read_image(params) { const img_obj = new Image(); params.img_obj = img_obj; img_obj.onload = (() => { draw_image(params); }); img_obj.src = params.img_url; } read_image({ img_area: 'img_area', img_url: 'test.png', }); })(); </script> </html>
JavaScript で実行中の script の URL を取得する方法のメモ。
document.currentScript で実行中の script を取得することができます。
そして、document.currentScript.src で JavaScript の URL を取得することができます。
■HTML
■JavaScript (script1.js)
■実行結果
document.currentScript で実行中の script を取得することができます。
そして、document.currentScript.src で JavaScript の URL を取得することができます。
■HTML
<html> <head> <title>script</title> </head> <body> </body> <script type="text/javascript" src="script1.js"></script> </html>
■JavaScript (script1.js)
const script_url = document.currentScript.src; console.log('script url:' + script_url); const url_obj = new URL(script_url) console.log('origin: ' + url_obj.origin);
■実行結果
script url: http://localhost/script/script1.js origin: http://localhost
jQuery での DOM 操作のメモ。
以下の DOM に対して追加・削除等の操作を行います。
■末尾に追加
■指定要素の前に子を追加
■指定要素の次に子を追加
<pre>
$(`<div id="d3-5"></div>`).insertAfter($('#d3-4'));
console.log($('#d1').html());
-->
<div id="d2-1">
<div id="d3-1">
<p id="p4-1">p4-1 text</p>
<p id="p4-2">p4-2 text</p>
</div>
<div id="d3-2"></div>
</div>
<div id="d2-2">
<div id="d3-3"></div>
<div id="d3-4"></div><div id="d3-5"></div>
</div>
■指定要素を削除
■指定要素の子を削除(空にする)
■繰り返し
以下の DOM に対して追加・削除等の操作を行います。
<div id="d1"> <div id="d2-1"> <div id="d3-1"> <p id="p4-1">p4-1 text</p> <p id="p4-2">p4-2 text</p> </div> <div id="d3-2"></div> </div> <div id="d2-2"> <div id="d3-3"></div> <div id="d3-4"></div> </div> </div> </div>
■末尾に追加
$(`<div id="d2-3"></div>`).appendTo($('#d1')); console.log($('#d1').html()); --> <div id="d2-1"> <div id="d3-1"> <p id="p4-1">p4-1 text</p> <p id="p4-2">p4-2 text</p> </div> <div id="d3-2"></div> </div> <div id="d2-2"> <div id="d3-3"></div> <div id="d3-4"></div> </div> <div id="d2-3"></div>
■指定要素の前に子を追加
$(`<div id="d2-0"></div>`).insertBefore($('#d2-1')); console.log($('#d1').html()); --> <div id="d2-0"></div><div id="d2-1"> <div id="d3-1"> <p id="p4-1">p4-1 text</p> <p id="p4-2">p4-2 text</p> </div> <div id="d3-2"></div> </div> <div id="d2-2"> <div id="d3-3"></div> <div id="d3-4"></div> </div>
■指定要素の次に子を追加
<pre>
$(`<div id="d3-5"></div>`).insertAfter($('#d3-4'));
console.log($('#d1').html());
-->
<div id="d2-1">
<div id="d3-1">
<p id="p4-1">p4-1 text</p>
<p id="p4-2">p4-2 text</p>
</div>
<div id="d3-2"></div>
</div>
<div id="d2-2">
<div id="d3-3"></div>
<div id="d3-4"></div><div id="d3-5"></div>
</div>
■指定要素を削除
$('#d3-1').remove(); console.log($('#d1').html()); --> <div id="d2-1"> <div id="d3-2"></div> </div> <div id="d2-2"> <div id="d3-3"></div> <div id="d3-4"></div> </div>
■指定要素の子を削除(空にする)
$('#d3-1').empty(); console.log($('#d1').html()); --> <div id="d2-1"> <div id="d3-1"></div> <div id="d3-2"></div> </div> <div id="d2-2"> <div id="d3-3"></div> <div id="d3-4"></div> </div>
■繰り返し
$('#d3-1').children().each((i, node) => { console.log($(node).text()); }); --> p4-1 text p4-2 text
jQuery でよく使うセレクタの使い方のメモ。
以下の DOM に対してセレクタを試してみます。
■id指定
■子要素のタグ指定
■子孫のタグ指定
■子孫のタグ指定
■子孫を検索
■前の要素
■次の要素
以下の DOM に対してセレクタを試してみます。
<div id="d1"> <div id="d2-1"> <div id="d3-1"> <p id="p4-1">p4-1 text</p> <p id="p4-2">p4-2 text</p> </div> <div id="d3-2"></div> </div> <div id="d2-2"> <div id="d3-3"></div> <div id="d3-4"></div> </div> </div> </div>
■id指定
d = $('#d1'); console.log(d.attr('id')); console.log(d.constructor.name); --> d1 S
■子要素のタグ指定
ns = $('#d1 > div'); console.log(ns.length); console.log(ns[0].constructor.name); console.log($(ns[0]).attr('id')); console.log($(ns[1]).attr('id')); --> 2 HTMLDivElement d2-1 d2-2
■子孫のタグ指定
ps = $('#d1 p'); console.log(ps.length); console.log(ps[0].constructor.name); console.log($(ps[0]).text()); console.log($(ps[1]).text()); --> 2 HTMLParagraphElement p4-1 text p4-2 text
■子孫のタグ指定
ps = $('#d1 p'); console.log(ps.length); console.log($(ps[0]).text()); console.log($(ps[1]).text()); --> 2 p4-1 text p4-2 text
■子孫を検索
d = $('#d1'); ps = d.find('p'); console.log(ps.length); console.log($(ps[0]).text()); console.log($(ps[1]).text()); --> 2 selector1.html:82 p4-1 text selector1.html:83 p4-2 text
■前の要素
console.log('前の要素'); d = $('#d2-2').prev(); console.log($(d).attr('id')); --> d2-1
■次の要素
d = $('#d2-1').next(); console.log($(d).attr('id')); --> d2-2
jQuery でのイベント処理のメモ。
ボタンが押された場合のクリックイベントは、.click(() => {...}) で登録します。
以下の例では、「追加」ボタンを押下すると、その直下に行を追加します。
「削除」ボタンを押すとその行を削除します。
ボタンが押された場合のクリックイベントは、.click(() => {...}) で登録します。
以下の例では、「追加」ボタンを押下すると、その直下に行を追加します。
「削除」ボタンを押すとその行を削除します。
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>test1</title> </head> <body> <h3>jQuery でのイベント処理</h3> <table border="1"> <tbody> <tr> <td><input type="text" name="memo"></td> <td><input type="button" name="add" value="追加"></td> </tr> </tbody> </table> </body> <script type="text/javascript" src="jquery-3.6.0.min.js"></script> <script type="text/javascript"> function add_row(btn) { const new_row = $(` <tr> <td><input type="text" name="memo"></td> <td> <input type="button" name="add" value="追加"> <input type="button" name="del" value="削除"> </td> </tr> `); // ボタンが押された行の直後の行に追加 const row = btn.parent().parent(); new_row.insertAfter(row); // イベントハンドラ: 追加 const add_btn = new_row.find('input[name="add"]'); add_btn.click(() => { add_row(add_btn); }); // イベントハンドラ: 削除 const del_btn = new_row.find('input[name="del"]'); del_btn.click(() => { del_row(del_btn); }); } function del_row(btn) { // ボタンが押された行を削除 const row = btn.parent().parent(); row.remove(); } (() => { const add_btn = $('input[name="add"]'); add_btn.click(() => { add_row(add_btn); }); })(); </script> </body> </html>
d3.js で折れ線グラフを描画する方法のメモ。
<html> <head> <meta http-equiv="Content-Type" content="text/html;utf-8"> <title>graph</title> </head> <body> <div id="graph"></div> <script type="text/javascript" src="../d3.min.js"></script> <script type="text/javascript"> const org_dataset = [ ['01/01', 4], ['01/02', 5], ['01/03', 8], ['01/04', 10], ['01/05', 9], ['01/06', 12], ['01/07', 8], ['01/08', 7], ['01/09', 6], ['01/10', 8], ]; const dataset = []; for (let i = 0; i < org_dataset.length; i++) { let d = org_dataset[i]; dataset.push({date: d[0], x: i, y: d[1]}); } const width = 600; const height = 400; const margin = { "top": 40, "bottom": 40, "right": 40, "left": 40 }; const svg = d3.select("body") .append("svg") .attr("width", margin.left+width+margin.right) .attr("height", margin.top+height+margin.bottom) ; var xScale = d3.scaleLinear() .domain([0, d3.max(dataset, function(d) { return d.x; })]) .range([margin.left, margin.left+width]) ; var yScale = d3.scaleLinear() .domain([0, d3.max(dataset, function(d) { return d.y; })]) .range([margin.top+height, margin.top]) ; var xAxis = d3.axisBottom(xScale) .ticks(5) .tickFormat((d) => { return dataset[d].date; }) ; var yAxis = d3.axisLeft(yScale) .ticks(5); svg.append("g") .attr("transform", "translate(" + [0, margin.top+height].join(",") + ")") .call(xAxis) .append("text") .attr("fill", "black") .attr("x", (margin.left+width+margin.right)/2) .attr("y", margin.bottom/2) .attr("text-anchor", "middle") .attr("font-size", "10pt") .text("日付"); svg.append("g") .attr("transform", "translate(" + [margin.left, 0].join(",") + ")") .call(yAxis) .append("text") .attr("fill", "black") .attr("text-anchor", "middle") .attr("x", -(height+margin.top+margin.bottom)/2) .attr("y", -margin.left/2) .attr("transform", "rotate(-90)") .attr("font-size", "10pt") .text("値"); svg.append("path") .datum(dataset) .attr("fill", "none") .attr("stroke", "steelblue") .attr("stroke-width", 1.5) .attr("d", d3.line() .x(function(d) { return xScale(d.x); }) .y(function(d) { return yScale(d.y); }) ); </script> </body> </html>
d3.js で折れ線グラフを描画する方法のメモ。
<html> <head> <title>graph</title> </head> <body> <script type="text/javascript" src="../d3.min.js"></script> <script type="text/javascript"> const org_dataset = [ ['01/01', 4], ['01/02', 5], ['01/03', 8], ['01/04', 10], ['01/05', 9], ['01/06', 12], ['01/07', 8], ['01/08', 7], ['01/09', 6], ['01/10', 8], ]; const dataset = []; for (let i = 0; i < org_dataset.length; i++) { let d = org_dataset[i]; dataset.push({date: d[0], x: i, y: d[1]}); } const width = 600; const height = 400; const margin = { "top": 40, "bottom": 40, "right": 40, "left": 40 }; const svg = d3.select("body") .append("svg") .attr("width", margin.left+width+margin.right) .attr("height", margin.top+height+margin.bottom) ; var xScale = d3.scaleLinear() .domain([0, d3.max(dataset, function(d) { return d.x; })]) .range([margin.left, margin.left+width]) ; var yScale = d3.scaleLinear() .domain([0, d3.max(dataset, function(d) { return d.y; })]) .range([margin.top+height, margin.top]) ; var xAxis = d3.axisBottom(xScale) .ticks(5) .tickFormat((d) => { return dataset[d].date; }) ; var yAxis = d3.axisLeft(yScale) .ticks(5); svg.append("g") .attr("transform", "translate(" + [0, margin.top+height].join(",") + ")") .call(xAxis) .append("text") .attr("fill", "black") .attr("x", (margin.left+width+margin.right)/2) .attr("y", margin.bottom/2) .attr("text-anchor", "middle") .attr("font-size", "10pt") .text("日付"); svg.append("g") .attr("transform", "translate(" + [margin.left, 0].join(",") + ")") .call(yAxis) .append("text") .attr("fill", "black") .attr("text-anchor", "middle") .attr("x", -(height+margin.top+margin.bottom)/2) .attr("y", -margin.left/2) .attr("transform", "rotate(-90)") .attr("font-size", "10pt") .text("値"); svg.append("path") .datum(dataset) .attr("fill", "none") .attr("stroke", "steelblue") .attr("stroke-width", 1.5) .attr("d", d3.line() .x(function(d) { return xScale(d.x); }) .y(function(d) { return yScale(d.y); }) ); </script> </body> </html>
d3.js の散布図でクリックイベントを設定する方法のメモ。
「d3.js の散布図でマウスオーバーでメッセージを表示」の例で、以下のように .on("click", function (e) {}) を指定するとクリックイベントを処理することができます。
「d3.js の散布図でマウスオーバーでメッセージを表示」の例で、以下のように .on("click", function (e) {}) を指定するとクリックイベントを処理することができます。
svg.append("g") .selectAll("circle") .data(dataset) .enter() .append("circle") .attr("cx", function (d) { return xScale(d[0]); }) .attr("cy", function (d) { return yScale(d[1]); }) .attr("r", 10) .attr("fill", function (d) { return "rgba(0, 0, " + Math.round(colorScale(d[2])) + ", 0.8)"; }) .on("mouseover", function (e) { const d = e.target.__data__; console.log(e); tooltip .style("left", e.x + 30 + 'px') .style("top", e.y + 'px') .html( "id: " + d[3] + "" + "[" + d[0] + ", " + d[1] + "]" + "" + "value: " + d[2] ) .style("opacity", 1) ; }) .on("mouseout", function (e) { tooltip .style("opacity", 0) ; }) .on("click", function (e) { const d = e.target.__data__; console.log(e); }) ;
実行中の script タグの要素を取得する方法のメモ。
実行中の script タグの要素は document.currentScript で取得できます。
実行中の script タグの要素は document.currentScript で取得できます。
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>script</title> </head> <body> <div>123</div> <script type="text/javascript"> var e = document.currentScript; var c = document.createElement('div') c.innerText = 'def'; e.parentNode.append(c); </script>456</body> </html>
d3.js で散布図でマウスオーバーでメッセージを表示する方法のメモ。
on("mouseover", function (e) { ... }) でマウスオーバー時のイベントを処理します。
メッセージは div タグで作成しておき、マウスオーバー時に内部の html を変更して表示するようにします。
以下のようなイメージです。
HTML 全体は以下の通りです。
on("mouseover", function (e) { ... }) でマウスオーバー時のイベントを処理します。
メッセージは div タグで作成しておき、マウスオーバー時に内部の html を変更して表示するようにします。
以下のようなイメージです。
const tooltip = d3.select("#scatter") .append("div") .style("position", "absolute") .style("text-align", "left") .style("background", "#ffffff") .style("border", "1px solid #000000") .style("padding", "10px") .style("opacity", 0) ; svg.append("g") .selectAll("circle") .data(dataset) .enter() .... .on("mouseover", function (e) { const d = e.target.__data__; tooltip .style("left", e.x + 30 + 'px') .style("top", e.y + 'px') .html( "id: " + d[3] + "" + "[" + d[0] + ", " + d[1] + "]" + "" + "value: " + d[2] ) .style("opacity", 1) ; }) .on("mouseout", function (d) { tooltip .style("opacity", 0) ; }) ;
HTML 全体は以下の通りです。
<html> <head> <title>d3.js test</title> </head> <body> d3.js test <script src="../d3.min.js"></script> <script type="text/javascript"> const dataset = [ [0.0, 0.0, 0.0, "p00"], [1.0, 2.0, 0.1, "p01"], [1.5, 4.0, 0.2, "p02"], [2.0, 1.5, 0.3, "p03"], [1.5, 4.0, 0.4, "p04"], [2.5, 3.5, 0.5, "p05"], [1.0, 4.0, 0.6, "p06"], [1.5, 3.5, 0.7, "p07"], [0.5, 2.0, 0.8, "p08"], [1.0, 2.5, 0.9, "p09"], [1.5, 1.0, 1.0, "p10"], ]; const width = 800; const height = 600; const margin = {"top": 30, "bottom": 30, "right": 30, "left": 30}; const svg = d3.select("#scatter") .append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) ; const xScale = d3.scaleLinear() .domain([0, d3.max(dataset, function (d) { return d[0]; })]) .range([margin.left, margin.left + width]) ; const yScale = d3.scaleLinear() .domain([d3.max(dataset, function (d) { return d[1]; }), 0]) .range([margin.bottom, margin.bottom + height]) ; svg.append("g") .attr("class", "x_axis") .attr("transform", "translate(" + [0, height + margin.top].join(",") + ")" ) .call(d3.axisBottom(xScale).ticks(0.5) ); svg.append("g") .attr("class", "y_axis") .attr("transform", "translate(" + [margin.left, 0].join(",") + ")" ) .call(d3.axisLeft(yScale).ticks(0.5) ); const colorMax = 255; const colorMin = 80; const colorScale = d3.scaleLinear() .domain([d3.min(dataset, function (d) { return d[2]; }) , d3.max(dataset, function (d) { return d[2]; })]) .range([colorMin, colorMax]) ; const tooltip = d3.select("#scatter") .append("div") .style("position", "absolute") .style("text-align", "left") .style("background", "#ffffff") .style("border", "1px solid #000000") .style("padding", "10px") .style("opacity", 0) ; svg.append("g") .selectAll("circle") .data(dataset) .enter() .append("circle") .attr("cx", function (d) { return xScale(d[0]); }) .attr("cy", function (d) { return yScale(d[1]); }) .attr("r", 10) .attr("fill", function (d) { return "rgba(0, 0, " + Math.round(colorScale(d[2])) + ", 0.8)"; }) .on("mouseover", function (e) { const d = e.target.__data__; console.log(e); tooltip .style("left", e.x + 30 + 'px') .style("top", e.y + 'px') .html( "id: " + d[3] + "" + "[" + d[0] + ", " + d[1] + "]" + "" + "value: " + d[2] ) .style("opacity", 1) ; }) .on("mouseout", function (d) { tooltip .style("opacity", 0) ; }) ; </script> </body> </html>