Quantcast
Channel: 簡睿隨筆
Viewing all 904 articles
Browse latest View live

Obs122 | AI大揭密!探索Obsidian筆記的神秘關聯性:Smart Connections

$
0
0

再介紹一個使用AI技術來增加Obsidian可用性的外掛:Smart Connections,它以整個儲存庫為基底,以智能方式找出筆記間的關聯性,透過AI的角度協助建立我們可能意想不到的知識網絡。

它的三大功能是 Smart View、Smart Connections 與 Smart Chat。

由社群外掛搜尋、安裝並啟用外掛後,若在右側邊欄找不到圖示的話,按Ctrl/Cmd+P在命令面板執行【Open: View Smart Connections】與【Open: Smart Chat Conversation】。

1. Smart View

用程式碼區塊顯示儲存庫裡的關聯性,再形成嵌入內容,格式如下:

```smart-connections
查詢內容
Java程式語言的使用

```smart-connections
Java程式語言的使用

2. Smart Connections

  • 在右側邊欄顯示當前筆記的關聯性
  • 可點擊查詢圖示輸入其他關鍵字

3. Smart Chat

以ChatGPT的對話形式取得回應。

例如:「總結 [[筆記]] 重點」。輸入[[時會彈出選擇筆記視窗。

4. 感想

  • 關聯性似乎不夠準確
  • 筆記關聯性分析時間太長,經常遇到失敗的狀況
  • 分析與擷取資料時沒有顯示進度,令人無法確認是否有在執行

5. 相關鏈接

6. 教學影片

##

您可能也會有興趣的類似文章


Edge7 | AI創意大爆發!Edge的Image Creator讓你輕鬆打造獨一無二的圖片,再也不用為配圖煩惱啦!

$
0
0

微軟 AI 圖片生成功能 Image Creator (影像建立者) 已經在Edge瀏覽器 112版現身了,它使用了OpenAI的DALL-E AI 影像生成技術,我們只要輸入提示文字,Image Creator就能自動創作出4組符合描述的圖片。

雖然Image Creator目前只接受英文提示,但我們可以使用聊天或DeepL等翻譯工具將中文翻譯成英文後再貼入,就可以產生需要的圖片了。

1. 給我驚喜

點擊【給我驚喜】可以產生建議的提示文字,我們可由中學習如何組合出更好的提示文字:

  • futuristic nike sneaker, digital art, 3d render
  • a boy wearing a yellow rain coat holding a red ballon, standing in front of a smokey volcano, digital art
  • the number 2 made out of leaves, on a teal background, photorealistic
  • robot holding an umbrella in the rain, ink drawing

2. 範例1

  • 提示文字中文:創意用圓點代表,畫出多個創意互相連結並激發出智慧火花
  • 提示文字英文:Represent creativity with dots, draw multiple creative ideas connected to each other and spark wisdom” in English is “Represent creativity with dots, draw multiple creative ideas connected to each other and spark wisdom

gh|700

3. 範例2

  • 提示文字:two robots read e-book and make notes by computer, digital art

gh|700

4. 教學影片

##

您可能也會有興趣的類似文章

Vrew2-【AI技術大揭密】從一句標題自動產出完整影片!腳本、配圖、語音、背景音樂一次搞定!

$
0
0

gh|500

Vrew 最新版(2023/04/13時是0.14.2) 提供了【透過文字製作影片】的功能,只要輸入影片標題,Vrew就能以ChatGPT AI整合功能自動產生出影片腳本、配圖、語音與背景音樂,一氣呵成、非常方便。

gh|700

配圖產生後,可以用【插入】→【以文字生成圖像】來產生 4 組面,由中挑選一個替代圖片。

gh|500

1. 相關鏈接

2. 教學影片

##

您可能也會有興趣的類似文章

Obs123-掌握Obsidian的神秘技巧:解密鮮為人知的操作方法

$
0
0

1. 大綱移動標題段落

  1. 啟用大綱核心外掛
  2. 在大綱面板:用左鍵按住要移動位置的標題,拖拉到目標位置後放開左鍵

[!INFO] v1.2.3 新功能
拖拉大綱面板的標題到書籤面板,到形成標題書籤

2. 搬移段落

Move line up(Ctrl+Shift+↑)與Move line down(Ctrl+Shift+↓)命令不是只能向上、向下移動游標所在行,選取一個段落後再執行,就能移動選取內容。

[!INFO] 題外話
安裝Code Editor Shortcuts後可設置快捷鍵在標題之前跳動:命令 Go to previous heading、Go to next heading

3. 開啟在新分頁

  1. 若安裝並啟用Open in New TabOpener外掛,按左鍵可將筆記開啟在新分頁
  2. 在檔案瀏覽器或筆記裡的超鏈接處點擊滑鼠滾輪(中鍵)可將檔案開啟在新分頁

4. 開啟在新窗格

4.1. 檔案瀏覽器

  1. 右鍵功能表→Open to the right
  2. Alt+Ctrl+左鍵 (不穩定)

4.2. 筆記更多選項功能表

  1. Split right 或按著Ctrl+左鍵點擊 Current View 按鈕
  2. Split down

4.3. 快速切換(Ctrl/Cmd+O)

  1. Ctrl+Alt+左鍵
  2. Ctrl+Alt+Enter

[!INFO] Another Quick Switcher Plugin

  1. 開啟在右側窗格:Ctrl+i
  2. 開啟在下側窗格:Ctrl+-

5. 系統功能選單

【Apperance】→【Advanced】→【Windows frame style】 選用「Obsidian frame」並重啟Obsidian系統後,視窗左上角的系統功能選單會更多個功能選項:File、Edit、Insert、Format、View等。

6. 教學影片

##

您可能也會有興趣的類似文章

Obs124|跳,跳,跳乎伊勇!Obsidian用書籤和標籤快速在檔案間跳轉

$
0
0

gh|500

程式編輯器裡的Bookmark可以快速的在多個不同檔案的多個位置跳轉,例如先在跳轉位置按Ctrl+Shift+數字設定位置書籤,需要跳回去時按Ctrl+數字就能跳回設定的位置。對於經常這樣操作的我來說,一直希望Obsidian的編輯器也能提供類似功能,可惜核心編輯器或Code Editor Shortcuts外掛、Keyshots外掛都沒有提供這個功能,我只好尋找其他替代方案來達成類似功能。

今天介紹兩個方法:使用書籤區塊標籤+query程式碼區塊來達成相仿的跳轉功能。

1. 書籤

上次介紹書籤功能時沒有試出區塊書籤,原來區塊書籤只能透過命令來新增:Bookmark block under cursor...,為了方便操作我對此命令綁定了一個快捷鍵。

在要跳轉的位置處新增區塊書籤,要跳轉時開啟書籤窗格再點擊區塊書籤即可。 ^17cc11

[!TIP]+ 技巧
為達快速新增,可以省略選擇資料夾,直接將書籤存到根目錄

1.1. 顯著識別

為了更快速識別出區塊書籤,我以下列CSS片段變更圖示顏色: ^e19de6

/* Bookmark面板: 區塊圖示設定不同顏色 */
.tree-item-icon .lucide-toy-brick {
  color: var(--color-accent);
}

2. 標籤

在要跳轉位置區塊後方先輸入一個空白,再加上特定的區塊標籤,例如#-1。 #-JUMP

[!COMMENT]+ 建議

  • 標籤名稱以減號或底線開頭,盡量簡短以方便輸入,並且標籤以名稱排序時能集中到開頭或最後
  • 範例:#-1#-JUMP

[!TIP]+ 技巧
可以用 AutoHotkey、TextExpander、Esponso之類的文字擴展工具設置熱鍵直接插入跳轉用標籤

#ifWinActive,ahk_exe Obsidian.exe
^+1::
  Send {#}-JUMP
  return  
#ifWinActive

2.1. 使用標籤窗格

在右側邊欄開啟標籤窗格後,點擊特定標籤,則搜尋窗格會列出設置了標籤的筆記,點擊要跳往位置。 #-JUMP

2.2. 建立跳轉用筆記

  1. 建立筆記,內容是Obsidian的查詢程式碼區塊如下:
```query
tag:#-JUMP


2. 將筆記拖拉到左側邊欄後放到適當位置
3. 需要跳轉時點擊左側邊欄的筆記,再點擊特定位置
4. 缺點:第一次顯示時需要重新查詢

> [!COMMENT]+ 建議
> 1. 可安裝Query Control外掛,擴充query程式碼區域的功能
> 2. 可惜目前此外掛與v1.2不相容,須待外掛作者修改

## 3. 相關鏈接

- Code Editor Shortcuts: https://github.com/timhor/obsidian-editor-shortcuts
- Keyshots: https://github.com/KrazyManJ/obsidian-keyshots

## 4. 教學影片


##

您可能也會有興趣的類似文章

Obs125|閒聊Fleeting Note的翻譯與其本質

$
0
0

閃聊幾句與Obsidian相關的名詞,有不同看法的歡迎提出討論並補充。

剛接觸卡片盒筆記法的朋友們最先認識的可能都是《How to Take Smart Notes》英文版裡介紹的筆記分類:

筆記分類 繁體中文翻譯 簡體中文翻譯 日文翻譯
Fleeting notes 靈感筆記 闪念笔记 走り書きメモ (潦草的筆記)
Literature notes 文獻筆記 文献笔记 文献メモ
Permanent notes 永久筆記 永久笔记 永久保存版メモ
Structure notes 結構筆記 结构笔记 構造メモ

其中,Fleeting Note的操作方法會是全新的:應該要在短時間裡把它的內容重新整理後,隨即刪除或封存歸檔。對照到《How to Take Smart Notes》中文版的翻譯:靈感或闪念,或許有人會有稍縱即逝的疑惑:

  • 既然是靈感或一閃而過的念頭,記錄下來了為何要刪除?
  • 既然是靈感,為何原作不使用 Inspiration 或 Flashing thoughts,而是使用Fleeting (轉瞬即逝)?

我覺得這些疑問是因為中文翻譯太過想當然爾的結果,對比日文的翻譯「走り書きメモ (潦草的筆記)」,我覺得日文翻譯得更加精準。

只要和最終要保存的永久筆記一對比,為何使用Fleeting這個詞就呼之欲出了:Fleeting Note指的是筆記存在的時間而不是要寫下的內容形式,所以原作者才會說「 這些都是暫時性的筆記」、「 寫在餐巾或收據上我也很OK」。

Fleeting Note是隨時將看到的、聽到的或想到的都寫下來的暫時性筆記(草稿),等有空整理時再梳理剖析、歸納總結、聯想連結,用自己的詞語記錄成永久筆記。

如果有了這個清楚的認知,就不會被翻譯的名詞誤導了。

2. 教學影片

##

您可能也會有興趣的類似文章

Obs126|Obsidian 2023/04 7個新外掛介紹與評析

$
0
0

介紹近日試用過的 7 個外掛,務必看到最後以免有遺珠之憾。


[!NOTE]+ 老生常談

  1. 外掛是輔助製作筆記的工具,寫好筆記、完善工作流程才是最重要的,千萬不要本末倒置
  2. 社群外掛的作者大多出於自身需要的一腔熱血來撰寫程式,除了感謝之外,也要警惕外掛有可能停止維護的可能,有風險意識才能長治永安
  3. 雖說對社群外掛提供的功能不要認為理所當然,也不須太過擔憂,因為它們都在GitHub上有原始碼
  4. 外掛常有更新,因此經常使用的外掛記得每隔一陣子就要溫故知新,才能發覺更好的功能;例如今天才發現Dynamic Table of contents (2021年9月的影片介紹:Obs#48 動態目錄外掛)提供了第三種inline類型,實在是後知後覺 😝

1. Plugin Update Tracker

[!comment]+ 功能

  1. 自動偵測外掛更新狀態,顯示待更新外掛數量
  2. 顯示更新說明,並可開啟GitHub的程式碼異動比較網頁
  3. 勾選欲更新外掛並更新

gh|700

gh|700

gh|700

2. Reveal File in Explorer

[!comment] 功能
點擊檔名標題列以顯示當前檔案在檔案瀏覽器(File Explorer)內的位置

  • 功能與Revel Active File Button相同
  • 游標操作時固定到開頭位置,只能以鍵盤左右鍵、Home鍵、End鍵移動游標位置
  • 使用Del鍵時注意游標位置,我曾經發生游標在檔案瀏覽器而誤刪檔案

3. Colorful Note Borders

[!comment] 功能
依設定規則在編輯區四周顯示顏色

  • 規則:資料夾或YAML欄位設定的Key與Value
  • 希望能提供正則運算式,否則條件太過簡單

4. Opener

[!comment] 功能

  1. 將筆記開啟在新分頁
  2. 用預設應用程式開啟PDF檔
  • 功能與Open in new Tab相同,但多了用預設應用開啟PDF的功能
  • 未上架,必須手動或用BRAT外掛安裝

5. Codeblock Customizer

[!comment] 功能
強化程式碼區域的顯示

  • 功能與先前介紹過的Obs#113-展示程式碼區塊的好工具:HK Code Block外掛類似,但有更多選項,能自訂顯示樣式,且區塊能在PDF裡呈現
  • 設定:
    • 可排除不處理的程式語言
    • 例如:,dataview,col,col
    • 為了顯示程式碼區塊的內容會在最外面用4個倒引號夾住,要排除渲染
    • 上列最後面是啟用Columns外掛時排除渲染
  • Markdown程式碼區塊選項:
    • 檔名:file:mytest.js
    • 高亮:hl:1,2,10-15
    • 自訂高亮,error、warn等皆可自訂:error:4-7 warn:10,15 info: 17-22
    • 折疊:fold

5.1. 範例

import java.util.zip.*;
import java.io.*;
public class Main {
    public static void main(String args[]) throws Exception {
      System.out.println("Hello world!");
    }
}

5.2. 特點

以下是作者自列的功能特點(ChatGPT翻譯):

  • 默認的深色和亮色主題。您也可以創建自己的主題。
  • 啟用編輯器活動行高亮。 Obsidian 中的活動行(包括代碼塊)將被突出顯示(您可以自定義顏色)。
  • 啟用代碼塊活動行高亮。代碼塊內部的活動行將被突出顯示(您可以自定義顏色)。
  • 排除語言。您可以定義以逗號分隔的語言,插件不會應用於這些語言。
  • 為代碼塊設置背景顏色。
  • 允許您突出特定行。→按:可指定高亮區域,用逗點或減號(起迄)
    • 自定義突出顏色
  • 讓你定義多個突出線條來強調重點。
  • 顯示文件名稱
    • 如果已定義文件名稱,將插入標頭,在其中可以自定義文本(彩色、粗體、斜體),以及標頭本身(彩色、標頭線)
  • 折疊代碼
    • 如果已展開標頭(通過指定文件名或其他方式解釋下面),則可單擊該標頭以折疊其下方的代碼塊
  • 顯示代碼塊語言。這會在標頭中顯示代碼塊的語言(如果指定)。
    • 自定義文本顏色、背景顏色、粗體文本、斜體文本,用於標頭內部的語言標籤。
    • 默認情況下,僅當已展開標頭並且為代碼塊定義了一種語言時才顯示該語言標籤。但是,您可以強制始終顯示代碼塊語言,即使不會顯示標頭也是如此。
  • 在標頭中顯示代碼塊語言圖標(如果可用)
  • 將行號添加到代碼块
    • 自定義是否在突出行時也突出行號
    • 自定義行數字的背景和文字颜色

6. OZ Calendar

[!comment] 功能
適合使用每日筆記的朋友使用,功能上是Calendar+Chronology(部份)的綜合

  • 可使用Style Settings外掛變更顏色樣式
  • 檔案來源可指定是依據YAML欄名或檔名,二者皆可自訂
    • YAML欄名預設是 created
    • 檔名格式預設是YYYY-MM-DD hh:mm:ss
  • 目前顯示格式未遵循Obsidian的語言設定
    • 美中一不足:
    • 資料來源無法混用
    • 無法自動開啟每日筆記
    • Create note for today不會調用模板

7. Link Favicons

[!comment] 功能
外部鏈接顯示網站圖示

  • 外部鏈接顯示該網址的圖示以與內部鏈接能明顯區分
  • 可設定顯示在開頭或結尾處

7.1. 範例

[!TIP]+ 技巧

  • 注意到了嗎?內部鏈接的不同格式使用了不同的樣式,Wiki格式沒有底線,Markdown格式的有底線
  • 建議用Wiki格式,有較多的外掛支援

8. 相關鏈接

9. 教學影片

##

您可能也會有興趣的類似文章

Obs127|用Templater Hotkeys簡化Obsidian自動化腳本,詳解4個腳本範例

$
0
0

用Templater Hotkeys來建立Obsidian自動化腳本,比QuickAdd方便許多。步驟如下:

  1. 安裝並啟用Templater外掛
  2. 新增Templater腳本的.md檔
  3. 到Templater選項裡新增Templater Hotkeys,讓腳本檔變成命令
  4. 為腳本命令設置快捷鍵或用Ctrl/Cmd+P執行命令

本次介紹4個範例,並說明如何使用Dataviewjs查詢命令代碼。

[!tip]+ 建議

  1. 所有腳本檔皆以Cmd-開頭,與一般的模板檔區隔
  2. 腳本檔執行發生錯誤時,將之複製成.js檔,刪除開頭的<%*與結尾的%>後,用VS Code檢視

1. 範例1-選取YAML欄位設定

  • 功用:在YAML區插入筆記種類

gh|700

<%*
let list = {
  "Fleeting Note": "fleeting note",
  "Literature Note": "literature note" ,
  "Permanent Note": "permanent note",
  "Structure Note": "structure note",
  "Meeting Note": "meeting note",
  "Daily Note": "daily note"
};
let keys = Object.keys(list);

let key = await tp.system.suggester(keys, keys);
if (!key) return;
let editor = app.workspace.activeLeaf.view.editor;  // 取編輯器物件
let position = editor.getCursor();  // 取游標物件
let text = editor.getLine(position.line);  // 取游標行的內容
if (text.length > 0) text += "\n";
text = text + "type: " + list[key];
editor.setLine(position.line, text);
-%>

2. 範例2-由選單插入Callout區塊

  • 功用:用選單插入Callout區塊

gh|700

<%*
let list = {
  "ℹ info" : "info,資訊",
  "✏ note" : "note,筆記",
  "📒 summary" : "summary,彙總",
  "🔥 tip" : "tip,技巧",
  "☑ check" : "check,查核",
  "❔Help" : "help,說明",
  "⚠ Warning" : "warning,警告",
  "❌ Fail" : "fail,失敗",
  "⚡Danger" : "danger,危險",
  "🪲 Bug" : "bug,錯誤",
  "📋 Example" : "example,範例",
  "✍ Quote " : "quote,引用",
  "😝 LOL " : "LOL,哈哈",
  "📕 Reference " : "REF,參考"
};
let keys = Object.keys(list);
key = await tp.system.suggester(keys, keys);
let value = list[key];
let index = value.indexOf(",");
let text = value.substring(index+1);
value = value.substring(0, index);
if (key) return ">[!" + value + "]+ " + text + "\n> ";
%>

3. 範例3-段落形成畫布卡片

  • 功用:將文字段落產生成畫布的卡片

gh|700

<%*
let sCanvasFolder = "030-Inbox/";

//d = tp.file.content.split("\n\n");
let sSelection = tp.file.selection();
let aLines =  sSelection.split("\n\n");
aNodes = [];
let iWidth = 320, iHeight = 160;
for (i = 0;i < aLines.length;i++){
  a = {};
  a.id = i;
  a.x = (i%3) * (iWidth+20);
  a.y = (parseInt(i / 3) % 3) * (iHeight+20);
  a.width = iWidth;
  a.height = iHeight;
  a.type = "text";
  a.text = aLines[i];
  if (a.text.length > 0) {
    aNodes.push(JSON.stringify(a));
  }
}
let sJson = '{"nodes":[' + aNodes.join(",") + ']}';
let sBasename = sCanvasFolder + tp.file.title;
let sFullFilename = sBasename + ".canvas";
let sPath = app.vault.getAbstractFileByPath(sFullFilename);

// 檔名可能重覆,加上序號處理
let k = 1;
while(sPath){
  sFullFilename = sBasename + " " + (k++) + ".canvas";
  sPath = app.vault.getAbstractFileByPath(sFullFilename);
}
sPath = await app.vault.create(sFullFilename, sJson);
await app.workspace.activeLeaf.openFile(sPath);
return null;  // 不回傳null或sSelection的話,原來的選取內容會被刪除
-%>

4. 用Dataviewjs列出所有命令代碼

  • 用Dataviewjs列出所有命令以找到需要使用的命令代碼

gh|700

```dataviewjs
const getNestedObject = (nestedObj, pathArr) => {
    return pathArr.reduce((obj, key) =>
        (obj && obj[key] !== 'undefined') ? obj[key] : undefined, nestedObj);
}

function getHotkey(arr) {
    return arr.hotkeys ? [[getNestedObject(arr.hotkeys, [0, 'modifiers'])],
    [getNestedObject(arr.hotkeys, [0, 'key'])]].flat(2).join('+').replace('Mod', 'Ctrl') : '–';
}

let cmds = dv.array(Object.entries(app.commands.commands))
    .sort(v => v[1].id, 'asc');

dv.paragraph(cmds.length + " commands currently enabled.<br><br>");

dv.table(["Command ID", "Name in current locale", "Hotkeys"],
    cmds.map(v => [
    v[1].id,
    v[1].name,
    getHotkey(v[1]),
    ])
  );

## 5. Templater Hotkeys命令選單

```js file:"Cmd-All.md"
<%*
let lstCmds = {
  "YAML Type": "templater-obsidian:010-Templates/Cmd-YAML type.md",
  "Week Review": "templater-obsidian:010-Templates/Cmd-Review.md" ,
  "Callout": "templater-obsidian:010-Templates/Cmd-Callout.md",
  "Prepend Line": "templater-obsidian:010-Templates/Cmd-Prepend Line.md",
  "Text to Canvas": "templater-obsidian:010-Templates/Cmd-Insert into canvas.md"
};
let keys = Object.keys(lstCmds);

let key = await tp.system.suggester(keys, keys);
if (!key) return;
let editor = app.workspace.activeLeaf.view.editor;
let position = editor.getCursor();
let text = editor.getLine(position.line);
app.commands.executeCommandById(lstCmds[key]);
-%>

6. 教學影片

https://youtu.be/U8HDmoQAwts

##

您可能也會有興趣的類似文章


Obs128|Obsidian Dataview進度條與YAML欄位快速輸入的方法

$
0
0

介紹Dataview表格顯示進度條的方法,依進度的百分比顯示不同的顏色,並說明如何使用Templater腳本快速輸入進度的對話窗的寫法。影片裡介紹的方法適用於閱讀筆記或工作筆記,需要進度管控的情況下可增進便利性。

gh|500

gh|500

  • 進度條的顏色參考Minimal Theme的設定

gh|500

1. 進度條的HTML標籤

[!note]+ 進度條的語法
<progress max=最大值 value=要顯示的值>文字</progress>

在筆記裡新增兩個YAML欄位:

  1. current表示目前的值(已閱讀的頁數)
  2. total表示全部的值(總頁數)

目前進度的完成百分比就是(current / total)*100,再用round()做四捨五入到整位數的計算,即:

[!note]+ 進度百分比
round((current / total) * 100)

加入progress標籤後,完整字串格式如下:

"<progress max=100 value=" + round((current / total) * 100) + "></progress>"

最後的Dataview敘述如下:

table current, total,
  "<progress max=100 value=" + round((current/total)*100) + "></progress> " + 
  round(current/total*100) + "%" as Prpgress
from #test
sort file.name

2. 快速變更進度值

要在YAML區找到current以變更最新值的輸入效率有點差,因此寫了個簡單的Templater Scripts以彈出視窗,在Templater Hotkeys裡註冊並設定快捷鍵,需要變更current的值時,按設定的快捷鍵就可以快速變更了。

如果筆記尚無total欄位時,會彈出其輸入的對話窗。

gh

2.1. 步驟1-撰寫Cmd-Page Read.md腳本

  • tp.frontmatter.欄位名 只能讀取值,無法設定,設定Front matter的欄位值可使用下列fileManager的寫法
<%*
  let oTotal = tp.frontmatter.total;
  if (!oTotal) {
    let oPage = await tp.system.prompt("Total pages:")
    if (!oPage) return;
    await app.fileManager.processFrontMatter(tp.config.active_file, (fm) => {
      fm["total"] = parseInt(oPage.toString());
    });
  }
  let oPage = await tp.system.prompt("The last page number read:")
  if (!oPage) return;
  //tp.frontmatter.current = iPage;
  await app.fileManager.processFrontMatter(tp.config.active_file, (fm) => {
    fm["current"] = parseInt(oPage.toString());
  });
-%>

2.2. 步驟2-Templater Hotkeys設定

設定→Templater選項→Templater Hotkeys→加入Cmd-Page read.md
設定快捷鍵。

3. 進度樣式設定

  • 依進度百分比顯示不同的顏色

進度條的進度部分使用了::-webkit-progress-value偽元素定義,進度條的背景部分使用了::-webkit-progress-bar偽元素定義。

/* 進度條顏色依value變化 */
progress[value^="1"]::-webkit-progress-value, 
progress[value^="2"]::-webkit-progress-value,
progress[value^="3"]::-webkit-progress-value {
  background: var(--color-red) !important;
  box-shadow: none;
  border-color: transparent;
  border-radius: 2px;
}

progress[value^="4"]::-webkit-progress-value,
progress[value^="5"]::-webkit-progress-value {
  background: var(--color-orange) !important;
  box-shadow: none;
  border-color: transparent;
  border-radius: 2px;
}

progress[value^="6"]::-webkit-progress-value,
progress[value^="7"]::-webkit-progress-value {
  background: var(--color-yellow) !important;
  box-shadow: none;
  border-color: transparent;
  border-radius: 2px;
}

progress[value^="8"]::-webkit-progress-value,
progress[value^="9"]::-webkit-progress-value {
  background: var(--color-green) !important;
  box-shadow: none;
  border-color: transparent;
  border-radius: 2px;
}

progress[value="1"]::-webkit-progress-value, 
progress[value="2"]::-webkit-progress-value,
progress[value="3"]::-webkit-progress-value,
progress[value="4"]::-webkit-progress-value,
progress[value="5"]::-webkit-progress-value,
progress[value="6"]::-webkit-progress-value,
progress[value="7"]::-webkit-progress-value,
progress[value="8"]::-webkit-progress-value,
progress[value="9"]::-webkit-progress-value
{
  background: var(--color-red) !important;
  box-shadow: none;
  border-color: transparent;
  border-radius: 2px;
}

progress[value="100"]::-webkit-progress-value {
  background: var(--color-blue) !important;
  box-shadow: none;
  border-color: transparent;
  border-radius: 2px;
}

.markdown-preview-view progress, .markdown-rendered progress, .markdown-source-view.is-live-preview progress {
  height: 15px;
}

4. 教學影片

https://youtu.be/c5T-flyo81E

您可能也會有興趣的類似文章

Obs129|Obsidian除了CSS片段以外的CSS進階用法與兩個CSS外掛

$
0
0
  • 目標(Datview表格樣式設定)
    1. 第2與第3直欄右靠
    2. 第2與第3直欄字體綠色
    3. 進度條依百分比顯示不同顏色
    4. 進度條內顯示百分比數值

gh|500

gh|500

1. 全域CSS片段

  • 所有筆記皆會套用
.dataview.table-view-table td:nth-child(2), 
.dataview.table-view-table td:nth-child(3) {
  text-align: right;
  color:var(--color-green);
}
  • 數值欄位右靠
    ```dataview
    table current, total,
    "<progress max=100 value=" + round(current/total*100) + 
    "></progress> " + round(current/total*100) + "%" as Progress
    from #test

2. 當前筆記套用:cssClasses

  • 在外部CSS檔設定CSS類別
  • 要套用時必須指定YAML欄位 cssClasses: td-right
.td-right .dataview.table-view-table td:nth-child(2), 
.td-right .dataview.table-view-table td:nth-child(3) {
  text-align: right;
  color:var(--color-green);
}
---
cssClasses: td-right
---

[!danger]+ 問題

  • 無法針對特定筆記設定,整個儲存庫一體適用
  • 動態資料(如Dataview)欄位不固定,因此使用不方便

3. 特定元素套用:Markdown Attributes

  • 安裝並啟用Markdown Attributes外掛
  • 在CSS片段裡定義CSS類別或ID
  • 在特定HTML元素內或後方添加類別屬性或CSS ID設定。

[!REF]+ 語法
{ .CSS類別 }、{ class=CSS類別 }、{ id=ID }

.color-red {
  color: var(--color-red) !important;
}

.color-green {
  color: var(--color-green) !important;
}

.color-yellow {
  color: var(--color-yellow) !important;
}
  1. 第1行
  2. 第2行是紅色 {.color-red}
  3. 第3行是綠色 {.color-green}
  4. 第4行是黃色 {.color-yellow}

▼ 表格預覽模式才會生效

標題1 標題2 {.color-red} 標題
1-1 1-2 1-3
2-1 2-2 {.color-green} 2-3
3-1 3-2 3-3

{.color-yellow}

gh

4. 內嵌樣式:Stylist

  • 安裝並啟用Stylist外掛
  • 預覽模式才生效

[!REF]+ 語法

```style
CSS類別 { CSS樣式設定 }
```style
.dataview.table-view-table td:nth-child(4), .dataview.table-view-table td:nth-child(5) {
  text-align: right !important;
  color:var(--color-purple);
}

```style
.dataview.table-view-table td:nth-child(4), .dataview.table-view-table td:nth-child(5) {
  text-align: right !important;
  color:var(--color-purple);
}
table created, modified, current, total,
  "<p class='progress'><progress max=100 value=" + round(current/total*100) + 
  "></progress> " + round(current/total*100) + "%" as Progress
from #test

5. 進度條樣式

  • 進度條內的百分比文字是定義在 progress::before
/* 進度條顏色依value變化 */
progress[value^="1"]::-webkit-progress-value, 
progress[value^="2"]::-webkit-progress-value,
progress[value^="3"]::-webkit-progress-value {
  background: var(--color-red) !important;
  box-shadow: none;
  border-color: transparent;
  border-radius: 2px;
}

progress[value^="4"]::-webkit-progress-value,
progress[value^="5"]::-webkit-progress-value {
  background: var(--color-orange) !important;
  box-shadow: none;
  border-color: transparent;
  border-radius: 2px;
}

progress[value^="6"]::-webkit-progress-value,
progress[value^="7"]::-webkit-progress-value {
  background: var(--color-yellow) !important;
  box-shadow: none;
  border-color: transparent;
  border-radius: 2px;
}

progress[value^="8"]::-webkit-progress-value,
progress[value^="9"]::-webkit-progress-value {
  background: var(--color-green) !important;
  box-shadow: none;
  border-color: transparent;
  border-radius: 2px;
}

progress[value="1"]::-webkit-progress-value, 
progress[value="2"]::-webkit-progress-value,
progress[value="3"]::-webkit-progress-value,
progress[value="4"]::-webkit-progress-value,
progress[value="5"]::-webkit-progress-value,
progress[value="6"]::-webkit-progress-value,
progress[value="7"]::-webkit-progress-value,
progress[value="8"]::-webkit-progress-value,
progress[value="9"]::-webkit-progress-value
{
  background: var(--color-red) !important;
  box-shadow: none;
  border-color: transparent;
  border-radius: 2px;
}

progress[value="100"]::-webkit-progress-value {
  background: var(--color-blue) !important;
  box-shadow: none;
  border-color: transparent;
  border-radius: 2px;
}

.markdown-preview-view progress, .markdown-rendered progress, .markdown-source-view.is-live-preview progress {
  text-align: center;
  height: 15px;
}

progress {
  position: relative;
  border: none;
  border-radius: 20px;
  overflow: hidden;
}

/* 進度條的進度部分 */
progress::-webkit-progress-value {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 50%;
  background-color: #007bff;
  border-radius: 20px;
}

/* ::-webkit-progress-bar:進度條的背景部分 */
progress::-webkit-progress-bar {
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  width: 100%;
  background-color: #eee;
  border-radius: 20px;
}

progress::before {
  z-index: 100;
  content: attr(value) '%';
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  font-size: 12px;
  font-weight: bold;
  color: blue;
}

6. 相關鏈接

7. 教學影片

##

您可能也會有興趣的類似文章

Obs130|用Dataviewjs將Dataview表格產生成Markdown格式,並複製到剪貼簿的技巧

$
0
0

Dataview讓我們將筆記當成資料來查詢,但查詢出來的表格卻無法搜尋、無法複製再利用。今天分享一個使用Dataviewjs來產生表格與Copy按鈕的作法:

  1. 以Dataviewjs查詢出表格
  2. 在表格下方產生一個【Copy】按鈕
  3. 點擊【Copy】按鈕後,將Dataview表格轉換成Markdown表格,並複製到系統剪貼簿
  4. 到需要插入Markdown表格的位置按Ctrl+V

1. Dataviewjs

```dataviewjs
let dataArray = dv.pages("")
  .where(page => (dv.date("today") - page.file.mday <= dv.duration("1days")))
  .sort(page =&gt page.file.mday, "desc")
  .map(page => [page.file.link, page.type, page.tags, 
    page.file.cday, page.file.mday]);
dv.table(["File", "Type", "Tags", "Created", "Modified"], dataArray);

const button = dv.el("button", "Copy");
button.onclick = function() {
  new Notice("Dataview content copy to clipboard!");
  let md_text = dv.markdownTable(["File("+dataArray.length+")", "Type", "tags", 
    "Created", "Modified"], dataArray);
  navigator.clipboard.writeText(md_text);
}
```

1.1. 本日建立或修改的筆記

```dataviewjs
let dataArray = dv.pages(&#039;&#039;)
  .where(page => (dv.date("today") - page.file.mday <= dv.duration("12hours")))
  .sort(page => page.file.mday, "desc")
  .map(page => [page.file.link, page.type, page.file.cday, page.file.mday]);
dv.table(["File", "Type", "Created", "Modified"], dataArray);

const button = dv.el("button", "Copy");
button.onclick = function() {
  new Notice("Dataview content copy to clipboard!");
  let md_text = dv.markdownTable(["File("+dataArray.length+")", "Type", 
    "Created", "Modified"], dataArray);
  navigator.clipboard.writeText(md_text);
}
```

2. 簡單點的範例

```dataview
table type, created
from #test
```
  • dv.pages(來源):傳回符合條件的筆記物件陣列
  • page是傳入的一個筆記物件
  • page.type 是取出YAML區的type欄位
  • page.file.link 是筆記物件的file屬性,file代表作業系統的檔案物件
  • dv.table([標題陣列], 資料陣列) 生成Dataview表格
  • dv.el 建立HTML標籤
  • dv.markdownTable([標題陣列], 資料陣列) 生成Markdown格式的Dataview表格
```dataviewjs
let data = dv.pages("#test").map(page => [page.file.link, page.type, page.created]);
dv.table(["Link", "Type", "Created"], data);
let btn = dv.el("button", "Copy table");

btn.onclick = function() {
  new Notice("COPY!")
  let md_text = dv.markdownTable(["File("+data.length+")", "Type", "Created"], data);
  navigator.clipboard.writeText(md_text);
}
```
| File(7)                                               | Type | Created             |
| ----------------------------------------------------- | ---- | ------------------- |
| [[test.md\|test]]                                     | 測試筆記 | 2023-05-03 08:51:26 |
| [[test-columns.md\|test-columns]]                     | 專案筆記 | 2022-05-03 20:57:16 |
| [[test-Admonitions.md\|test-Admonitions]]             | 專案筆記 | 2022-03-31 20:15:33 |
| [[300-R興趣/300-01-筆記方法/康乃爾筆記法 Notes.md\|康乃爾筆記法 Notes]] | 彙總筆記 | 2022-03-26 16:15:11 |
| [[300-R興趣/300-01-筆記方法/PARA 說文解字.md\|PARA 說文解字]]       | 原子筆記 | 2022-03-26 16:18:50 |
| [[042-Chat/Chats/test-chat.md\|test-chat]]            | 專案筆記 | 2023-03-07 10:48:33 |
| [[000-Index/!!! StartHere !!!.md\|!!! StartHere !!!]] | 專案筆記 | 2022-03-26 16:21:32 |

3. 相關鏈接

4. 教學影片

##

您可能也會有興趣的類似文章

Obs131|Obsidian使用Dataviewjs動態查詢的嘗試

$
0
0

[!WARNING]+ 建議
建議有程式設計經驗的朋友們試用,本次介紹的是概念性的嘗試,不見得會增進你的筆記流程的完整性。

gh|700

1. 插入訊息區域

為了顯示更醒目的執行訊息,在筆記開頭處插入HTML標籤。

![gh|400](https://raw.githubusercontent.com/emisjerry/upgit/master/2023/1684643871000ycb31l.png)

![gh|400](https://raw.githubusercontent.com/emisjerry/upgit/master/2023/1684643933000pv6sau.png)

程式裡用 document.getElementById("ID") 取到HTML元素物件。

let MSG = document.getElementById("MSG");

eleDate.onfocus = function() {
  MSG.innerText = "";
}

2. 日期與標籤輸入元素

使用下列程式碼插入日期與標籤的輸入欄位,最後再加上查詢按鈕。

// Date input 
dv.span("Date: ");
let today = dv.date("today");
let eleDate = dv.el("input");
eleDate.value = dv.date("today").toString().substring(0, 10);
eleDate.style.width = "120px";

// Tag input
dv.span("  ");
dv.span("Tag: ");
let eleTag = dv.el("input");
eleTag.style.width = "120px";

// Query button
dv.span("  ");
let eleBtn = dv.el("button", "Query");

3. Dataviewjs查詢

  • 取出標籤元素的輸入值,形成井號標籤字串
  • 筆記過濾條件:略過 010-Templates與050-Scripts,若有輸入標籤則加入標籤條件(AND)
  • 顯示鏈接、標籤字串、建檔日、修改日、檔案大小(加入千位點)
  let data = [];
  try {
    let sTag = "";
    if (eleTag.value != "") {
      sTag = " and #" + eleTag.value;
    }
    data = dv.pages('-"010-Templates" and -"050-Scripts"'+sTag)
      .where(p=> p.file.mday.toString().substring(0,10)==sDate)
      .map(p => [ p.file.link, /*p.tags*/ "#"+p.tags.join(" #"), 
      p.created.substring(0,10), p.modified.substring(0,10), 
      p.file.size.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")]);
  } catch (e) {
    MSG.innerText = e.message;
  }
  // ...
  dv.header(2, sDate);
  dv.table(["File("+data.length+")", "Tags", "Created", "Modified", "Size"], 
    data);

4. 腳本原始碼

```dataviewjs
// Date input 
dv.span("Date: ");
let today = dv.date("today");
let eleDate = dv.el("input");
eleDate.value = dv.date("today").toString().substring(0, 10);
eleDate.style.width = "120px";

// Tag input
dv.span("  ");
dv.span("Tag: ");
let eleTag = dv.el("input");
eleTag.style.width = "120px";

// Query button
dv.span("  ");
let eleBtn = dv.el("button", "Query");
let MSG = document.getElementById("MSG");

function msg(sMsg) {
  new Notice(sMsg);
  MSG.innerText = sMsg;
}

eleDate.onfocus = function() {
  MSG.innerText = "";
}

eleBtn.onclick = function() {
  const sDate = eleDate.value;
  if (!dv.date(sDate)) {
    new Notice("Invalid date format!");
    MSG.innerText = "Invalid date format! Please try again.";
    return;
  }
  let data = [];
  try {
    let sTag = "";
    if (eleTag.value != "") {
      sTag = " and #" + eleTag.value;
    }
    data = dv.pages('-"010-Templates" and -"050-Scripts"'+sTag)
      .where(p=> p.file.mday.toString().substring(0,10)==sDate)
      .map(p => [ p.file.link, /*p.tags*/ "#"+p.tags.join(" #"), 
      p.created.substring(0,10), p.modified.substring(0,10), 
      p.file.size.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")]);
  } catch (e) {
    MSG.innerText = e.message;
  }
  msg("Matched items: " + data.length);
  let md_table = dv.markdownTable(["File("+data.length+")", "Tags", 
    "Created", "Modified", "Size"], data);
  if (data.length > 0) {
    dv.header(2, sDate);
    //dv.span(table);
    dv.table(["File", "Tags", 
      "Created", "Modified", "Size"], data);
    navigator.clipboard.writeText(md_table);
  }
}

5. 相關鏈接

6. 教學影片

https://youtu.be/JDPMHoZbjow

##

您可能也會有興趣的類似文章

Obs132|標籤使用彙總與TagFolder:多重+階層式標籤資料夾,更妥善使用#標籤的技巧

$
0
0

gh|600

要在眾多筆記裡找到需要的內容時,我首先會使用全文檢索,輸入關鍵字搜尋;雖然Obsidian的搜尋功能已算頗強了,但如果仍無法尋獲需要的內容時,會再透過標籤來查詢。

[!TIP]+ 技巧
不要忘了Obsidian的所有檔案都在本地硬碟裡,因此搜尋的大招是用文字或程式編輯器或命令行(grep, ripgrep等)做正則運算式的搜尋

本次影片彙總標籤在使用上的常見問題、Obsidian的標籤種類、通常的使用方法,和我在實際使用時的處理方案,若觀眾們有更好的方法的話,請提出討論,以收集思廣益之效。

1. 標籤的問題

  • 標籤過多
  • 名稱不一致
  • 管理困難

2. Obsidian標籤分類

Obsidian的標籤有兩大類:

  1. 筆記(頁面)標籤:針對整個筆記檔案的標籤,寫在YAML區或本文區獨立一行
  2. 行內標籤:加在區塊後方的標籤(與區塊文字之間必須至少有一個空白)

3. 標籤的使用方法

標籤的使用有兩大類型:

  1. 內容標籤:方便搜尋與聯想的筆記屬性標籤:例如 #旅遊/半日遊#旅遊/一日遊
    1. 內容分類的關鍵字,以聯想可能性為優先
    2. 筆記的外在屬性,例如閱讀筆記中的作者姓名與出版日期等
  2. 場景標籤:進度與使用情境的狀態標籤:例如 #todo#important#next-week
    • 我並不使用此類標籤,而是採用Kanban來管理

另外我也沒有使用巢狀式標籤的習慣,採用扁平式的「大」標籤系統。

4. 外掛1-TagFolder基本概念

  • 自動形成巢狀式(階層式)的父-子標籤,互相嵌套

4.1. 範例

筆記名稱 使用標籤 搜尋路徑
Apple.md #red, #sweet #red
#sweet
#red #sweet
#sweet #red
Peach.md #sweet #sweet
Strawberry.md #red #red

![[TagFolder-1|700]]

gh|300

gh|300

gh|300

gh|700

[!INFO] 心得
TagFolder其實就是用聯集的方法把標籤的各種組合呈現出來

4.2. 特點

  • _untagged 標籤自動列出缺少標籤的筆記
  • 標籤核心外掛點擊標籤時都會做標籤搜尋,TagFolder則立即顯示
    • 💡建議啟用【List files in a separated pane】,將使用該標籤的筆記顯示在下方窗格
  • 可設定【Ignore Folders】,以前放在模板檔裡的標籤不再出現
  • 右鍵功能表提供的方便功能
    • 可釘選常用標籤
    • 點擊標籤數量或右鍵【Open scroll view】可將其所屬筆記在右窗格合併顯示
  • 工具列
    • 可指定標籤與檔名的排序方式
    • 可指定擴展階層
    • 可過濾標題,可使用的搜尋語法:「3c -NAS | server」
  • 虛擬標題用圖示顯示最後修改日期的符號
Icon Edited ...
🕐 Within an hour
📖 Within 6 hours
📗 Within 3 days
📚 Within 7 days
🗄 Older than 7 days ago

5. 可能的解決方案

問題點 可能的應對方法
標籤過多 多重標籤
名稱不一致 TagFolder的Pin應能減輕部份負擔
管理困難 改寫MOC以Dataview查詢標籤產出各種鏈接

6. 外掛2-標籤管理 Tag Wrangler

  • 功用:重新命名、搜尋等功能。
  • 操作方法:在標籤側邊欄找到要操作的標籤後,用右鍵功能表彈出功能表

tag1|400

7. 相關鏈接

9. 教學影片

##

您可能也會有興趣的類似文章

Obs133 | Properties (Obsidian 1.4)! 視覺化YAML編輯,讓Frontmatter可用性又向上一階

$
0
0

彙總Obsidian最近幾個大版本添加的新功能:

  • v1.0: Tabs
  • v1.1: Canvas
  • v1.2: Bookmarks
  • v1.3: New PDF viewer
  • v1.4: Properties

1. Properties (特性,性質)

我們使用中的筆記就是個電子檔案,檔案具有作業系統指派的檔案屬性(路徑檔名、建檔時間、最後存取時間等),而編輯中的純文字檔就是透過最開頭的YAML區為筆記賦予了自訂的屬性(或特性),例如編輯中的讀書筆記就可以有專用的特性:

  • 作者姓名
  • 出版日期
  • 出版社
  • 閱讀起迄日期
  • ...

YAML區的這些自訂的特性(Frontmatter)擴充了純文字本身內容以外的意義,由文字延伸成可供再利用的資料,再藉由Dataview外掛(或開發中的核心外掛Datacore)就能再由資料中萃取成資訊。

[!TIP]+ PKM的目標
文字→資料→資訊→知識

2. Properties相關重點

2.1. 新增命令

  • Add file property (預設按鍵:Ctrl/Cmd+;)
  • Edit file property
  • Clear file prolperties
  • Properties Core plugin: Show all properties
  • Properties Core plugin: Show file properties

    2.2. 設定

  • YAML區顯示切換:Settings→Editor→Display→Show file properties
  • Properties Core plugin: 將全部或檔案的YAML顯示成獨立窗格

2.3. Property type (特性種類)

YAML欄位的類型:

  • Text:文字類型
  • List:清單類型
  • Number:數值類型
  • Checkbox:核取盒(真假值)
  • Date:日期類型
  • Time:日期+時間類型

2.4. 操作

  • 最開頭的Properties可切換顯示/隱藏
  • 點擊最左側的圖示可顯示功能單
    • 由Property type指定此特性的種類
    • 用Remove移除不需要的特性 (點擊圖示後按 Del比較快)
  • 點擊左側圖示後,移動游標到另一個圖示按 Shift+Click即可多行選取
  • 點擊左側圖示後可拖拉該行,放開即可移動到新位置

    3. Properties的好處

  • 一致性:雖然YAML區可 透過模板來產生初始的內容,但假以時日, 特性和標籤都面臨不易管理的問題,透過核心外掛的功能可以降低管理成本,讓特性逐漸達到一致性的運用
  • 搜尋:點擊特性窗格的特性後,能搜尋出使用該特性的筆記
  • 易用性:方便入門者使用Frontmatter的門檻,透過種類的輸入檢核可確保輸入正確格式的資料值

    4. 已知問題

    1. 在我的模板裡使用下列方法在建立新筆記時可挑選筆記種類:
---
type: {{FT_type:choice:專案筆記:彙總筆記:閱讀筆記:永久筆記}}
---

但目前Properties外掛不會排除模板的值而造成問題:
gh|600

  1. Linter修改時間無法更新

    5. Attribute vs Property (屬性與特性)

    [!COMMENT]+ Attribute vs Property

    • The difference is subtle. Attributes are refering to additional information of an object. Properties are describing the characteristics of an object. Most people use these two words as synonyms.
    • 差異是微妙的。屬性是指物件的附加資訊。特性是描述物件的特徵。大多數人將這兩個詞視為同義詞。

6. 相關鏈接

##

您可能也會有興趣的類似文章

使用Subtitle Edit合併兩個.srt字幕檔的方法,讓播放時間自動調整

$
0
0

如何簡單的合併兩個 .srt 字幕檔呢?合併兩個文字格式的 .srt 不難,但要能自動調整每句字幕的時間與播放長度才是最困難的工程。透過Subtitle Edit,我們就可輕鬆的完成了。

載入.srt後,移動到字幕最後一行→右鍵→由右鍵功能表選用【在此行之後插入字幕...】,再選取第二個.srt檔,如此就能合併兩個檔案了,時間也會自動調整。

相關鏈接

教學影片

https://youtu.be/rjtDsKjXeTE

##

您可能也會有興趣的類似文章


Obs134|用Dataviewjs製作簡單的建檔統計圖-使用Charts外掛

$
0
0

h使用Charts外掛可以輕鬆地產生統計表,資料來源則使用Dataviewjs來查詢一段時間內的建檔筆記數量統計。

1. Charts基本使用

Charts外掛安裝後可以調用Insert new Chart命令,輸入三個欄位資料:

  • X-Axis (X軸標題): Aug. 10, Aug. 11, Aug. 12
  • Y-Axis Name (Y軸標題): Number of created
  • Y-Axis Data (Y軸資料): 10, 5, 3
  • Start at Zero: 勾選

gh|700

```chart
type: bar
labels: [Aug. 10, Aug. 11, Aug. 12]
series:
  - title: Number of Created
    data: [10, 5, 3]
tension: 0.2
width: 80%
labelColors: false
fill: false
beginAtZero: true
bestFit: false
bestFitTitle: undefined
bestFitNumber: 0
```

gh

2. Dataviewjs統計

gh

gh

---
aliases: []
created: 2023-05-22 18:32:55
modified: 2023-08-12 12:27:05
number headings: first-level 1, max 6, _.1.1.
tags: []
type:
  - 專案筆記
folder: '""'
daysback: 3
chartDays: 100
---
# Chart Test

```dataviewjs
const iDaysback = parseInt(dv.current().daysback) || 2;
const iChartDays = parseInt(dv.current().chartDays) || 10;

const lStartTime = moment();
const sFolder = dv.current().folder || &#039;&#039;;  // 要統計的資料夾
// const dateField = &#039;created&#039;; // 使用YAML欄位時需要
const sChartColor = &#039;#4e9a06&#039;;
const oDocs = dv.pages(sFolder);

function getRecentDocs(iNumDays) {
  return oDocs.where(f => {
    //if (!f[dateField]) return false;  // 如果沒有日期欄位則不繼續處理
    const lPastTime = moment().subtract(iNumDays, &#039;days&#039;);
    let lDocTime = f.file.ctime;   // moment(f[dateField]);  //.toISO());
    let valid = lDocTime >= lPastTime && lStartTime >= lDocTime;  //.isAfter(lPastTime) && lDocTime.isBefore(start);
    return valid;
  });
}

// creating the table
var oChartDocs = getRecentDocs(iDaysback);

// 輸出表格樣式的符合條件筆記清單
dv.span(iDaysback + " days ago");
dv.table([&#039;link&#039;, &#039;Created on&#039;], oChartDocs
    .sort(file => file.file.ctime, &#039;desc&#039;)
    .map(page => [page.file.link, page.file.ctime]));

// creating the charts
var oChartDocs = getRecentDocs(iChartDays).sort(f => f.file.ctime);
var daysData = [];
var totalcount = 0;

dv.paragraph(iChartDays + " days ago");
// formatting the data
for (var i=0; i<=oChartDocs.length; i++) {
  var f = oChartDocs[i];
  if (f) {
    var itemDate = moment(f.file.ctime.ts);  //moment(f[dateField]);
    var newDate = moment(itemDate).format(&#039;MM-DD&#039;);
     var index = daysData.findIndex(d => d.label === newDate);
    if (index !== -1) {
        daysData[index].num += 1;  // 該日數值遞增
    } else {
        daysData.push({label: newDate, num: 1});  // 該日啟始為1
    }
    totalcount += 1;
  }
};

var labels = [], data = [], aggData = [];

daysData.map(el => {
  labels.push(el.label);
  data.push(el.num);

  if (aggData.length) {
    var lastNum = aggData[aggData.length - 1];
    aggData.push(el.num + lastNum);
  } else {
    aggData.push(el.num);
  }
});

const lineChart = {
  type: &#039;line&#039;,
  data: {
    labels: labels,
    datasets: [{
      label: &#039;Docs created&#039;,
      data: data,
      backgroundColor: [
        sChartColor
      ],
      borderColor: [
        sChartColor
      ],
      borderWidth: 1
    }]
  }
}

const aggregateChart = {
  type: &#039;line&#039;,
  data: {
    labels: labels,
    datasets: [{
      label: &#039;Aggregate Docs Created&#039;,
      data: aggData,
      backgroundColor: [
          sChartColor
      ],
      borderColor: [
          sChartColor
      ],
      borderWidth: 1
    }]
  }
}

dv.paragraph(&#039;Created Chart&#039;);
window.renderChart(lineChart, this.container);

dv.paragraph(&#039;Growth Chart&#039;);
window.renderChart(aggregateChart, this.container);

dv.paragraph(&#039;Total: &#039; + totalcount);
```

3. 相關鏈接

4. 教學影片

##

您可能也會有興趣的類似文章

Obs135|解鎖簡易Dataview查詢:驚人的SQL技巧,使用Query All The Things(QATT)外掛

$
0
0

Dataview可以很方便的透過Obsidian的Metadata來蒐集筆記資訊,雖然Dataview的查詢語法不複雜,但輸出格式固定,需要較不同的輸出樣式時就必須透過稍複雜的Dataviewjs,以JavaScript來撰寫。Query All The Things (以下簡稱qatt) 外掛則嘗試填平簡單語法+自訂輸出格式之間的差距。

Qatt以類SQL語法當做查詢語言,以Handlebars當做輸出模板引擎,要活用Qatt就必須學習它的SQL語法與Handlebars模板語言。

1. 撰寫第一個qatt程式碼區塊

和Dataview一樣,qatt也是透過程式碼區塊來動態執行的,程式碼區塊的語言指定為==qatt==,以YAML語法提供querytemplate兩個欄位:

query: |
  SELECT TOP 5 *, moment(stat->ctime)->format("YYYY-MM-DD") ctime
  FROM obsidian_markdown_notes
  WHERE 'obsidian' in tags
  ORDER BY stat->ctime DESC
template: |
      {{#each result}}
        - {{ctime}} [[{{path}}\|{{basename}}]]
      {{/each}}

執行結果:

gh

  • YAML語法裡的 | 指定關鍵欄位的內容是區塊
  • 區塊內不要用 4 個空白開頭,以免被渲染成區塊

1.1. query重點

  • select ... from ... order by ... 是標準的SQL語法
  • obsidian_markdown_files 是Obsidian系統裡的所有筆記檔案
  • SQL標準的 . 在Qatt裡要改用 ->

1.2. template重點

  • 查詢後的結果用{{#each result}}{{/each}}裡的樣式輸出
  • 輸出欄位用兩個大括號夾住,如:{{basename}}

1.3. Another sample

query: |
  SELECT TOP 10 
  basename, path, moment(stat->mtime).format() as LastModified
  from obsidian_markdown_notes
  where moment(stat->mtime)->isAfter(moment().startOf('month'))
template: |
  | Name | Path | Last Modified |
  | --- | --- | ---|
  {{#each result}}
  | {{basename}} | {{path}} | {{LastModified}} |
  {{/each}}

2. 資料表

3. HTML輸出範例

3.1. 資料表:dataview_pages

postRenderFormat: html
query: |
  SELECT top 5 tags, file->name name, file->path path, file->link->path link, created
  FROM dataview_pages
  WHERE 'obsidian' in tags and file->path not like '%template%'
  ORDER BY file->ctime DESC
template: |
  <table>
  <tr><th>建檔日期</th><th>檔名</th><th>標籤</th></tr>
  {{#each result}} 
  <tr><td>{{created}}</td><td> <a href="{{link}}" target="_blank" class="internal-link" >{{name}}</a> </td><td> {{tags}} </td></tr>
  {{/each}}
  </table>

gh

3.2. 資料表: obsidian_markdown_notes

query: |
  SELECT top 5 REPLACE(CAST(tags as varchar),',', ' ') tags, basename, 
  makeMarkdownLink(basename, path) AS mdLink,
    REPLACE(path, ' ', '%20') path, 
    moment(stat->ctime).format("YYYY-MM-DD hh:mm") created
  FROM obsidian_markdown_notes
  WHERE 'obsidian' in tags and path not like '%template%'
  ORDER BY stat->ctime DESC
template: |
  | Created on | File name | Tags |
  |--|--|--|
  {{#each result}} 
  |{{created}}| [{{basename}}]({{path}}) | {{tags}}|
  {{/each}}

gh

[!WARNING]+ 注意!
資料表obsidian_markdown_notes與dataview_pages裡欄位不同,小心使用

4. 相關鏈接

5. 教學影片

##

您可能也會有興趣的類似文章

VS Code的套殼:「全国首款支持多环境开发的 IDE —— CEC-IDE」

$
0
0

今天對岸的OSChina公佈了一個訊息:全国首款支持多环境开发的 IDE —— CEC-IDE

gh|700

引發了眾多正義之士的憤慨,紛紛到微軟VS Code的GitHub上張貼Issue,最終有人看不下去了,發出了沉重呼籲(貼文原址):

gh

##

您可能也會有興趣的類似文章

Obs136|3 個方法讓你用Obsidian QATT外掛讀取外部檔案

$
0
0

Query All The Things (QATT) 除了能用obsidian_markdown_notes、dataview_pages等資料表當做資料來源之外,也能指定儲存庫裡的其他檔案(CSV、Markdown或JSON格式)來當做資料來源,如此就能用SQL來對這些外部檔案做查詢,並透過Handlebars模板來輸出內容了。

操作步驟如下。

1. 建立資料表

我們必須把要操作的檔案在設定裡指定好,在Obsidian與QATT啟動時,會依檔案內第一行建立內部資料表。

下圖指定了兩個CSV格式的檔案,030_Inbox/visit_places.md 副檔名雖然是.md,但其內容是CSV格式。副檔名.md時就能使用Obsidian直接開啟與編輯。資料是即時呈現的,當你在外部新增資料後,Obsidian會立即顯示變動。

外部檔也能使用網址的形式,格式是:「WEB|資料表名稱|傳回資料的網址」,例如:WEB|test_posts|https://jsonplaceholder.typicode.com/posts
gh

2. QATT範例1

2.1. visit_places.md

第一行是欄位,注意:欄位逗點後不能有空白。

country,visit_date,visit_days
Japan日本, 2022-12-28, 10
USA, 2020-12-30, 14
Singapore, 2017-05-05, 7
Korea, 2018-01-02, 10

2.2. 查詢與輸出

query: |
  select country, visit_date, visit_days
  from visit_places
  order by visit_date
template: |
  | Country | Visit Date | Visit Days |
  |--|--|--:|
  {{#each result}}
  | {{country}} | {{visit_date}} | {{visit_days}} |
  {{/each}}
  • 輸出依visit_date排序

gh|500

[!TIP]+ 技巧
如果QATT顯示Table does not exist:錯誤時,進入QATT的程式碼區塊後再離開,應該就會重新渲染了

3. QATT範例2

透過網頁內容的設定格式是:WEB|test_posts|https://jsonplaceholder.typicode.com/posts,傳回的內容是:
gh|500

query: |
  select top 30 *
  from test_posts
template: |
  {{#each result}}
   - {{id}},{{title}}
  {{/each}}

4. 相關鏈接

5. 教學影片

https://youtu.be/sw1NiqawWlM

##

您可能也會有興趣的類似文章

Obs137|用Dataviewjs讀取CSV資料以繪製統計圖表

$
0
0

Dataviewjs可以用下列3種函數讀取外部檔案:

[!COMMENT]+ Dataviewjs讀檔

  1. 內容 = await dv.io.csv(路徑, [origin-file])
  2. 內容 = await dv.io.load(路徑, [origin-file])
  3. dv.io.normalize(路徑, [origin-file]): 將相對路徑鏈接轉換成絕對路徑

gh|500

1. 原始碼

let data = await dv.io.csv("visit_places.csv");
//data = data.sort(r => r.country);
//dv.table(["Country", "Date", "Days"], data.map(r => [r.country, r.visit_date, r.visit_days])) 

var labels = [];
const sChartColor = '#4e9a06';

const lineChart = {
  type: 'bar',
  width: '50%',
  data: {
    labels: data.country.values,
    datasets: [{
      label: 'Days',
      data: data.visit_days.values,
      backgroundColor: [
        sChartColor
      ],
      borderColor: [
        "white"
      ],
      borderWidth: 1
    }]
  }
}  // lineChart

window.renderChart(lineChart, this.container);

2. 相關鏈接

3. 教學影片

##

您可能也會有興趣的類似文章

Viewing all 904 articles
Browse latest View live