<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>たぬきの人文研究所</title>
	<atom:link href="https://writer-tanuki.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://writer-tanuki.com</link>
	<description>世界で最も役に立たない哲学</description>
	<lastBuildDate>Sun, 04 Jan 2026 12:14:07 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://writer-tanuki.com/wp-content/uploads/2024/05/cropped-たぬきアイコン-1-32x32.png</url>
	<title>たぬきの人文研究所</title>
	<link>https://writer-tanuki.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>zotero-test2</title>
		<link>https://writer-tanuki.com/zotero-test2/</link>
		
		<dc:creator><![CDATA[たぬき]]></dc:creator>
		<pubDate>Sun, 30 Nov 2025 07:24:10 +0000</pubDate>
				<category><![CDATA[未分類]]></category>
		<guid isPermaLink="false">https://writer-tanuki.com/?p=1606</guid>

					<description><![CDATA[]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph"></p>



<div id="graphArea"></div>
<div id="columnToggleArea"></div>
<div id="books"></div>

<!-- DataTables CSS -->
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.6/css/jquery.dataTables.min.css">

<!-- jQuery & DataTables JS -->
<script src="https://code.jquery.com/jquery-3.7.0.min.js"></script>
<script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"></script>

<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels"></script>


<script>
// 最初にディスプレイサイズを取得して幅を決定
const fullWidth = 1070;
const viewportWidth = window.innerWidth;
const graphWidth = viewportWidth < fullWidth ? Math.max(150, viewportWidth - 40) : fullWidth;

// グラフエリアのHTMLを動的に生成
const graphAreaHTML = `
<!-- トグル用テキスト -->
<div style="text-align:center; margin-bottom:10px;">
  <div id="graphToggle" style="display:inline-block; width:${graphWidth}px; height:30px;
        background-color: rgba(202, 199, 195);
        border-radius: 12px;
        text-align:center; line-height:30px;
        font-weight:bold; cursor:pointer;">
    たぬきの脳内
  </div>
</div>
<div id="graphContent" style="text-align:center; margin-top:0px;">
  <!-- 左：棒グラフ -->
  <div style="display:inline-block; width:880px; height:200px; margin-right:10px;
              background-color: rgba(252, 249, 245, 0.9); 
              border-radius: 12px; padding:10px; box-sizing:border-box;
              overflow-x: auto; overflow-y: hidden;">
    <canvas id="callGraph" width="880" height="200"></canvas>
  </div>
  <!-- 右：テキスト＋円グラフ -->
  <div style="display:inline-block; width:170px; vertical-align:top;">
    <!-- 上：テキスト -->
    <div id="pieTitle" style="width:170px; height:30px; 
            background-color: rgba(252, 249, 245, 0.9); 
            border-radius: 12px; 
            text-align:center; line-height:30px;
            font-weight:bold;
            margin-bottom:10px;">
          棒グラフをクリック
    </div>
    <!-- 下：円グラフ -->
    <div style="width:170px; height:170px; 
                background-color: rgba(252, 249, 245, 0.9); 
                border-radius: 100px; 
                padding:10px; box-sizing:border-box;">
      <canvas id="detailPie" width="170" height="170"></canvas>
    </div>
  </div>
</div>
`;

document.getElementById('graphArea').innerHTML = graphAreaHTML;

// カラムトグル用のHTMLを生成
const columnToggleHTML = `
<div id="column-toggle" style="background-color: rgba(252, 249, 245, 0.9); padding: 10px; border-radius: 12px;">
  <strong>表示項目：</strong>
  <label><input type="checkbox" class="toggle-col" data-col="col-author" checked> 著者・編者</label>
  <label><input type="checkbox" class="toggle-col" data-col="col-translator"> 翻訳者</label>
  <label><input type="checkbox" class="toggle-col" data-col="col-publisher"> 出版社</label>
  <label><input type="checkbox" class="toggle-col" data-col="col-date"> 出版年</label>
  <label><input type="checkbox" class="toggle-col" data-col="col-isbn"> ISBN</label>
  <label><input type="checkbox" class="toggle-col" data-col="col-call"> 請求記号</label>
  <label><input type="checkbox" class="toggle-col" data-col="col-status" checked> 進捗</label>
  <label><input type="checkbox" class="toggle-col" data-col="col-tag" checked> タグ</label>
  <label><input type="checkbox" class="toggle-col" data-col="col-rating" checked> ★☆☆</label>
</div>
`;

document.getElementById('columnToggleArea').innerHTML = columnToggleHTML;

fetch('/wp-content/book/MyLibrary_book.json', {
  cache: 'no-cache'
})
  .then(res => res.json())
  .then(data => {

    // 著者・編者・翻訳者・タグの出現回数をカウント
    const personCount = {};
    const translatorCount = {};
    const tagCount = {};

    data.forEach(row => {
      ['author', 'editor'].forEach(field => {
        if (row[field]) {
          row[field].forEach(name => {
            personCount[name] = (personCount[name] || 0) + 1;
          });
        }
      });

      if (row.translator) {
        const translators = Array.isArray(row.translator) ? row.translator : [row.translator];
        translators.forEach(name => {
          translatorCount[name] = (translatorCount[name] || 0) + 1;
        });
      }

      if (row.keywords) {
        row.keywords.forEach(tag => {
          tagCount[tag] = (tagCount[tag] || 0) + 1;
        });
      }
    });

    const tableHtml = `
      <table id="books-table">
        <thead>
          <tr>
            <th class="col-id">id</th>
            <th class="col-type">文献タイプ</th>
            <th class="col-title">タイトル</th>
            <th class="col-author">著者・編者</th>
            <th class="col-translator">翻訳者</th>
            <th class="col-edition">版</th>
            <th class="col-publisher">出版社</th>
            <th class="col-date">出版年</th>
            <th class="col-review">レビューリンク</th>
            <th class="col-isbn">ISBN</th>
            <th class="col-call">請求記号</th>
            <th class="col-url">URL</th>
            <th class="col-status">進捗</th>
            <th class="col-tag">タグ</th>
            <th class="col-rating">★☆☆</th>
            <th class="col-added">追加日</th>
          </tr>
        </thead>
        <tbody>
        ${data.map(row => {

          // 著者・編者をまとめる
          const combinedList = [];
          if (row.author) {
            const validAuthors = row.author.filter(name => name && name.trim() !== '');
            validAuthors.forEach(name => combinedList.push(`${name}［著］`));
          }
          if (row.editor) {
            const validEditors = row.editor.filter(name => name && name.trim() !== '');
            validEditors.forEach(name => combinedList.push(`${name}［編］`));
          }

          // / で結合、リンクを付与
          const authorHtml = combinedList.map(nameWithTag => {
            const plainName = nameWithTag.replace(/［.］/g, '');
            return personCount[plainName] >= 2
              ? `<a href="#" class="filter-link" data-filter="${plainName}">${nameWithTag}</a>`
              : nameWithTag;
          }).join(' / ');

          // 翻訳者
          let translatorHtml = '';
          if (row.translator) {
            const translators = Array.isArray(row.translator) ? row.translator : [row.translator];
            const validTranslators = translators.filter(name => name && name.trim() !== ''); // ★空文字除外
            if (validTranslators.length > 0) {
              translatorHtml = validTranslators.map(name => {
                const nameWithTag = `${name}［訳］`;
                return translatorCount[name] >= 2
                  ? `<a href="#" class="filter-link" data-filter="${name}">${nameWithTag}</a>`
                  : nameWithTag;
              }).join(' / ');
            }
          }

          // タグ
          const tagHtml = row.keywords
            ? row.keywords.map(tag => {
                return tagCount[tag] >= 2
                  ? `<a href="#" class="filter-link" data-filter="${tag}">${tag}</a>`
                  : tag;
              }).join(', ')
            : '';

          // タイトル
          const titleHtml = (() => {
            let baseTitle;
            if (/^(japanese|jp|日本語)$/i.test(row.language)) {
              // 日本語は『title』〈edition〉
              const editionPart = row.edition ? `〈${row.edition}〉` : '';
              baseTitle = `『${row.title}』${editionPart}`;
            } else {
              // 英語などは title (edition)
              const editionPart = row.edition ? ` (${row.edition})` : '';
              baseTitle = `<em>${row.title}${editionPart}</em>`;
            }
            // レビューリンクがあればリンク付きに
            return row.bookReviewUrl
              ? `<a target="_self" href="${row.bookReviewUrl}" class="review-link">${baseTitle}<span class="fa fa-link internal-icon anchor-icon"></span></a>`
              : baseTitle;
          })();

          return `
            <tr>
              <td class="col-id">${row.id}</td>
              <td class="col-type">${row.type}</td>
              <td class="col-title">${titleHtml}</td>
              <td class="col-author">${authorHtml || ''}</td>
              <td class="col-translator">${translatorHtml || ''}</td>
              <td class="col-edition">${row.edition || ''}</td>
              <td class="col-publisher"><a href="#" class="filter-link" data-filter="${row.publisher}">${row.publisher}</a></td>
              <td class="col-date">${row.date || ''}</td>
              <td class="col-review">${row.bookReviewUrl || ''}</td>
              <td class="col-isbn">${row.isbn ? `<a rel="noopener" target="_blank" href="https://ndlsearch.ndl.go.jp/search?cs=bib&#038;f-isbn=${row.isbn.replace(/-/g, '')}">${row.isbn}<span class="fa fa-external-link external-icon anchor-icon"></span></a>` : ''}</td>
              <td class="col-call">${row.call || ''}</td>
              <td class="col-url"><a href="#" class="icon-link" data-filter="${row.url || ''}">${row.url || ''}</a></td>
              <td class="col-status"><a href="#" class="filter-link" data-filter="${row.status || ''}">${row.status || ''}</a></td>
              <td class="col-tag">${tagHtml}</td>
              <td class="col-rating"><a href="#" class="icon-link" data-filter="${row.rating || ''}">${row.rating || ''}</a></td>
              <td class="col-added">${row.added || ''}</td>
            </tr>
          `;
        }).join('')}
        </tbody>
      </table>
      <div><a href="#" id="reset-filter">フィルターを解除</a></div>
    `;
    document.getElementById('books').innerHTML = tableHtml;

    // DataTable初期化
    const table = $('#books-table').DataTable({
      paging: true,
      searching: true,
      autoWidth: false,
      columnDefs: [
        { targets: [0], visible: false },
        { targets: [1], visible: false },
        { targets: [2], width: 200 },
        { targets: [3], width: 130 },
        { targets: [4], width: 130, visible: false },
        { targets: [5], visible: false },
        { targets: [6], width: 40, visible: false },
        { targets: [7], width: 20, visible: false },
        { targets: [8], visible: false },
        { targets: [9], width: 30, visible: false },
        { targets: [10], width: 30, visible: false },
        { targets: [11], visible: false },
        { targets: [12], width: 20 },
        { targets: [13], width: 70 },
        { targets: [14], width: 20 },
        { targets: [15], visible: false },
        { targets: [0,1,2,3,4,5,6,8,9,10,11,12,13,14], orderable: false } // ソートを無効
      ],
      language: {url: "//cdn.datatables.net/plug-ins/9dcbecd42ad/i18n/Japanese.json"},
      // 初期ソート
      order: [[15, 'desc']],
      // 横スクロールバーを有効にする (scrollXはtrueかfalseで有効無効を切り替えます)
      scrollX: true,
      // 縦スクロールバーを有効にする (scrollYは200, "200px"など「最大の高さ」を指定します)
      // scrollY: 400,
      // 件数切替の値を10～50の10刻みにする
      lengthMenu: [ 10, 25, 50, 100, 200 ],
      // 件数のデフォルトの値を50にする
      displayLength: 25,
    });

    // ページ番号入力欄を追加する関数
    function addPageInput() {
      // 既に存在する場合は削除
      const existing = document.getElementById('page-input-container');
      if (existing) {
        existing.remove();
      }
      
      const pageInputHTML = `
        <div id="page-input-container" style="display: inline-block; margin-left: 20px;">
          <label>ページ移動: 
            <input type="number" id="page-input" min="1" style="width: 70px; padding: 9px; height: 35px; text-align: right;" />
          </label>
          <button id="page-go" style="width: 40px; height: 40px; border-radius: 50%; background-color: #888; color: white; border: none; cursor: pointer; font-weight: bold;">Go</button>
        </div>
      `;
      
      const paginate = document.querySelector('#books-table_paginate');
      if (paginate) {
        paginate.insertAdjacentHTML('beforeend', pageInputHTML);
        
        // イベントリスナーを設定
        document.getElementById('page-go').addEventListener('click', function() {
          const pageNum = parseInt(document.getElementById('page-input').value);
          const pageInfo = table.page.info();
          if (pageNum >= 1 && pageNum <= pageInfo.pages) {
            table.page(pageNum - 1).draw('page');
          }
        });

        document.getElementById('page-input').addEventListener('keypress', function(e) {
          if (e.which === 13 || e.keyCode === 13) {
            document.getElementById('page-go').click();
          }
        });
      }
    }

    // 初期表示
    setTimeout(addPageInput, 100);
    
    // ページ遷移のたびに再追加とスクロール
    table.on('draw', function() {
      addPageInput();
      // booksエリアの先頭にスクロール
      document.getElementById('books').scrollIntoView({ behavior: 'smooth', block: 'start' });
    });

        // チェックボックス連動
    document.querySelectorAll('.toggle-col').forEach(cb => {
      cb.addEventListener('change', function() {
        const colClass = this.dataset.col;
        const visible = this.checked;
        table.columns(`.${colClass}`).visible(visible);
      });
    });

    // タグなどクリック時のフィルタ処理
    document.addEventListener('click', e => {
      if (e.target.classList.contains('filter-link')) {
        e.preventDefault();
        const filterValue = e.target.getAttribute('data-filter');
        table.search(filterValue).draw();
      }
    });

    // フィルターをリセット
    document.getElementById('reset-filter').addEventListener('click', e => {
      e.preventDefault();
      table.search('').draw();
    });

    const graphToggleBtn = document.getElementById('graphToggle');
    const graphContentArea = document.getElementById('graphContent');

    graphToggleBtn.addEventListener('click', () => {
      if (graphContentArea.style.display === 'none') {
        graphContentArea.style.display = 'block';
      } else {
        graphContentArea.style.display = 'none';
      }
    });

    // 読み終えた文献数をカウント
    const readBooks = new Set(data.map(row => `${row.title}-${row.author || ''}`)).size;

    // 件数表示を追加(表の下)
    const countDiv = document.createElement('div');
    countDiv.textContent = `通読した本の数:${readBooks}`;
    countDiv.style.marginTop = '10px';
    document.getElementById('books').appendChild(countDiv);
    // --- 十進分類 百の位ごとの棒グラフ ---
    const categories = ['0 総記','1 哲学','2 歴史','3 社会科学','4 自然科学','5 技術・工学','6 産業','7 芸術・美術','8 言語','9 文学'];
    const counts = Array(10).fill(0);
    const tenLevelCounts={};

    data.forEach(row=>{
      if(!row.call) return;
      const num = parseFloat(row.call);
      if(isNaN(num)) return;
      const hundred=Math.floor(num/100);
      const ten=Math.floor(num/10)*10;
      counts[Math.min(Math.max(hundred,0),9)]++;
      if(!tenLevelCounts[hundred]) tenLevelCounts[hundred]={};
      tenLevelCounts[hundred][ten]=(tenLevelCounts[hundred][ten]||0)+1;
    });

    const barCanvas=document.getElementById('callGraph');
    const ctxBar=barCanvas.getContext('2d');
    const pieCanvas=document.getElementById('detailPie');
    const ctxPie=pieCanvas.getContext('2d');
    let pieChart=null;

    // 棒グラフのコンテナを横スクロール可能に
    const barContainer = barCanvas.parentElement;
    barContainer.style.overflowX = 'auto';
    barContainer.style.overflowY = 'hidden';
    barContainer.style.maxWidth = '100%';
    
    // graphToggleとgraphContentの幅を調整
    const graphToggle = document.getElementById('graphToggle');
    const graphContent = document.getElementById('graphContent');
    const fullWidth = 1070;
    const viewportWidth = window.innerWidth;
    
    // 最小幅を設定（1〜2本の棒グラフが見える幅）
    const minChartWidth = 150;
    
    if (viewportWidth < fullWidth) {
      const adjustedWidth = Math.max(minChartWidth, viewportWidth - 40);
      barContainer.style.width = adjustedWidth + 'px';
      // style.widthで直接上書き
      graphToggle.style.width = adjustedWidth + 'px';
      graphContent.style.width = adjustedWidth + 'px';
    } else {
      barContainer.style.width = fullWidth;
    }

    // 棒グラフ色保持用
    const defaultBarColor='rgba(165, 140, 123, 0.9)';
    const activeBarColor='rgba(107, 148, 125, 0.9)';
    const barColors=Array(10).fill(defaultBarColor);

    // 画像ロード
    const tanukiImg = new Image();
    tanukiImg.src = '/wp-content/book/nikukyu.png';

    // 選択された棒のインデックスを保存
    let selectedBarIndex = null;

    // カスタムプラグイン:縦軸タイトルを任意位置・角度で描画
    const customYAxisLabel = {
      id: 'customYAxisLabel',
      afterDraw(chart) {
        const { ctx, chartArea, scales } = chart;
        const yAxis = scales.y;
        ctx.save();
        ctx.fillStyle = '#333';
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        // 描画位置(x, y)は好みで調整可
        const x = yAxis.left - 20;
        const y = chartArea.top - 10;
        ctx.translate(x, y);
        ctx.rotate(0); // ← 回転角度。90で縦、0で横、-90で逆縦
        ctx.fillText('冊', 0, 0);
        ctx.restore();
      }
    };

    // 画像オーバーレイ用プラグイン
    const imageOverlayPlugin = {
      id: 'imageOverlay',
      afterDatasetsDraw(chart) {
        if (selectedBarIndex === null || !tanukiImg.complete) return;
        
        const meta = chart.getDatasetMeta(0);
        const bar = meta.data[selectedBarIndex];
        if (!bar) return;

        const ctx = chart.ctx;
        const { scales } = chart;
        const yAxis = scales.y;
        
        const imageSize = 40; // 画像サイズ
        const x = bar.x - imageSize / 2;
        const y = yAxis.getPixelForValue(0) - imageSize; // y座標0の位置から画像の高さ分上に配置

        ctx.save();
        ctx.drawImage(tanukiImg, x, y, imageSize, imageSize);
        ctx.restore();
      }
    };

    const barChart=new Chart(ctxBar,{
      type:'bar',
      data:{
        labels:categories,
        datasets:[{
          label:'冊',
          data:counts,
          backgroundColor:barColors,
          borderWidth:0,
          borderRadius: 6
        }]
      },
      options:{
        animation: {
          duration: 20000,
          easing: 'easeOutQuart'
        },
        scales: {
          x: {
            grid: {
              display: false  // 縦方向の罫線を非表示
            },
            ticks: {
              font: {
                weight: 'bold' // これで太字!
              }
            }
          },
          y: {
            grid: {
              display: false  // 横方向の罫線を非表示
            },
            title: {
              display: false
            },
            ticks: {
              callback: (value) => value + ' 冊',
              font: {
                weight: 'bold' // これで太字!
              }
            }
          }
        },
        plugins: {
          legend: {
            display: false
          }
        },
        onClick:(evt, elements)=>{
          if(!elements.length) return;
          const index=elements[0].index;
          const tenData=tenLevelCounts[index];
          if(!tenData) return;

          // すべてのバーを初期色に戻す
          barChart.data.datasets[0].backgroundColor = Array(10).fill(defaultBarColor);
          // クリックされたバーだけ色変更
          barChart.data.datasets[0].backgroundColor[index] = activeBarColor;
          
          // 選択されたバーのインデックスを保存
          selectedBarIndex = index;
          
          barChart.update('none');

          // --- 数字をジャンル名に変換 ---
          const tenLevelLabels = {
            0: "総記",
            10: "図書館、図書館情報学",
            20: "図書、書誌学",
            30: "百科事典",
            40: "一般論文集、一般講演集",
            50: "逐次刊行物",
            60: "団体",
            70: "ジャーナリズム、新聞",
            80: "叢書、全集、選集",
            90: "貴重書、郷土資料、その他の特別コレクション",
            100: "哲学",
            110: "哲学各論",
            120: "東洋思想",
            130: "西洋哲学",
            140: "心理学",
            150: "倫理学、道徳",
            160: "宗教",
            170: "神道",
            180: "仏教",
            190: "キリスト教",
            200: "歴史",
            210: "日本史",
            220: "アジア史、東洋史",
            230: "ヨーロッパ史、西洋史",
            240: "アフリカ史",
            250: "北アメリカ史",
            260: "南アメリカ史",
            270: "オセアニア史、両極地方史",
            280: "伝記",
            290: "地理、地誌、紀行",
            300: "社会科学",
            310: "政治",
            320: "法律",
            330: "経済",
            340: "財政",
            350: "統計",
            360: "社会",
            370: "教育",
            380: "風俗習慣、民俗学、民族学",
            390: "国防、軍事",
            400: "自然科学",
            410: "数学",
            420: "物理学",
            430: "化学",
            440: "天文学、宇宙科学",
            450: "地球科学、地学",
            460: "生物科学、一般生物学",
            470: "植物学",
            480: "動物学",
            490: "医学",
            500: "技術、工学",
            510: "建設工学、土木工学",
            520: "建築学",
            530: "機械工学",
            540: "電気工学",
            550: "海洋工学、船舶工学",
            560: "金属工学、鉱山工学",
            570: "化学工業",
            580: "製造工業",
            590: "家政学、生活科学",
            600: "産業",
            610: "農業",
            620: "園芸",
            630: "蚕糸業",
            640: "畜産業",
            650: "林業",
            660: "水産業",
            670: "商業",
            680: "運輸、交通",
            690: "通信事業",
            700: "芸術、美術",
            710: "彫刻",
            720: "絵画",
            730: "版画",
            740: "写真",
            750: "工芸",
            760: "音楽",
            770: "演劇",
            780: "スポーツ、体育",
            790: "諸芸、娯楽",
            800: "言語",
            810: "日本語",
            820: "中国語",
            830: "英語",
            840: "ドイツ語",
            850: "フランス語",
            860: "スペイン語",
            870: "イタリア語",
            880: "ロシア語",
            890: "その他の諸言語",
            900: "文学",
            910: "日本文学",
            920: "中国文学",
            930: "英米文学",
            940: "ドイツ文学",
            950: "フランス文学",
            960: "スペイン文学",
            970: "イタリア文学",
            980: "ロシア・ソビエト文学",
            990: "その他の諸言語文学"
          };

          const labels=Object.keys(tenData).map(k => tenLevelLabels[k] || k);
          const values=Object.values(tenData);

          // 上のテキスト欄にタイトルを表示
          document.getElementById('pieTitle').textContent = categories[index];

          // 円グラフ描画
          const colors = ['#cfc296','#a6b9a5','#d4b7a9','#7eacbc','#98a5b6','#b1aab2','#c4ca9c','#89b7b4','#99a0b3','#d3b0ae'];

          if(pieChart) pieChart.destroy();
          pieChart=new Chart(ctxPie,{
            type:'pie',
            data: { labels, datasets:[{ data:values, backgroundColor:colors }] },
            options: {
              plugins: {
                legend: { display:false },
                datalabels: { display:false } // 内部ラベルは非表示
              }
            },
            plugins: [
              ChartDataLabels,
              {
                id: 'radialLabels',
                afterDraw: chart => {
                  const ctx = chart.ctx;
                  const pieMeta = chart.getDatasetMeta(0);
                  const centerX = chart.width/2;
                  const centerY = chart.height/2;
                  pieMeta.data.forEach((arc, i) => {
                    const angle = (arc.startAngle + arc.endAngle)/2;
                    const radius = arc.outerRadius - 20;
                    const x = centerX + Math.cos(angle) * radius;
                    const y = centerY + Math.sin(angle) * radius;

                    ctx.save();
                    ctx.translate(x, y);
                    ctx.rotate(angle);
                    ctx.textAlign = 'center';
                    ctx.textBaseline = 'middle';
                    ctx.font = 'bold 10px sans-serif';
                    ctx.fillText(chart.data.labels[i], 0, 0);
                    ctx.restore();
                  });
                }
              }
            ]
          });
        }
      },
      plugins: [customYAxisLabel, imageOverlayPlugin]
    });
  });
</script> 



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>zotero-test</title>
		<link>https://writer-tanuki.com/zotero-test/</link>
		
		<dc:creator><![CDATA[たぬき]]></dc:creator>
		<pubDate>Sun, 05 Oct 2025 06:56:20 +0000</pubDate>
				<category><![CDATA[未分類]]></category>
		<guid isPermaLink="false">https://writer-tanuki.com/?p=1453</guid>

					<description><![CDATA[たぬきの脳内 棒グラフをクリック]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph"></p>



<!-- トグル用テキスト -->
<div style="text-align:center; margin-bottom:10px;">
  <div id="graphToggle" style="display:inline-block; width:1070px; height:30px;
        background-color: rgba(202, 199, 195);
        border-radius: 12px;
        text-align:center; line-height:30px;
        font-weight:bold; cursor:pointer;">
    たぬきの脳内
  </div>
</div>

<div id="graphContent" style="text-align:center; margin-top:0px;">

  <!-- 左：棒グラフ -->
  <div style="display:inline-block; width:880px; height:200px; margin-right:10px;
              background-color: rgba(252, 249, 245, 0.9); 
              border-radius: 12px; padding:10px; box-sizing:border-box;">
    <canvas id="callGraph" width="880" height="200"></canvas>
  </div>

  <!-- 右：テキスト＋円グラフ -->
  <div style="display:inline-block; width:170px; vertical-align:top;">

    <!-- 上：テキスト -->
    <div id="pieTitle" style="width:170px; height:30px; 
            background-color: rgba(252, 249, 245, 0.9); 
            border-radius: 12px; 
            text-align:center; line-height:30px;
            font-weight:bold;
            margin-bottom:10px;">
          棒グラフをクリック
    </div>

    <!-- 下：円グラフ -->
    <div style="width:170px; height:170px; 
                background-color: rgba(252, 249, 245, 0.9); 
                border-radius: 100px; 
                padding:10px; box-sizing:border-box;">
      <canvas id="detailPie" width="170" height="170"></canvas>
    </div>
  </div>
</div>



<div class="wp-block-cocoon-blocks-toggle-box-1 toggle-wrap toggle-box block-box has-background has-grey-background-color"><input id="toggle-checkbox-20251005155937" class="toggle-checkbox" type="checkbox"/><label class="toggle-button" for="toggle-checkbox-20251005155937">表示項目を変更</label><div class="toggle-content">
<div id="column-toggle">
  <strong>表示項目：</strong>
  <label><input type="checkbox" class="toggle-col" data-col="col-author" checked> 著者・編者</label>
  <label><input type="checkbox" class="toggle-col" data-col="col-translator"> 翻訳者</label>
  <label><input type="checkbox" class="toggle-col" data-col="col-publisher"> 出版社</label>
  <label><input type="checkbox" class="toggle-col" data-col="col-date"> 出版年</label>
  <label><input type="checkbox" class="toggle-col" data-col="col-isbn"> ISBN</label>
  <label><input type="checkbox" class="toggle-col" data-col="col-call"> 請求記号</label>
  <label><input type="checkbox" class="toggle-col" data-col="col-status" checked> 進捗</label>
  <label><input type="checkbox" class="toggle-col" data-col="col-tag" checked> タグ</label>
  <label><input type="checkbox" class="toggle-col" data-col="col-rating" checked> ★☆☆</label>
</div>
</div></div>



<div id="books"></div>

<!-- DataTables CSS -->
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.6/css/jquery.dataTables.min.css">

<!-- jQuery & DataTables JS -->
<script src="https://code.jquery.com/jquery-3.7.0.min.js"></script>
<script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"></script>

<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels"></script>


<script>
fetch('/wp-content/book/MyLibrary_book.json')
  .then(res => res.json())
  .then(data => {

    // 著者・編者・翻訳者・タグの出現回数をカウント
    const personCount = {};
    const translatorCount = {};
    const tagCount = {};

    data.forEach(row => {
      ['author', 'editor'].forEach(field => {
        if (row[field]) {
          row[field].forEach(name => {
            personCount[name] = (personCount[name] || 0) + 1;
          });
        }
      });

      if (row.translator) {
        const translators = Array.isArray(row.translator) ? row.translator : [row.translator];
        translators.forEach(name => {
          translatorCount[name] = (translatorCount[name] || 0) + 1;
        });
      }

      if (row.keywords) {
        row.keywords.forEach(tag => {
          tagCount[tag] = (tagCount[tag] || 0) + 1;
        });
      }
    });

    const tableHtml = `
      <table id="books-table">
        <thead>
          <tr>
            <th class="col-id">id</th>
            <th class="col-type">文献タイプ</th>
            <th class="col-title">タイトル</th>
            <th class="col-author">著者・編者</th>
            <th class="col-translator">翻訳者</th>
            <th class="col-edition">版</th>
            <th class="col-publisher">出版社</th>
            <th class="col-date">出版年</th>
            <th class="col-review">レビューリンク</th>
            <th class="col-isbn">ISBN</th>
            <th class="col-call">請求記号</th>
            <th class="col-url">URL</th>
            <th class="col-status">進捗</th>
            <th class="col-tag">タグ</th>
            <th class="col-rating">★☆☆</th>
            <th class="col-added">追加日</th>
          </tr>
        </thead>
        <tbody>
        ${data.map(row => {

          // 著者・編者をまとめる
          const combinedList = [];
          if (row.author) {
            const validAuthors = row.author.filter(name => name && name.trim() !== '');
            validAuthors.forEach(name => combinedList.push(`${name}［著］`));
          }
          if (row.editor) {
            const validEditors = row.editor.filter(name => name && name.trim() !== '');
            validEditors.forEach(name => combinedList.push(`${name}［編］`));
          }

          // / で結合、リンクを付与
          const authorHtml = combinedList.map(nameWithTag => {
            const plainName = nameWithTag.replace(/［.］/g, '');
            return personCount[plainName] >= 2
              ? `<a href="#" class="filter-link" data-filter="${plainName}">${nameWithTag}</a>`
              : nameWithTag;
          }).join(' / ');

          // 翻訳者
          let translatorHtml = '';
          if (row.translator) {
            const translators = Array.isArray(row.translator) ? row.translator : [row.translator];
            const validTranslators = translators.filter(name => name && name.trim() !== ''); // ★空文字除外
            if (validTranslators.length > 0) {
              translatorHtml = validTranslators.map(name => {
                const nameWithTag = `${name}［訳］`;
                return translatorCount[name] >= 2
                  ? `<a href="#" class="filter-link" data-filter="${name}">${nameWithTag}</a>`
                  : nameWithTag;
              }).join(' / ');
            }
          }

          // タグ
          const tagHtml = row.keywords
            ? row.keywords.map(tag => {
                return tagCount[tag] >= 2
                  ? `<a href="#" class="filter-link" data-filter="${tag}">${tag}</a>`
                  : tag;
              }).join(', ')
            : '';

          // タイトル
          const titleHtml = (() => {
            let baseTitle;
            if (/^(japanese|jp|日本語)$/i.test(row.language)) {
              // 日本語は『title』〈edition〉
              const editionPart = row.edition ? `〈${row.edition}〉` : '';
              baseTitle = `『${row.title}』${editionPart}`;
            } else {
              // 英語などは title (edition)
              const editionPart = row.edition ? ` (${row.edition})` : '';
              baseTitle = `<em>${row.title}${editionPart}</em>`;
            }
            // レビューリンクがあればリンク付きに
            return row.bookReviewUrl
              ? `<a target="_self" href="${row.bookReviewUrl}" class="review-link">${baseTitle}<span class="fa fa-link internal-icon anchor-icon"></span></a>`
              : baseTitle;
          })();

          return `
            <tr>
              <td class="col-id">${row.id}</td>
              <td class="col-type">${row.type}</td>
              <td class="col-title">${titleHtml}</td>
              <td class="col-author">${authorHtml || ''}</td>
              <td class="col-translator">${translatorHtml || ''}</td>
              <td class="col-edition">${row.edition || ''}</td>
              <td class="col-publisher"><a href="#" class="filter-link" data-filter="${row.publisher}">${row.publisher}</a></td>
              <td class="col-date">${row.date || ''}</td>
              <td class="col-review">${row.bookReviewUrl || ''}</td>
              <td class="col-isbn">${row.isbn ? `<a rel="noopener" target="_blank" href="https://ndlsearch.ndl.go.jp/search?cs=bib&#038;f-isbn=${row.isbn.replace(/-/g, '')}">${row.isbn}<span class="fa fa-external-link external-icon anchor-icon"></span></a>` : ''}</td>
              <td class="col-call">${row.call || ''}</td>
              <td class="col-url"><a href="#" class="icon-link" data-filter="${row.url || ''}">${row.url || ''}</a></td>
              <td class="col-status"><a href="#" class="filter-link" data-filter="${row.status || ''}">${row.status || ''}</a></td>
              <td class="col-tag">${tagHtml}</td>
              <td class="col-rating"><a href="#" class="icon-link" data-filter="${row.rating || ''}">${row.rating || ''}</a></td>
              <td class="col-added">${row.added || ''}</td>
            </tr>
          `;
        }).join('')}
        </tbody>
      </table>
      <div><a href="#" id="reset-filter">フィルターを解除</a></div>
    `;
    document.getElementById('books').innerHTML = tableHtml;

    // DataTable初期化
    const table = $('#books-table').DataTable({
      paging: true,
      searching: true,
      autoWidth: false,
      columnDefs: [
        { targets: [0], visible: false },
        { targets: [1], visible: false },
        { targets: [2], width: 200 },
        { targets: [3], width: 130 },
        { targets: [4], width: 130, visible: false },
        { targets: [5], visible: false },
        { targets: [6], width: 40, visible: false },
        { targets: [7], width: 20, visible: false },
        { targets: [8], visible: false },
        { targets: [9], width: 30, visible: false },
        { targets: [10], width: 30, visible: false },
        { targets: [11], visible: false },
        { targets: [12], width: 20 },
        { targets: [13], width: 70 },
        { targets: [14], width: 20 },
        { targets: [15], visible: false },
        { targets: [0,1,2,3,4,5,6,8,9,10,11,12,13,14], orderable: false } // ソートを無効
      ],
      language: {url: "//cdn.datatables.net/plug-ins/9dcbecd42ad/i18n/Japanese.json"},
      // 初期ソート
      order: [[15, 'desc']],
      // 横スクロールバーを有効にする (scrollXはtrueかfalseで有効無効を切り替えます)
      // scrollX: true,
      // 縦スクロールバーを有効にする (scrollYは200, "200px"など「最大の高さ」を指定します)
      // scrollY: 400,
      // 件数切替の値を10～50の10刻みにする
      lengthMenu: [ 10, 50, 100, 200 ],
      // 件数のデフォルトの値を50にする
      displayLength: 50,
    });

        // チェックボックス連動
    document.querySelectorAll('.toggle-col').forEach(cb => {
      cb.addEventListener('change', function() {
        const colClass = this.dataset.col;
        const visible = this.checked;
        table.columns(`.${colClass}`).visible(visible);
      });
    });

    // タグなどクリック時のフィルタ処理
    document.addEventListener('click', e => {
      if (e.target.classList.contains('filter-link')) {
        e.preventDefault();
        const filterValue = e.target.getAttribute('data-filter');
        table.search(filterValue).draw();
      }
    });

    // フィルターをリセット
    document.getElementById('reset-filter').addEventListener('click', e => {
      e.preventDefault();
      table.search('').draw();
    });

    const graphToggleBtn = document.getElementById('graphToggle');
    const graphContentArea = document.getElementById('graphContent');

    graphToggleBtn.addEventListener('click', () => {
      if (graphContentArea.style.display === 'none') {
        graphContentArea.style.display = 'block';
      } else {
        graphContentArea.style.display = 'none';
      }
    });

    // 読み終えた文献数をカウント
    const readBooks = new Set(data.map(row => `${row.title}-${row.author || ''}`)).size;

    // 件数表示を追加(表の下)
    const countDiv = document.createElement('div');
    countDiv.textContent = `通読した本の数:${readBooks}`;
    countDiv.style.marginTop = '10px';
    document.getElementById('books').appendChild(countDiv);
    // --- 十進分類 百の位ごとの棒グラフ ---
    const categories = ['0 総記','1 哲学','2 歴史','3 社会科学','4 自然科学','5 技術・工学','6 産業','7 芸術・美術','8 言語','9 文学'];
    const counts = Array(10).fill(0);
    const tenLevelCounts={};

    data.forEach(row=>{
      if(!row.call) return;
      const num = parseFloat(row.call);
      if(isNaN(num)) return;
      const hundred=Math.floor(num/100);
      const ten=Math.floor(num/10)*10;
      counts[Math.min(Math.max(hundred,0),9)]++;
      if(!tenLevelCounts[hundred]) tenLevelCounts[hundred]={};
      tenLevelCounts[hundred][ten]=(tenLevelCounts[hundred][ten]||0)+1;
    });

    const barCanvas=document.getElementById('callGraph');
    const ctxBar=barCanvas.getContext('2d');
    const pieCanvas=document.getElementById('detailPie');
    const ctxPie=pieCanvas.getContext('2d');
    let pieChart=null;

    // 棒グラフのコンテナを横スクロール可能に
    const barContainer = barCanvas.parentElement;
    barContainer.style.overflowX = 'auto';
    barContainer.style.overflowY = 'hidden';
    barContainer.style.maxWidth = '100%';
    
    // graphToggleとgraphContentの幅を調整
    const graphToggle = document.getElementById('graphToggle');
    const graphContent = document.getElementById('graphContent');
    const fullWidth = 1070;
    const viewportWidth = window.innerWidth;
    
    // 最小幅を設定（1〜2本の棒グラフが見える幅）
    const minChartWidth = 150;
    
    if (viewportWidth < fullWidth) {
      const adjustedWidth = Math.max(minChartWidth, viewportWidth - 40);
      barContainer.style.width = adjustedWidth + 'px';
      // style.widthで直接上書き
      graphToggle.style.width = adjustedWidth + 'px';
      graphContent.style.width = adjustedWidth + 'px';
    } else {
      barContainer.style.width = fullWidth;
    }

    // 棒グラフ色保持用
    const defaultBarColor='rgba(165, 140, 123, 0.9)';
    const activeBarColor='rgba(107, 148, 125, 0.9)';
    const barColors=Array(10).fill(defaultBarColor);

    // 画像ロード
    const tanukiImg = new Image();
    tanukiImg.src = '/wp-content/book/nikukyu.png';

    // 選択された棒のインデックスを保存
    let selectedBarIndex = null;

    // カスタムプラグイン:縦軸タイトルを任意位置・角度で描画
    const customYAxisLabel = {
      id: 'customYAxisLabel',
      afterDraw(chart) {
        const { ctx, chartArea, scales } = chart;
        const yAxis = scales.y;
        ctx.save();
        ctx.fillStyle = '#333';
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        // 描画位置(x, y)は好みで調整可
        const x = yAxis.left - 20;
        const y = chartArea.top - 10;
        ctx.translate(x, y);
        ctx.rotate(0); // ← 回転角度。90で縦、0で横、-90で逆縦
        ctx.fillText('冊', 0, 0);
        ctx.restore();
      }
    };

    // 画像オーバーレイ用プラグイン
    const imageOverlayPlugin = {
      id: 'imageOverlay',
      afterDatasetsDraw(chart) {
        if (selectedBarIndex === null || !tanukiImg.complete) return;
        
        const meta = chart.getDatasetMeta(0);
        const bar = meta.data[selectedBarIndex];
        if (!bar) return;

        const ctx = chart.ctx;
        const { scales } = chart;
        const yAxis = scales.y;
        
        const imageSize = 40; // 画像サイズ
        const x = bar.x - imageSize / 2;
        const y = yAxis.getPixelForValue(0) - imageSize; // y座標0の位置から画像の高さ分上に配置

        ctx.save();
        ctx.drawImage(tanukiImg, x, y, imageSize, imageSize);
        ctx.restore();
      }
    };

    const barChart=new Chart(ctxBar,{
      type:'bar',
      data:{
        labels:categories,
        datasets:[{
          label:'冊',
          data:counts,
          backgroundColor:barColors,
          borderWidth:0,
          borderRadius: 6
        }]
      },
      options:{
        animation: {
          duration: 20000,
          easing: 'easeOutQuart'
        },
        scales: {
          x: {
            grid: {
              display: false  // 縦方向の罫線を非表示
            },
            ticks: {
              font: {
                weight: 'bold' // これで太字!
              }
            }
          },
          y: {
            grid: {
              display: false  // 横方向の罫線を非表示
            },
            title: {
              display: false
            },
            ticks: {
              callback: (value) => value + ' 冊',
              font: {
                weight: 'bold' // これで太字!
              }
            }
          }
        },
        plugins: {
          legend: {
            display: false
          }
        },
        onClick:(evt, elements)=>{
          if(!elements.length) return;
          const index=elements[0].index;
          const tenData=tenLevelCounts[index];
          if(!tenData) return;

          // すべてのバーを初期色に戻す
          barChart.data.datasets[0].backgroundColor = Array(10).fill(defaultBarColor);
          // クリックされたバーだけ色変更
          barChart.data.datasets[0].backgroundColor[index] = activeBarColor;
          
          // 選択されたバーのインデックスを保存
          selectedBarIndex = index;
          
          barChart.update('none');

          // --- 数字をジャンル名に変換 ---
          const tenLevelLabels = {
            0: "総記",
            10: "図書館、図書館情報学",
            20: "図書、書誌学",
            30: "百科事典",
            40: "一般論文集、一般講演集",
            50: "逐次刊行物",
            60: "団体",
            70: "ジャーナリズム、新聞",
            80: "叢書、全集、選集",
            90: "貴重書、郷土資料、その他の特別コレクション",
            100: "哲学",
            110: "哲学各論",
            120: "東洋思想",
            130: "西洋哲学",
            140: "心理学",
            150: "倫理学、道徳",
            160: "宗教",
            170: "神道",
            180: "仏教",
            190: "キリスト教",
            200: "歴史",
            210: "日本史",
            220: "アジア史、東洋史",
            230: "ヨーロッパ史、西洋史",
            240: "アフリカ史",
            250: "北アメリカ史",
            260: "南アメリカ史",
            270: "オセアニア史、両極地方史",
            280: "伝記",
            290: "地理、地誌、紀行",
            300: "社会科学",
            310: "政治",
            320: "法律",
            330: "経済",
            340: "財政",
            350: "統計",
            360: "社会",
            370: "教育",
            380: "風俗習慣、民俗学、民族学",
            390: "国防、軍事",
            400: "自然科学",
            410: "数学",
            420: "物理学",
            430: "化学",
            440: "天文学、宇宙科学",
            450: "地球科学、地学",
            460: "生物科学、一般生物学",
            470: "植物学",
            480: "動物学",
            490: "医学",
            500: "技術、工学",
            510: "建設工学、土木工学",
            520: "建築学",
            530: "機械工学",
            540: "電気工学",
            550: "海洋工学、船舶工学",
            560: "金属工学、鉱山工学",
            570: "化学工業",
            580: "製造工業",
            590: "家政学、生活科学",
            600: "産業",
            610: "農業",
            620: "園芸",
            630: "蚕糸業",
            640: "畜産業",
            650: "林業",
            660: "水産業",
            670: "商業",
            680: "運輸、交通",
            690: "通信事業",
            700: "芸術、美術",
            710: "彫刻",
            720: "絵画",
            730: "版画",
            740: "写真",
            750: "工芸",
            760: "音楽",
            770: "演劇",
            780: "スポーツ、体育",
            790: "諸芸、娯楽",
            800: "言語",
            810: "日本語",
            820: "中国語",
            830: "英語",
            840: "ドイツ語",
            850: "フランス語",
            860: "スペイン語",
            870: "イタリア語",
            880: "ロシア語",
            890: "その他の諸言語",
            900: "文学",
            910: "日本文学",
            920: "中国文学",
            930: "英米文学",
            940: "ドイツ文学",
            950: "フランス文学",
            960: "スペイン文学",
            970: "イタリア文学",
            980: "ロシア・ソビエト文学",
            990: "その他の諸言語文学"
          };

          const labels=Object.keys(tenData).map(k => tenLevelLabels[k] || k);
          const values=Object.values(tenData);

          // 上のテキスト欄にタイトルを表示
          document.getElementById('pieTitle').textContent = categories[index];

          // 円グラフ描画
          const colors = ['#cfc296','#a6b9a5','#d4b7a9','#7eacbc','#98a5b6','#b1aab2','#c4ca9c','#89b7b4','#99a0b3','#d3b0ae'];

          if(pieChart) pieChart.destroy();
          pieChart=new Chart(ctxPie,{
            type:'pie',
            data: { labels, datasets:[{ data:values, backgroundColor:colors }] },
            options: {
              plugins: {
                legend: { display:false },
                datalabels: { display:false } // 内部ラベルは非表示
              }
            },
            plugins: [
              ChartDataLabels,
              {
                id: 'radialLabels',
                afterDraw: chart => {
                  const ctx = chart.ctx;
                  const pieMeta = chart.getDatasetMeta(0);
                  const centerX = chart.width/2;
                  const centerY = chart.height/2;
                  pieMeta.data.forEach((arc, i) => {
                    const angle = (arc.startAngle + arc.endAngle)/2;
                    const radius = arc.outerRadius - 20;
                    const x = centerX + Math.cos(angle) * radius;
                    const y = centerY + Math.sin(angle) * radius;

                    ctx.save();
                    ctx.translate(x, y);
                    ctx.rotate(angle);
                    ctx.textAlign = 'center';
                    ctx.textBaseline = 'middle';
                    ctx.font = 'bold 10px sans-serif';
                    ctx.fillText(chart.data.labels[i], 0, 0);
                    ctx.restore();
                  });
                }
              }
            ]
          });
        }
      },
      plugins: [customYAxisLabel, imageOverlayPlugin]
    });
  });
</script>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>保護中: 図書館巡りの日記</title>
		<link>https://writer-tanuki.com/japan-library-quest-diary/</link>
		
		<dc:creator><![CDATA[たぬき]]></dc:creator>
		<pubDate>Thu, 02 Oct 2025 10:40:16 +0000</pubDate>
				<category><![CDATA[TanuTrip]]></category>
		<category><![CDATA[図書館巡り]]></category>
		<guid isPermaLink="false">https://writer-tanuki.com/?p=1394</guid>

					<description><![CDATA[この投稿はパスワードで保護されているため抜粋文はありません。]]></description>
										<content:encoded><![CDATA[<form action="https://writer-tanuki.com/tanuki?action=postpass" class="post-password-form" method="post"><input type="hidden" name="redirect_to" value="https://writer-tanuki.com/japan-library-quest-diary/" /></p>
<p>このコンテンツはパスワードで保護されています。閲覧するには以下にパスワードを入力してください。</p>
<p><label for="pwbox-1394">パスワード: <input name="post_password" id="pwbox-1394" type="password" spellcheck="false" required size="20" /></label> <input type="submit" name="Submit" value="確定" /></p>
</form>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>全国図書館マップ</title>
		<link>https://writer-tanuki.com/library-map-japan/</link>
		
		<dc:creator><![CDATA[たぬき]]></dc:creator>
		<pubDate>Thu, 02 Oct 2025 08:45:55 +0000</pubDate>
				<category><![CDATA[TanuTrip]]></category>
		<category><![CDATA[図書館巡り]]></category>
		<category><![CDATA[マップ]]></category>
		<category><![CDATA[リスト]]></category>
		<guid isPermaLink="false">https://writer-tanuki.com/?p=461</guid>

					<description><![CDATA[目次]]></description>
										<content:encoded><![CDATA[
<div id="index-wrapper">
  <div id="index-toggle">
    <img decoding="async" id="index-toggle-icon" src="/wp-content/icon/index.png" alt="icon">
    <span id="index-toggle-text">目次</span>
  </div>
  <div id="index-content"></div>
</div>



<div class="wp-block-cocoon-blocks-toggle-box-1 toggle-wrap toggle-box block-box"><input id="toggle-checkbox-20251002175351" class="toggle-checkbox" type="checkbox"/><label class="toggle-button" for="toggle-checkbox-20251002175351">北海道・東北地方の図書館マップ（作成中）</label><div class="toggle-content">
<iframe src="https://www.google.com/maps/d/u/1/embed?mid=1jackb7EOCFnzcdzvLQqqVcvnrVXUamw&#038;ehbc=2E312F" width="960" height="480"></iframe>
</div></div>



<div class="wp-block-cocoon-blocks-toggle-box-1 toggle-wrap toggle-box block-box"><input id="toggle-checkbox-20251002180617" class="toggle-checkbox" type="checkbox"/><label class="toggle-button" for="toggle-checkbox-20251002180617">関東地方の図書館マップ（作成中）</label><div class="toggle-content">
<iframe src="https://www.google.com/maps/d/embed?mid=1k5nU90jvGu-ytPow-6KLz1NkrcBgMbg&#038;hl=ja&#038;ehbc=2E312F" width="960" height="480"></iframe>
</div></div>



<div class="wp-block-cocoon-blocks-toggle-box-1 toggle-wrap toggle-box block-box"><input id="toggle-checkbox-20251002181228" class="toggle-checkbox" type="checkbox"/><label class="toggle-button" for="toggle-checkbox-20251002181228">中部地方の図書館マップ（作成中）</label><div class="toggle-content">
<iframe src="https://www.google.com/maps/d/u/1/embed?mid=1fF3jGJbRdJ0kytWgmgoMraSoE2ny6xk&#038;ehbc=2E312F" width="960" height="480"></iframe>
</div></div>



<div class="wp-block-cocoon-blocks-toggle-box-1 toggle-wrap toggle-box block-box"><input id="toggle-checkbox-20251002181249" class="toggle-checkbox" type="checkbox"/><label class="toggle-button" for="toggle-checkbox-20251002181249">近畿地方の図書館マップ（作成中）</label><div class="toggle-content">
<iframe loading="lazy" src="https://www.google.com/maps/d/u/1/embed?mid=1C3bEyeaf7CtuoprjI84YeSxLxt8hsAw&#038;ehbc=2E312F" width="960" height="480"></iframe>
</div></div>



<div class="wp-block-cocoon-blocks-toggle-box-1 toggle-wrap toggle-box block-box"><input id="toggle-checkbox-20251002181259" class="toggle-checkbox" type="checkbox"/><label class="toggle-button" for="toggle-checkbox-20251002181259">中国地方の図書館マップ（作成中）</label><div class="toggle-content">
<iframe loading="lazy" src="https://www.google.com/maps/d/u/1/embed?mid=1Mv5axe6sZXFlAqQAS7WvJDTfZrn1ClQ&#038;ehbc=2E312F" width="960" height="480"></iframe>
</div></div>



<div class="wp-block-cocoon-blocks-toggle-box-1 toggle-wrap toggle-box block-box"><input id="toggle-checkbox-20251002181747" class="toggle-checkbox" type="checkbox"/><label class="toggle-button" for="toggle-checkbox-20251002181747">四国地方の図書館マップ</label><div class="toggle-content">
<iframe loading="lazy" src="https://www.google.com/maps/d/u/1/embed?mid=1UZInNAG04Urc5Pnu3NVy_Tz8SI6okBg&#038;ehbc=2E312F" width="960" height="480"></iframe>
</div></div>



<div class="wp-block-cocoon-blocks-toggle-box-1 toggle-wrap toggle-box block-box"><input id="toggle-checkbox-20251002181339" class="toggle-checkbox" type="checkbox"/><label class="toggle-button" for="toggle-checkbox-20251002181339">九州・沖縄地方の図書館マップ（作成中）</label><div class="toggle-content">
<iframe loading="lazy" src="https://www.google.com/maps/d/u/1/embed?mid=1NM5ywCpJQTm9OfzJ4rf1ii6EGI15Gak&#038;ehbc=2E312F" width="960" height="480"></iframe>
</div></div>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>図書館制覇状況マップ ～日本全図～</title>
		<link>https://writer-tanuki.com/japan-library-visit-log-map/</link>
		
		<dc:creator><![CDATA[たぬき]]></dc:creator>
		<pubDate>Thu, 02 Oct 2025 07:02:14 +0000</pubDate>
				<category><![CDATA[未分類]]></category>
		<guid isPermaLink="false">https://writer-tanuki.com/?p=978</guid>

					<description><![CDATA[&#x1f5fa;&#xfe0f; 地図を読み込んでいます&#8230; 都道府県をクリックしてください 0% 1-25% 26-50% 51-75% 76-100%]]></description>
										<content:encoded><![CDATA[
<div class="wp-block-cocoon-blocks-icon-box common-icon-box block-box information-box">
<p class="wp-block-paragraph">このページは作成中です</p>
</div>



<style>
.japan-map-container {
    max-width: 1000px;
    margin: 40px auto;
    padding: 20px;
}

#japan-map-loading {
    text-align: center;
    padding: 60px 20px;
    font-size: 16px;
    color: #666;
}

#japan-map svg {
    width: 100%;
    height: auto;
    display: block;
}

#japan-map .prefecture {
    stroke: #333;
    stroke-width: 0.5;
    cursor: pointer;
    transition: all 0.2s ease;
    fill: #f0f0f0; /* デフォルト（未着手） */
}

/* 制覇状況別の色設定（25%刻み） */
#japan-map .level-1 { fill: #d1e9ff; } /* 1-25% */
#japan-map .level-2 { fill: #7fbfff; } /* 26-50% */
#japan-map .level-3 { fill: #007fff; } /* 51-75% */
#japan-map .level-4 { fill: #004080; } /* 76-100% */

#japan-map .prefecture:hover {
    opacity: 0.7;
    stroke-width: 1.5;
    filter: brightness(1.1);
}

#japan-map-info {
    text-align: center;
    padding: 15px;
    margin-top: 20px;
    background: #f0f0f0;
    border-radius: 5px;
    font-size: 16px;
    min-height: 50px;
}

/* 凡例を制覇状況用に変更 */
.map-legend {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 15px;
    margin-top: 20px;
    padding: 15px;
    background: #f9f9f9;
    border-radius: 5px;
}

.legend-item {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 14px;
}

.legend-color {
    width: 20px;
    height: 20px;
    border-radius: 3px;
    border: 1px solid #ccc;
}
</style>

<div class="japan-map-container">
    <div id="japan-map-loading">&#x1f5fa;&#xfe0f; 地図を読み込んでいます&#8230;</div>
    <div id="japan-map"></div>
    <div id="japan-map-info">都道府県をクリックしてください</div>
    
    <div class="map-legend">
        <div class="legend-item"><div class="legend-color" style="background: #f0f0f0;"></div><span>0%</span></div>
        <div class="legend-item"><div class="legend-color" style="background: #d1e9ff;"></div><span>1-25%</span></div>
        <div class="legend-item"><div class="legend-color" style="background: #7fbfff;"></div><span>26-50%</span></div>
        <div class="legend-item"><div class="legend-color" style="background: #007fff;"></div><span>51-75%</span></div>
        <div class="legend-item"><div class="legend-color" style="background: #004080;"></div><span>76-100%</span></div>
    </div>
</div>

<script>
(function() {
    // サンプルデータ: 都道府県コード(1~47)に対してランダムな制覇率(0~100)を生成
    const achievementData = {};
    for (let i = 1; i <= 47; i++) {
        achievementData[i] = Math.floor(Math.random() * 101);
    }

    const prefLinks = {
        1: "https://www.pref.hokkaido.lg.jp/",
        2: "https://www.pref.aomori.lg.jp/",
        3: "https://www.pref.iwate.lg.jp/",
        4: "https://www.pref.miyagi.lg.jp/",
        5: "https://www.pref.akita.lg.jp/",
        6: "https://www.pref.yamagata.jp/",
        7: "https://www.pref.fukushima.lg.jp/",
        8: "https://www.pref.ibaraki.jp/",
        9: "https://www.pref.tochigi.lg.jp/",
        10: "https://www.pref.gunma.jp/",
        11: "https://www.pref.saitama.lg.jp/",
        12: "https://www.pref.chiba.lg.jp/",
        13: "https://www.metro.tokyo.lg.jp/",
        14: "https://www.pref.kanagawa.jp/",
        15: "https://www.pref.niigata.lg.jp/",
        16: "https://www.pref.toyama.jp/",
        17: "https://www.pref.ishikawa.lg.jp/",
        18: "https://www.pref.fukui.lg.jp/",
        19: "https://www.pref.yamanashi.jp/",
        20: "https://www.pref.nagano.lg.jp/",
        21: "https://www.pref.gifu.lg.jp/",
        22: "https://www.pref.shizuoka.jp/",
        23: "https://www.pref.aichi.jp/",
        24: "https://www.pref.mie.lg.jp/",
        25: "https://www.pref.shiga.lg.jp/",
        26: "https://www.pref.kyoto.jp/",
        27: "https://www.pref.osaka.lg.jp/",
        28: "https://web.pref.hyogo.lg.jp/",
        29: "https://www.pref.nara.jp/",
        30: "https://www.pref.wakayama.lg.jp/",
        31: "https://www.pref.tottori.lg.jp/",
        32: "https://www.pref.shimane.lg.jp/",
        33: "https://www.pref.okayama.jp/",
        34: "https://www.pref.hiroshima.lg.jp/",
        35: "https://www.pref.yamaguchi.lg.jp/",
        36: "https://www.pref.tokushima.lg.jp/",
        37: "https://www.pref.kagawa.lg.jp/",
        38: "https://www.pref.ehime.jp/",
        39: "https://www.pref.kochi.lg.jp/",
        40: "https://www.pref.fukuoka.lg.jp/",
        41: "https://www.pref.saga.lg.jp/",
        42: "https://www.pref.nagasaki.lg.jp/",
        43: "https://www.pref.kumamoto.jp/",
        44: "https://www.pref.oita.jp/",
        45: "https://www.pref.miyazaki.lg.jp/",
        46: "https://www.pref.kagoshima.jp/",
        47: "https://www.pref.okinawa.jp/"
    };

    // 制覇率に基づいてクラス名を決定する関数
    function getLevelClass(percent) {
        if (percent === 0) return '';
        if (percent <= 25) return 'level-1';
        if (percent <= 50) return 'level-2';
        if (percent <= 75) return 'level-3';
        return 'level-4';
    }

    async function init() {
        const loading = document.getElementById('japan-map-loading');
        const map = document.getElementById('japan-map');
        const info = document.getElementById('japan-map-info');
        
        try {
            const res = await fetch('https://geolonia.github.io/japanese-prefectures/map-full.svg');
            if (!res.ok) throw new Error('読み込み失敗');
            
            const svg = await res.text();
            loading.style.display = 'none';
            map.innerHTML = svg;
            
            const prefs = map.querySelectorAll('.prefecture');
            
            prefs.forEach(pref => {
                const code = parseInt(pref.getAttribute('data-code'));
                const titleTag = pref.querySelector('title');
                let name = '不明';
                    
                    if (titleTag) {
                        // 「宮城 / Miyagi」を「/」で分割し、最初の要素（[0]）を取得して前後の空白を削除
                        name = titleTag.textContent.split('/')[0].trim();
                    }
                const percent = achievementData[code] || 0;
                
                // 制覇状況に応じたクラスを追加
                const levelClass = getLevelClass(percent);
                if (levelClass) {
                    pref.classList.add(levelClass);
                }
                
                pref.addEventListener('mouseenter', () => {
                    info.innerHTML = `<strong>${name}</strong>: 制覇率 ${percent}%<br><span style="font-size:12px">（クリックで詳細へ）</span>`;
                    info.style.background = '#e3f2fd';
                });
                
                pref.addEventListener('mouseleave', () => {
                    info.textContent = '都道府県をクリックしてください';
                    info.style.background = '#f0f0f0';
                    info.style.color = '#333';
                });
                
                pref.addEventListener('click', () => {
                    const link = prefLinks[code];
                    if (link) {
                        info.textContent = `${name}へ移動中...`;
                        setTimeout(() => window.location.href = link, 200);
                    }
                });
            });
            
            console.log('&#x2705; 地図初期化完了（制覇状況色分け版）');
        } catch (err) {
            loading.innerHTML = '<p style="color: red;">エラー: ' + err.message + '</p>';
        }
    }
    
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }
})();
</script>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>YouTube動画</title>
		<link>https://writer-tanuki.com/tanuworks-movie/</link>
		
		<dc:creator><![CDATA[たぬき]]></dc:creator>
		<pubDate>Thu, 02 Oct 2025 03:58:41 +0000</pubDate>
				<category><![CDATA[作品]]></category>
		<category><![CDATA[動画]]></category>
		<guid isPermaLink="false">https://writer-tanuki.com/?p=1277</guid>

					<description><![CDATA[]]></description>
										<content:encoded><![CDATA[]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>フォトギャラリー</title>
		<link>https://writer-tanuki.com/tanuworks-photo/</link>
		
		<dc:creator><![CDATA[たぬき]]></dc:creator>
		<pubDate>Thu, 02 Oct 2025 03:56:31 +0000</pubDate>
				<category><![CDATA[作品]]></category>
		<category><![CDATA[写真]]></category>
		<guid isPermaLink="false">https://writer-tanuki.com/?p=1278</guid>

					<description><![CDATA[]]></description>
										<content:encoded><![CDATA[]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>たぬき製ソフトウェア</title>
		<link>https://writer-tanuki.com/tanuworks-software/</link>
		
		<dc:creator><![CDATA[たぬき]]></dc:creator>
		<pubDate>Thu, 02 Oct 2025 03:54:29 +0000</pubDate>
				<category><![CDATA[テクノロジー]]></category>
		<category><![CDATA[Software]]></category>
		<guid isPermaLink="false">https://writer-tanuki.com/?p=1270</guid>

					<description><![CDATA[]]></description>
										<content:encoded><![CDATA[]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>たぬきの文章</title>
		<link>https://writer-tanuki.com/tanuworks-writing/</link>
		
		<dc:creator><![CDATA[たぬき]]></dc:creator>
		<pubDate>Thu, 02 Oct 2025 03:52:45 +0000</pubDate>
				<category><![CDATA[ただのたぬきの著作]]></category>
		<category><![CDATA[自著]]></category>
		<guid isPermaLink="false">https://writer-tanuki.com/?p=1271</guid>

					<description><![CDATA[]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed is-type-wp-embed"><div class="wp-block-embed__wrapper">
<a target="_self" href="https://writer-tanuki.com/collection-of-my-works/" title="著作リスト" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img width="160" height="90" src="https://writer-tanuki.com/wp-content/uploads/2025/09/books-160x90.jpg" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" loading="lazy" decoding="async" srcset="https://writer-tanuki.com/wp-content/uploads/2025/09/books-160x90.jpg 160w, https://writer-tanuki.com/wp-content/uploads/2025/09/books-120x68.jpg 120w, https://writer-tanuki.com/wp-content/uploads/2025/09/books-320x180.jpg 320w" sizes="auto, (max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">著作リスト</div><div class="blogcard-snippet internal-blogcard-snippet">閲覧とダウンロードブラウザで読む場合はビュアー右下のフルスクリーンボタンを押すと全画面モードになります。縦書きなので左矢印をタップして次のページに進んでくださいPDFのダウンロードはビュアー下部の【PDF】という...</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img src="https://www.google.com/s2/favicons?domain=https://writer-tanuki.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" loading="lazy" decoding="async" /></div><div class="blogcard-domain internal-blogcard-domain">writer-tanuki.com</div></div></div></div></a>
</div></figure>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>徒歩日本横断旅の日記</title>
		<link>https://writer-tanuki.com/sea-of-japan-to-pacific-ocean-journey-on-foot-diary/</link>
		
		<dc:creator><![CDATA[たぬき]]></dc:creator>
		<pubDate>Thu, 02 Oct 2025 03:31:28 +0000</pubDate>
				<category><![CDATA[TanuTrip]]></category>
		<category><![CDATA[徒歩旅]]></category>
		<category><![CDATA[徒歩]]></category>
		<guid isPermaLink="false">https://writer-tanuki.com/?p=1256</guid>

					<description><![CDATA[]]></description>
										<content:encoded><![CDATA[]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Disk: Enhanced  を使用したページ キャッシュ

Served from: writer-tanuki.com @ 2026-06-21 03:26:19 by W3 Total Cache
-->