renaming, cleanup
This commit is contained in:
8
Makefile
8
Makefile
@@ -1,8 +1,6 @@
|
|||||||
|
|
||||||
dist/wikimap.js: src/*.js
|
all: dist/app.js
|
||||||
# node_modules/.bin/rollup src/index.js --file dist/index.js --format iife
|
|
||||||
node_modules/.bin/rollup -c
|
dist/app.js: src/*.js
|
||||||
|
|
||||||
dist/%.js: src/%.js src/*.js
|
|
||||||
# node_modules/.bin/rollup src/index.js --file dist/index.js --format iife
|
# node_modules/.bin/rollup src/index.js --file dist/index.js --format iife
|
||||||
node_modules/.bin/rollup -c
|
node_modules/.bin/rollup -c
|
||||||
5555
dist/app.js
vendored
Normal file
5555
dist/app.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -37,6 +37,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
<script src="custom_scroller_menu.js"></script>
|
<script src="custom_scroller_menu.js"></script>
|
||||||
<script type="text/javascript" src="dist/wikimaptotal.js"></script>
|
<script type="text/javascript" src="dist/app.js"></script>
|
||||||
<script src="index.js"></script>
|
<script src="index.js"></script>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
2
index.js
2
index.js
@@ -41,7 +41,7 @@ var symbols = {
|
|||||||
"Enseignants": "symbols.svg#Enseignants",
|
"Enseignants": "symbols.svg#Enseignants",
|
||||||
"default": "symbols.svg#Main"
|
"default": "symbols.svg#Main"
|
||||||
};
|
};
|
||||||
var map = new wikimap.SimpleMap(symbols);
|
var map = new app.Map(symbols);
|
||||||
|
|
||||||
map.init_svg("#svg");
|
map.init_svg("#svg");
|
||||||
async function doload () {
|
async function doload () {
|
||||||
|
|||||||
@@ -4,26 +4,14 @@ import commonjs from 'rollup-plugin-commonjs';
|
|||||||
import resolve from 'rollup-plugin-node-resolve';
|
import resolve from 'rollup-plugin-node-resolve';
|
||||||
|
|
||||||
export default [{
|
export default [{
|
||||||
input: 'src/wikimap.js',
|
input: 'src/app.js',
|
||||||
output: {
|
output: {
|
||||||
file: 'dist/wikimap.js',
|
file: 'dist/app.js',
|
||||||
format: 'iife',
|
format: 'iife',
|
||||||
name: 'wikimap'
|
name: 'app'
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
resolve(),
|
resolve(),
|
||||||
commonjs()
|
commonjs()
|
||||||
]
|
]
|
||||||
},{
|
}];
|
||||||
input: 'src/wikimaptotal.js',
|
|
||||||
output: {
|
|
||||||
file: 'dist/wikimaptotal.js',
|
|
||||||
format: 'iife',
|
|
||||||
name: 'wikimap'
|
|
||||||
},
|
|
||||||
plugins: [
|
|
||||||
resolve(),
|
|
||||||
commonjs()
|
|
||||||
]
|
|
||||||
}
|
|
||||||
];
|
|
||||||
2
src/app.js
Normal file
2
src/app.js
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
import { Map } from './wikimap.js';
|
||||||
|
export { Map };
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
export function test () {
|
|
||||||
alert("testing import");
|
|
||||||
}
|
|
||||||
326
src/wikimap.js
326
src/wikimap.js
@@ -1,142 +1,172 @@
|
|||||||
import { event, select, selectAll} from 'd3-selection';
|
import { event, select, selectAll} from 'd3-selection';
|
||||||
import { values, set, map } from 'd3-collection';
|
import { values, set, map } from 'd3-collection';
|
||||||
import { drag } from 'd3-drag';
|
import { drag } from 'd3-drag';
|
||||||
|
import { zoom } from 'd3-zoom';
|
||||||
import { forceSimulation, forceLink, forceManyBody, forceCenter, forceX, forceY, forceRadial } from 'd3-force';
|
import { forceSimulation, forceLink, forceManyBody, forceCenter, forceX, forceY, forceRadial } from 'd3-force';
|
||||||
import { Wiki, Page } from './wiki.js';
|
import { Wiki, Page } from './wiki.js';
|
||||||
import EventEmitter from 'eventemitter3';
|
import EventEmitter from 'eventemitter3';
|
||||||
|
import { json } from 'd3-fetch';
|
||||||
|
|
||||||
|
import { ForceNet } from './forcenet.js';
|
||||||
|
|
||||||
export class Map {
|
export class Map {
|
||||||
|
|
||||||
constructor (apiurl) {
|
constructor (symbols) {
|
||||||
var width = 600,
|
var width = 600,
|
||||||
height = 600;
|
height = 600;
|
||||||
this.wiki = new Wiki(apiurl);
|
|
||||||
this.events = new EventEmitter();
|
this.events = new EventEmitter();
|
||||||
this.active_page = null;
|
this.active_page = null;
|
||||||
// this.nodes = {};
|
// this.nodes = {};
|
||||||
this.simulation = forceSimulation()
|
this.symbols = symbols;
|
||||||
.velocityDecay(0.1)
|
this.net = new ForceNet(symbols);
|
||||||
.force("link", forceLink().id(d => d.title))
|
this.net.on("nodeclick", this.nodeclick.bind(this));
|
||||||
.force("charge", forceManyBody())
|
// this.simulation = forceSimulation()
|
||||||
.force("radial", forceRadial(180, width/2, height/2));
|
// .velocityDecay(0.1)
|
||||||
// .force("center", forceCenter(width / 2, height / 2));
|
// .force("link", forceLink().id(d => d.title))
|
||||||
|
// .force("charge", forceManyBody())
|
||||||
|
// .force("radial", forceRadial(180, width/2, height/2));
|
||||||
|
// // .force("center", forceCenter(width / 2, height / 2));
|
||||||
this.svg = null;
|
this.svg = null;
|
||||||
this.historylinks = {};
|
this.historylinks = {};
|
||||||
|
this.links = null;
|
||||||
|
this.highlight_category = null;
|
||||||
|
this.show_history = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeclick (d, elt) {
|
||||||
|
console.log("nodeclick", d, elt, this);
|
||||||
|
this.set_active_node(d, elt);
|
||||||
|
}
|
||||||
|
|
||||||
|
init_svg (svg) {
|
||||||
|
this.net.init_svg(svg);
|
||||||
|
}
|
||||||
|
|
||||||
|
async load_json (source) {
|
||||||
|
var data = await json(source);
|
||||||
|
// console.log("got data!", data);
|
||||||
|
// index the nodes by title, init link-arity count
|
||||||
|
var index = {};
|
||||||
|
this.nodes_by_title = index;
|
||||||
|
for (let i=0, l=data.nodes.length; i<l; i++) {
|
||||||
|
let node = data.nodes[i];
|
||||||
|
node.count = 0;
|
||||||
|
index[node.title] = node;
|
||||||
|
}
|
||||||
|
this.nodes = data.nodes;
|
||||||
|
|
||||||
|
var use_links = [];
|
||||||
|
data.links = data.links.forEach(x => {
|
||||||
|
var source = index[x.source],
|
||||||
|
target = index[x.target];
|
||||||
|
if (source === undefined) {
|
||||||
|
console.log("bad source", x.source);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (target === undefined) {
|
||||||
|
console.log("bad target", x.target);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
source.count += 1;
|
||||||
|
target.count += 1;
|
||||||
|
use_links.push({ source: source, target: target });
|
||||||
|
});
|
||||||
|
data.links = use_links;
|
||||||
|
this.links = data.links;
|
||||||
|
// console.log("data", data);
|
||||||
|
// calculate the node sizes (link arity)
|
||||||
|
this.net.update_graph(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
get_symbol_image_path (cname) {
|
||||||
|
var symbol = this.symbols[cname];
|
||||||
|
if (symbol) {
|
||||||
|
let hpos = symbol.indexOf("#"),
|
||||||
|
rest = symbol.substr(hpos+1);
|
||||||
|
rest = rest.replace(/'/g, '');
|
||||||
|
return "img/"+rest+".png";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async load_cats (src, elt) {
|
||||||
|
var data = await json(src);
|
||||||
|
|
||||||
|
console.log("indexing categories by title");
|
||||||
|
var cats_by_title = {};
|
||||||
|
for (let i=0, l=data.length; i<l; i++) {
|
||||||
|
let cat = data[i];
|
||||||
|
cats_by_title[cat.title] = cat;
|
||||||
|
cat.pages = [];
|
||||||
|
cat.tcount = 0;
|
||||||
|
}
|
||||||
|
// index categories
|
||||||
|
console.log("indexing categories");
|
||||||
|
for (let key in this.nodes_by_title) {
|
||||||
|
let node = this.nodes_by_title[key];
|
||||||
|
// console.log("key", key, node.cats);
|
||||||
|
for (let j=0, jl=node.cats.length; j<jl; j++) {
|
||||||
|
let cname = node.cats[j],
|
||||||
|
cat = cats_by_title[cname];
|
||||||
|
if (cat) {
|
||||||
|
// increment the category + parents
|
||||||
|
cat.pages.push(node);
|
||||||
|
cat.tcount += 1
|
||||||
|
while (cat.parent) {
|
||||||
|
cat = cats_by_title[cat.parent];
|
||||||
|
cat.tcount += 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log("Warning, unknown category", cname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log("pre filter", data.length);
|
||||||
|
data = data.filter(d => d.tcount > 0)
|
||||||
|
console.log("post filter", data.length);
|
||||||
|
console.log("load_cats.data", data, elt);
|
||||||
|
var cat = select(elt)
|
||||||
|
.selectAll("div.cat")
|
||||||
|
.data(data)
|
||||||
|
.enter()
|
||||||
|
.append("div")
|
||||||
|
.attr("class", "cat");
|
||||||
|
cat.classed("icon", d => this.get_symbol_image_path(d.title));
|
||||||
|
cat.append("span").attr("class", "icon").filter(d=> this.get_symbol_image_path(d.title)).style("background-image", d => "url("+this.get_symbol_image_path(d.title)+")");
|
||||||
|
cat.append("span").attr("class", "spacing").html(d => {
|
||||||
|
var d = d.depth,
|
||||||
|
ret = "";
|
||||||
|
while(d) {
|
||||||
|
ret += " ";
|
||||||
|
d-=1;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
});
|
||||||
|
cat.append("a").attr("class", "label").html(d => d.title).attr("href", "#").on("click", d => {
|
||||||
|
event.preventDefault();
|
||||||
|
this.category_click(d);
|
||||||
|
})
|
||||||
|
cat.append("span").attr("class", "count").html(d => d.tcount)
|
||||||
|
}
|
||||||
|
|
||||||
|
category_click (d) {
|
||||||
|
console.log("category click", d);
|
||||||
|
if (this.highlight_category) {
|
||||||
|
// cleanup old pages
|
||||||
|
this.highlight_category.pages.forEach(d => d.highlight = false);
|
||||||
|
}
|
||||||
|
this.highlight_category = d;
|
||||||
|
this.highlight_category.pages.forEach(d => d.highlight = true);
|
||||||
|
this.net.update_nodes();
|
||||||
|
// set highlight category...
|
||||||
|
// all nodes with this category get .highlight = true
|
||||||
|
// make a category index ?!
|
||||||
}
|
}
|
||||||
|
|
||||||
on (message, callback, context) {
|
on (message, callback, context) {
|
||||||
this.events.on(message, callback, context);
|
this.events.on(message, callback, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
init_svg (svg) {
|
/* OLD STYLE with node.all_links
|
||||||
this.svg = select(svg || "svg");
|
|
||||||
this.linksg = this.svg.append("g")
|
|
||||||
.attr("class", "links");
|
|
||||||
this.nodesg = this.svg.append("g")
|
|
||||||
.attr("class", "nodes");
|
|
||||||
}
|
|
||||||
|
|
||||||
dragstarted (d) {
|
|
||||||
if (!event.active) this.simulation.alphaTarget(0.3).restart();
|
|
||||||
d.fx = d.x;
|
|
||||||
d.fy = d.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
dragged (d) {
|
|
||||||
d.fx = event.x;
|
|
||||||
d.fy = event.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
dragended(d) {
|
|
||||||
if (!event.active) this.simulation.alphaTarget(0);
|
|
||||||
d.fx = null;
|
|
||||||
d.fy = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
update_graph (graph) {
|
|
||||||
// console.log("UPDATE GRAPH", graph.nodes.length, graph.links.length);
|
|
||||||
var that = this,
|
|
||||||
link = this.linksg.selectAll("line")
|
|
||||||
.data(graph.links, function (d) { return that.link_key(d.source.title, d.target.title) });
|
|
||||||
var link_enter = link.enter()
|
|
||||||
.append("line");
|
|
||||||
|
|
||||||
link.exit().each(d => {
|
|
||||||
d.source.linked = false;
|
|
||||||
d.target.linked = false;
|
|
||||||
}).remove();
|
|
||||||
|
|
||||||
link_enter.merge(link).each(d => {
|
|
||||||
d.source.linked = true;
|
|
||||||
d.target.linked = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
var node = this.nodesg
|
|
||||||
.selectAll("g.page")
|
|
||||||
.data(graph.nodes, function (d) { return d.title });
|
|
||||||
|
|
||||||
var node_enter = node.enter().append("g")
|
|
||||||
.attr("class", d=>"page "+this.wiki.get_ns_classname(d.ns))
|
|
||||||
.on("click", d => {
|
|
||||||
this.set_active_node(d.title);
|
|
||||||
})
|
|
||||||
.on("mouseover", function (d) {
|
|
||||||
// console.log("mouseover", this);
|
|
||||||
select(this).classed("mouse", true);
|
|
||||||
})
|
|
||||||
.on("mouseout", function (d) {
|
|
||||||
// console.log("mouseout", this);
|
|
||||||
select(this).classed("mouse", false);
|
|
||||||
})
|
|
||||||
.call(drag()
|
|
||||||
.on("start", this.dragstarted.bind(this))
|
|
||||||
.on("drag", this.dragged.bind(this))
|
|
||||||
.on("end", this.dragended.bind(this)));
|
|
||||||
|
|
||||||
node_enter.append("circle")
|
|
||||||
.attr("r", 6);
|
|
||||||
|
|
||||||
node_enter.append("text")
|
|
||||||
.text(d => d.title)
|
|
||||||
.attr("x", 10);
|
|
||||||
|
|
||||||
//node_enter.append("title")
|
|
||||||
// .text(function(d) { return d.title; });
|
|
||||||
|
|
||||||
node = node_enter.merge(node);
|
|
||||||
link = link_enter.merge(link);
|
|
||||||
|
|
||||||
node.classed("active", d=>d.active);
|
|
||||||
|
|
||||||
this.simulation
|
|
||||||
.nodes(graph.nodes)
|
|
||||||
.on("tick", ticked);
|
|
||||||
|
|
||||||
this.simulation.force("link")
|
|
||||||
.links(graph.links);
|
|
||||||
|
|
||||||
this.simulation.force("radial").radius(d => d.linked ? null : 200);
|
|
||||||
|
|
||||||
function ticked() {
|
|
||||||
link
|
|
||||||
.attr("x1", function(d) { return d.source.x; })
|
|
||||||
.attr("y1", function(d) { return d.source.y; })
|
|
||||||
.attr("x2", function(d) { return d.target.x; })
|
|
||||||
.attr("y2", function(d) { return d.target.y; });
|
|
||||||
|
|
||||||
// node
|
|
||||||
// .attr("cx", function(d) { return d.x; })
|
|
||||||
// .attr("cy", function(d) { return d.y; });
|
|
||||||
node
|
|
||||||
.attr("transform", d => `translate(${d.x},${d.y})`);
|
|
||||||
}
|
|
||||||
this.simulation.alphaTarget(0.3).restart();
|
|
||||||
}
|
|
||||||
|
|
||||||
link_key (a, b) {
|
|
||||||
return (a < b) ? ("link_"+a+"_"+b) : ("link_"+b+"_"+a);
|
|
||||||
}
|
|
||||||
|
|
||||||
walk (node, links) {
|
walk (node, links) {
|
||||||
var links_seen = {};
|
var links_seen = {};
|
||||||
// var node = this.ensure_node(nodename);
|
// var node = this.ensure_node(nodename);
|
||||||
@@ -149,35 +179,78 @@ export class Map {
|
|||||||
})
|
})
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
set_active_title (title) {
|
set_active_title (title) {
|
||||||
this.set_active_node(title);
|
this.set_active_node(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
activate_linked_nodes (page, active) {
|
||||||
|
// deactivate linked links/nodes
|
||||||
|
for (let i=0, l=this.links.length; i<l; i++) {
|
||||||
|
let link = this.links[i];
|
||||||
|
if (link.source == page || link.target == page) {
|
||||||
|
link.active2 = active;
|
||||||
|
link.source.active2 = active;
|
||||||
|
link.target.active2 = active;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async set_active_node (page) {
|
async set_active_node (page) {
|
||||||
if (typeof(page) === "string") {
|
if (typeof(page) === "string") {
|
||||||
page = this.wiki.get_page_by_title(page)
|
let pagename = page;
|
||||||
}
|
page = this.nodes_by_title[page];
|
||||||
|
|
||||||
|
if (!page) {
|
||||||
|
console.log("wikimap.set_active_node: page not found", pagename);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (page === this.active_page) {
|
if (page === this.active_page) {
|
||||||
// console.log("page is already the active page", page, this.active_page);
|
// console.log("page is already the active page", page, this.active_page);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this.active_page) {
|
if (this.active_page) {
|
||||||
this.active_page.active = false;
|
this.active_page.active = false;
|
||||||
var lkey = this.link_key(this.active_page.title, page.title),
|
// deactivate linked links/nodes
|
||||||
source = (this.active_page.title < page.title) ? this.active_page : page,
|
this.activate_linked_nodes(this.active_page, false);
|
||||||
target = (this.active_page.title < page.title) ? page : this.active_page;
|
// ENSURE HISTORY LINK TO PREVIOUS NODE AND CURRENT
|
||||||
this.historylinks[lkey] = {source: source, target: target};
|
var lkey = this.net.link_key(this.active_page.title, page.title),
|
||||||
|
source = (this.active_page.title < page.title) ? this.active_page : page,
|
||||||
|
target = (this.active_page.title < page.title) ? page : this.active_page;
|
||||||
|
this.historylinks[lkey] = {source: source, target: target, type:"history"};
|
||||||
}
|
}
|
||||||
// n = this.ensure_node(pagetitle);
|
|
||||||
|
|
||||||
this.active_page = page;
|
this.active_page = page;
|
||||||
this.active_page.active = true;
|
this.active_page.active = true;
|
||||||
this.load(this.active_page);
|
this.activate_linked_nodes(this.active_page, true);
|
||||||
|
|
||||||
this.events.emit("page", this.active_page.title);
|
this.events.emit("page", this.active_page.title);
|
||||||
|
|
||||||
|
this.net.update_nodes();
|
||||||
|
this.net.update_forces();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set_show_history (value) {
|
||||||
|
console.log("wikimap.show_history", value);
|
||||||
|
if (this.show_history !== value) {
|
||||||
|
this.show_history = value;
|
||||||
|
if (this.show_history) {
|
||||||
|
let graph = {};
|
||||||
|
graph.nodes = this.nodes;
|
||||||
|
graph.links = this.links.slice();
|
||||||
|
for (var key in this.historylinks) {
|
||||||
|
graph.links.push(this.historylinks[key])
|
||||||
|
}
|
||||||
|
this.net.update_graph(graph);
|
||||||
|
} else {
|
||||||
|
let graph = {};
|
||||||
|
graph.nodes = this.nodes;
|
||||||
|
graph.links = this.links;
|
||||||
|
this.net.update_graph(graph);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
async load (page) {
|
async load (page) {
|
||||||
console.log("loading", page.title);
|
console.log("loading", page.title);
|
||||||
var links = await page.get_links(),
|
var links = await page.get_links(),
|
||||||
@@ -200,6 +273,7 @@ export class Map {
|
|||||||
// console.log("GOT DATA", titles);
|
// console.log("GOT DATA", titles);
|
||||||
// return titles;
|
// return titles;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,284 +0,0 @@
|
|||||||
import { event, select, selectAll} from 'd3-selection';
|
|
||||||
import { values, set, map } from 'd3-collection';
|
|
||||||
import { drag } from 'd3-drag';
|
|
||||||
import { zoom } from 'd3-zoom';
|
|
||||||
import { forceSimulation, forceLink, forceManyBody, forceCenter, forceX, forceY, forceRadial } from 'd3-force';
|
|
||||||
import { Wiki, Page } from './wiki.js';
|
|
||||||
import EventEmitter from 'eventemitter3';
|
|
||||||
import { json } from 'd3-fetch';
|
|
||||||
|
|
||||||
import { ForceNet } from './forcenet.js';
|
|
||||||
|
|
||||||
export class SimpleMap {
|
|
||||||
|
|
||||||
constructor (symbols) {
|
|
||||||
var width = 600,
|
|
||||||
height = 600;
|
|
||||||
|
|
||||||
this.events = new EventEmitter();
|
|
||||||
this.active_page = null;
|
|
||||||
// this.nodes = {};
|
|
||||||
this.symbols = symbols;
|
|
||||||
this.net = new ForceNet(symbols);
|
|
||||||
this.net.on("nodeclick", this.nodeclick.bind(this));
|
|
||||||
// this.simulation = forceSimulation()
|
|
||||||
// .velocityDecay(0.1)
|
|
||||||
// .force("link", forceLink().id(d => d.title))
|
|
||||||
// .force("charge", forceManyBody())
|
|
||||||
// .force("radial", forceRadial(180, width/2, height/2));
|
|
||||||
// // .force("center", forceCenter(width / 2, height / 2));
|
|
||||||
this.svg = null;
|
|
||||||
this.historylinks = {};
|
|
||||||
this.links = null;
|
|
||||||
this.highlight_category = null;
|
|
||||||
this.show_history = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
nodeclick (d, elt) {
|
|
||||||
console.log("nodeclick", d, elt, this);
|
|
||||||
this.set_active_node(d, elt);
|
|
||||||
}
|
|
||||||
|
|
||||||
init_svg (svg) {
|
|
||||||
this.net.init_svg(svg);
|
|
||||||
}
|
|
||||||
|
|
||||||
async load_json (source) {
|
|
||||||
var data = await json(source);
|
|
||||||
// console.log("got data!", data);
|
|
||||||
// index the nodes by title, init link-arity count
|
|
||||||
var index = {};
|
|
||||||
this.nodes_by_title = index;
|
|
||||||
for (let i=0, l=data.nodes.length; i<l; i++) {
|
|
||||||
let node = data.nodes[i];
|
|
||||||
node.count = 0;
|
|
||||||
index[node.title] = node;
|
|
||||||
}
|
|
||||||
this.nodes = data.nodes;
|
|
||||||
|
|
||||||
var use_links = [];
|
|
||||||
data.links = data.links.forEach(x => {
|
|
||||||
var source = index[x.source],
|
|
||||||
target = index[x.target];
|
|
||||||
if (source === undefined) {
|
|
||||||
console.log("bad source", x.source);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (target === undefined) {
|
|
||||||
console.log("bad target", x.target);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
source.count += 1;
|
|
||||||
target.count += 1;
|
|
||||||
use_links.push({ source: source, target: target });
|
|
||||||
});
|
|
||||||
data.links = use_links;
|
|
||||||
this.links = data.links;
|
|
||||||
// console.log("data", data);
|
|
||||||
// calculate the node sizes (link arity)
|
|
||||||
this.net.update_graph(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
get_symbol_image_path (cname) {
|
|
||||||
var symbol = this.symbols[cname];
|
|
||||||
if (symbol) {
|
|
||||||
let hpos = symbol.indexOf("#"),
|
|
||||||
rest = symbol.substr(hpos+1);
|
|
||||||
rest = rest.replace(/'/g, '');
|
|
||||||
return "img/"+rest+".png";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
async load_cats (src, elt) {
|
|
||||||
var data = await json(src);
|
|
||||||
|
|
||||||
console.log("indexing categories by title");
|
|
||||||
var cats_by_title = {};
|
|
||||||
for (let i=0, l=data.length; i<l; i++) {
|
|
||||||
let cat = data[i];
|
|
||||||
cats_by_title[cat.title] = cat;
|
|
||||||
cat.pages = [];
|
|
||||||
cat.tcount = 0;
|
|
||||||
}
|
|
||||||
// index categories
|
|
||||||
console.log("indexing categories");
|
|
||||||
for (let key in this.nodes_by_title) {
|
|
||||||
let node = this.nodes_by_title[key];
|
|
||||||
// console.log("key", key, node.cats);
|
|
||||||
for (let j=0, jl=node.cats.length; j<jl; j++) {
|
|
||||||
let cname = node.cats[j],
|
|
||||||
cat = cats_by_title[cname];
|
|
||||||
if (cat) {
|
|
||||||
// increment the category + parents
|
|
||||||
cat.pages.push(node);
|
|
||||||
cat.tcount += 1
|
|
||||||
while (cat.parent) {
|
|
||||||
cat = cats_by_title[cat.parent];
|
|
||||||
cat.tcount += 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log("Warning, unknown category", cname);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log("pre filter", data.length);
|
|
||||||
data = data.filter(d => d.tcount > 0)
|
|
||||||
console.log("post filter", data.length);
|
|
||||||
console.log("load_cats.data", data, elt);
|
|
||||||
var cat = select(elt)
|
|
||||||
.selectAll("div.cat")
|
|
||||||
.data(data)
|
|
||||||
.enter()
|
|
||||||
.append("div")
|
|
||||||
.attr("class", "cat");
|
|
||||||
cat.classed("icon", d => this.get_symbol_image_path(d.title));
|
|
||||||
cat.append("span").attr("class", "icon").filter(d=> this.get_symbol_image_path(d.title)).style("background-image", d => "url("+this.get_symbol_image_path(d.title)+")");
|
|
||||||
cat.append("span").attr("class", "spacing").html(d => {
|
|
||||||
var d = d.depth,
|
|
||||||
ret = "";
|
|
||||||
while(d) {
|
|
||||||
ret += " ";
|
|
||||||
d-=1;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
});
|
|
||||||
cat.append("a").attr("class", "label").html(d => d.title).attr("href", "#").on("click", d => {
|
|
||||||
event.preventDefault();
|
|
||||||
this.category_click(d);
|
|
||||||
})
|
|
||||||
cat.append("span").attr("class", "count").html(d => d.tcount)
|
|
||||||
}
|
|
||||||
|
|
||||||
category_click (d) {
|
|
||||||
console.log("category click", d);
|
|
||||||
if (this.highlight_category) {
|
|
||||||
// cleanup old pages
|
|
||||||
this.highlight_category.pages.forEach(d => d.highlight = false);
|
|
||||||
}
|
|
||||||
this.highlight_category = d;
|
|
||||||
this.highlight_category.pages.forEach(d => d.highlight = true);
|
|
||||||
this.net.update_nodes();
|
|
||||||
// set highlight category...
|
|
||||||
// all nodes with this category get .highlight = true
|
|
||||||
// make a category index ?!
|
|
||||||
}
|
|
||||||
|
|
||||||
on (message, callback, context) {
|
|
||||||
this.events.on(message, callback, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* OLD STYLE with node.all_links
|
|
||||||
walk (node, links) {
|
|
||||||
var links_seen = {};
|
|
||||||
// var node = this.ensure_node(nodename);
|
|
||||||
node.all_links.forEach(x => {
|
|
||||||
var link_key = this.link_key(node.title, x.title);
|
|
||||||
if (!links_seen[link_key]) {
|
|
||||||
links.push({source: node, target: x});
|
|
||||||
links_seen[link_key] = true;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
set_active_title (title) {
|
|
||||||
this.set_active_node(title);
|
|
||||||
}
|
|
||||||
|
|
||||||
activate_linked_nodes (page, active) {
|
|
||||||
// deactivate linked links/nodes
|
|
||||||
for (let i=0, l=this.links.length; i<l; i++) {
|
|
||||||
let link = this.links[i];
|
|
||||||
if (link.source == page || link.target == page) {
|
|
||||||
link.active2 = active;
|
|
||||||
link.source.active2 = active;
|
|
||||||
link.target.active2 = active;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async set_active_node (page) {
|
|
||||||
if (typeof(page) === "string") {
|
|
||||||
let pagename = page;
|
|
||||||
page = this.nodes_by_title[page];
|
|
||||||
|
|
||||||
if (!page) {
|
|
||||||
console.log("wikimap.set_active_node: page not found", pagename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (page === this.active_page) {
|
|
||||||
// console.log("page is already the active page", page, this.active_page);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (this.active_page) {
|
|
||||||
this.active_page.active = false;
|
|
||||||
// deactivate linked links/nodes
|
|
||||||
this.activate_linked_nodes(this.active_page, false);
|
|
||||||
// ENSURE HISTORY LINK TO PREVIOUS NODE AND CURRENT
|
|
||||||
var lkey = this.net.link_key(this.active_page.title, page.title),
|
|
||||||
source = (this.active_page.title < page.title) ? this.active_page : page,
|
|
||||||
target = (this.active_page.title < page.title) ? page : this.active_page;
|
|
||||||
this.historylinks[lkey] = {source: source, target: target, type:"history"};
|
|
||||||
}
|
|
||||||
|
|
||||||
this.active_page = page;
|
|
||||||
this.active_page.active = true;
|
|
||||||
this.activate_linked_nodes(this.active_page, true);
|
|
||||||
|
|
||||||
this.events.emit("page", this.active_page.title);
|
|
||||||
|
|
||||||
this.net.update_nodes();
|
|
||||||
this.net.update_forces();
|
|
||||||
}
|
|
||||||
|
|
||||||
set_show_history (value) {
|
|
||||||
console.log("wikimapsimple.show_history", value);
|
|
||||||
if (this.show_history !== value) {
|
|
||||||
this.show_history = value;
|
|
||||||
if (this.show_history) {
|
|
||||||
let graph = {};
|
|
||||||
graph.nodes = this.nodes;
|
|
||||||
graph.links = this.links.slice();
|
|
||||||
for (var key in this.historylinks) {
|
|
||||||
graph.links.push(this.historylinks[key])
|
|
||||||
}
|
|
||||||
this.net.update_graph(graph);
|
|
||||||
} else {
|
|
||||||
let graph = {};
|
|
||||||
graph.nodes = this.nodes;
|
|
||||||
graph.links = this.links;
|
|
||||||
this.net.update_graph(graph);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
async load (page) {
|
|
||||||
console.log("loading", page.title);
|
|
||||||
var links = await page.get_links(),
|
|
||||||
backlinks = await page.get_linkshere(),
|
|
||||||
alllinks = this.wiki.union(links, backlinks);
|
|
||||||
|
|
||||||
page.all_links = alllinks;
|
|
||||||
// console.log("alllinks", alllinks);
|
|
||||||
var graph = {};
|
|
||||||
|
|
||||||
graph.nodes = values(this.wiki.pages_by_title);
|
|
||||||
graph.links = [];
|
|
||||||
this.walk(page, graph.links);
|
|
||||||
// activate historylinks
|
|
||||||
values(this.historylinks).forEach(x => {
|
|
||||||
graph.links.push(x);
|
|
||||||
})
|
|
||||||
// graph.links = titles.map(t => ({source: pagetitle, target: t}));
|
|
||||||
this.update_graph(graph);
|
|
||||||
// console.log("GOT DATA", titles);
|
|
||||||
// return titles;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// http://erg.activearchives.org/mw/api.php?action=query&prop=links&titles=Bienvenue_%C3%A0_l%E2%80%99erg
|
|
||||||
// http://erg.activearchives.org/w/api.php?action=query&prop=info&titles=Main%20Page
|
|
||||||
// Bienvenue_à_l’erg
|
|
||||||
// http://erg.activearchives.org/mw/index.php/Bienvenue_%C3%A0_l%E2%80%99erg
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
|
|
||||||
import { SimpleMap } from './wikimapsimple.js';
|
|
||||||
|
|
||||||
// gather ALL nodes + links from the wiki via the API
|
|
||||||
|
|
||||||
export { SimpleMap };
|
|
||||||
Reference in New Issue
Block a user