-
Notifications
You must be signed in to change notification settings - Fork 7
/
tag-ontology.html
91 lines (81 loc) · 4.89 KB
/
tag-ontology.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
---
title: "The Tag Ontology Viewer"
---
<div id="hello">
Below you'll find a flowchart explaining the relationship between all the published and planned tags.
Scroll left to right to see deeper into the ontology.
Click on any node to open it up.
Courses without associated tags are given diamonds.
Published tags are in bold.
</div>
<input id="secondaries" type="checkbox"><label for="secondaries" style="font-weight: unset;">
Show secondary edges →</label><br>
<div id="loading">Loading...
<i class="fas fa-spinner fa-spin-pulse"></i>
</div>
<div id="disp" style="overflow-x: auto;"></div>
<div id="others"></div>
<script type="module">
import * as d3 from "https://cdn.jsdelivr.net/npm/d3@7/+esm";
import { graphviz } from "https://cdn.jsdelivr.net/npm/d3-graphviz@5/+esm";
var edgetoggle = d3.select("input#secondaries");
edgetoggle.disabled = true;
function transitionFactory() {
return d3.transition("main").ease(d3.easeLinear).duration(300);
}
{% assign knownslugs = '' | split: '' %}
const nodedata = `
{% for t in site.tags %}{% assign knownslugs = knownslugs | push: t.slug %}{{ t.slug | replace: "-", "_" }} [label="{{ t.slug }}" tooltip="{{ t.title }}" URL="{{ t.url }}" style="{% if t.status == "published" %}bold" fontsize="15{% else %}solid{% endif %}"]
{% endfor %}{% for c in site.data.course_order %}{% if knownslugs contains c %}{% continue %}{% endif %}
{{ c | replace: "-", "_" }} [label="{{ c }}" URL="/courses/{{ c }}" style="bold" shape="Mdiamond"]{% assign knownslugs = knownslugs | push: c %}{% endfor %}
`;
const primaryedgedata = `
{% for t in site.tags %}{% if t.level == 1 %}{% continue %}{% endif %}{% for p in t.parents %}{% unless knownslugs contains p %}{% continue %}{% endunless %}{{p | replace: "-", "_" }} -> {{t.slug | replace: "-", "_" }} [penwidth={% if t.status == "published" %}2{% else %}1{% endif %} weight=7]{% break %}
{% endfor %}{% endfor %}
{% for c in site.courses %}{% if c.slug == "philosophy" %}{% continue %}{% endif %}{% for t in c.tags %}{% unless knownslugs contains t %}{% continue %}{% endunless %}{{ t | replace: "-", "_" }} -> {{ c.slug | replace: "-", "_" }} [style="dashed"] {% break %}{% endfor %}{% endfor %}
`;
const secondaryedgedata = `
{% for t in site.tags %}{% if t.level == 1 %}{% continue %}{% endif %}{% for p in t.parents %}{% unless knownslugs contains p and forloop.index0 > 0 %}{% continue %}{% endunless %}{{p | replace: "-", "_" }} -> {{t.slug | replace: "-", "_" }} [penwidth={% if t.status == "published" %}0.8{% else %}0.5{% endif %}]
{% endfor %}{% endfor %}
{% for c in site.courses %}{% if c.slug == "philosophy" %}{% continue %}{% endif %}{% for t in c.tags %}{% unless knownslugs contains t and forloop.index0 > 0 %}{% continue %}{% endunless %}{{ t | replace: "-", "_" }} -> {{ c.slug | replace: "-", "_" }} [style="dashed"]
{% endfor %}{% endfor %}
`;
var graph = graphviz("#disp").fit(true).zoom(false).transition(transitionFactory).tweenShapes(true).on("initEnd", render);
function render() {
var splines = "splines=true;";
var edgedata = primaryedgedata;
if (edgetoggle.checked) {
splines = "splines=false;";
edgedata += secondaryedgedata;
}
graph.renderDot(`digraph { rankdir="LR"
node [style="dashed" fontname="arial"]
${splines}
{ rank=same world buddhism }
${nodedata}
${edgedata}
}`).on("end",function(){
var thesvg = document.querySelector("#disp svg");
thesvg.setAttribute("width", parseFloat(thesvg.getAttribute("width"))*0.8);
thesvg.setAttribute("height", parseFloat(thesvg.getAttribute("height"))*0.8);
edgetoggle.disabled = false;
d3.select("div#loading").style("display", "none");
});
}
edgetoggle.on("change",updateGraph);
function updateGraph() {
this.disabled = true;
edgetoggle = this;
d3.select("div#loading").style("display", "block");
setTimeout(render);
}
const othertags = [{% for c in site.content %}{% if c.course %}{% unless knownslugs contains c.course %}"{{ c.course }}",{% endunless %}{% endif %}{% for t in c.tags %}{% unless knownslugs contains t %}"{{ t }}",{% endunless %}{% endfor %}{% endfor %}];
const ots = Object.entries(
othertags.reduce((map, val) => { map[val] = (map[val] || 0) + 1; return map; }, {})
).map(
([slug, count]) => ({slug, count})
).sort(
(a, b) => b.count - a.count || a.slug.localeCompare(b.slug)
);
d3.select("#others").html(`<h2>Misc Tags</h2><p>Below is a list of all the "shadow" tags which have been used on library content but which haven't yet been added to the above ontology. Some of these are vaguely planned for addition in the far future, but some are just keywords.</p><table><tr><th>Tag</th><th>Content Count</th></tr>${ots.map((t)=>`<tr><td><a href="https://buddhistuniversity.net/search/?q=tag%3A${t.slug.replace("-","%20tag%3A")}">${t.slug}</a></td><td>${t.count}</td></tr>`).join('')}</table>`);
</script>