Skip to content

Instantly share code, notes, and snippets.

@nitriques
Last active December 17, 2015 22:29
Show Gist options
  • Save nitriques/5682356 to your computer and use it in GitHub Desktop.
Save nitriques/5682356 to your computer and use it in GitHub Desktop.
How facts are created with Jess: see it http://bl.ocks.org/nitriques/5682356
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link href="http://fonts.googleapis.com/css?family=Ubuntu" rel="stylesheet" type="text/css">
<style>
body {
font-family: 'Ubuntu', Helvetica, Arial, sans-serif;
width: 960px;
height: 500px;
position: relative;
font-size: 14px;
}
h3 {
margin: 6px 0 3px 0;
}
#root {
position: relative;
}
#output {
position: absolute;
top: 180px;
left: 90px;
width: 240px;
font-size: 16px;
}
svg * {
-webkit-transition: all 350ms ease-in;
-moz-transition: all 350ms ease-in;
-ms-transition: all 350ms ease-in;
-o-transition: all 350ms ease-in;
transition: all 350ms ease-in;
}
.node {
stroke-width: 0px;
}
.node.selected {
stroke-width: 14px;
}
.label {
display: none;
text-shadow: 0 0 1px #fff, 0 0 2px #fff, 0 0 3px #fff, 0 0 4px #fff, 0 0 5px #fff;
font-size: 16px;
}
.label.selected {
display:block;
}
.level {
font-size: 13px;
}
.link {
stroke-width: 2px;
}
.link.selected {
stroke-width: 6px;
}
</style>
</head>
<body>
<div id="root">
<div id="output"></div>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
(function ($, d3, undefined) {
"use strict";
var
WIDTH = 960,
HEIGHT = 500,
COLORS = d3.scale.category20b(),
NODE_SIZE = 10,
NODE_SIZE_HALF = NODE_SIZE/2,
NODE_SPACING = 30,
TRANSLATE = 'translate(-' + NODE_SIZE_HALF + ',-' + NODE_SIZE_HALF + ')',
TRANSLATE_TEXT = 'translate(-' + NODE_SIZE + ',-' + NODE_SIZE + ')',
facts = [
{id: 0, level:0, text:'seen ?hair at ?time'},
{id: 1, level:0, text:'is ?name ?hair'},
{id: 2, level:0, text:'visit ?dir ?mood'},
{id: 3, level:0, text:'direction ?shop ?dir'},
{id: 4, level:0, text:'sold ?os at ?time'},
{id: 5, level:0, text:'run ?product ?os'},
{id: 6, level:0, text:'has ?head ?mood'},
{id: 7, level:0, text:'wears ?name ?head'},
{id: 8, level:0, text:'goto ?loc ?transport'},
{id: 9, level:0, text:'location ?shop ?loc'},
{id:10, level:0, text:'bought ?os ?job'},
{id:11, level:0, text:'transact ?company ?job'},
{id:12, level:0, text:'company ?payment-type ?company'},
{id:13, level:0, text:'rank ?name ?rank'},
{id:14, level:0, text:'requires ?transport ?rank'},
{id:15, level:0, text:'sex ?name ?sex'},
{id:16, level:0, text:'job-sex ?job ?sex'},
{id:17, level:0, text:'sell ?shop ?os'},
{id:18, level:0, text:'use ?dir ?company'},
{id: 100, level:1, text:'seen-l0 ?name at ?time'},
{id: 101, level:1, text:'visit-l0 ?shop ?mood'},
{id: 102, level:1, text:'sold-l0 ?product at ?time'},
{id: 103, level:1, text:'is-l0 ?name ?mood'},
{id: 104, level:1, text:'goto-l0 ?shop ?transport'},
{id: 105, level:1, text:'bought-l0 ?product ?job'},
{id: 106, level:1, text:'transact-l0 ?payment-type ?job'},
{id: 107, level:1, text:'use-l0 ?name ?transport'},
{id: 108, level:1, text:'job-l0 ?name ?job'},
{id: 109, level:1, text:'sell-l0 ?shop ?product'},
{id: 110, level:1, text:'use-l0 ?shop ?company'},
{id: 200, level:2, text:'visit-l1 ?name ?shop'},
{id: 201, level:2, text:'bought-l1 ?name ?product'},
{id: 202, level:2, text:'via-l1 ?payment-type ?product'},
{id: 203, level:2, text:'transact-l1 ?shop ?payment-type'},
{id: 204, level:2, text:'uses-l1 ?name ?payment-type'},
{id: 300, level:3, text:'sold-l2 ?shop ?product ?payment-type'},
{id: 301, level:3, text:'bought-l2 ?name ?product ?payment-type'},
{id: 302, level:3, text:'seen-l2 ?name ?product ?shop'},
{id: 303, level:3, text:'transact-l2 ?name ?payment-type ?shop'},
{id: 400, level:4, text:'FOUND ?name ?product ?payment-type ?shop'}
],
relationships = [
{from:0,to:100},{from:1,to:100},
{from:2,to:101},{from:3,to:101},
{from:4,to:102},{from:5,to:102},
{from:6,to:103},{from:7,to:103},
{from:8,to:104},{from:9,to:104},
{from:10,to:105},{from:5,to:105},
{from:11,to:106},{from:12,to:106},
{from:13,to:107},{from:14,to:107},
{from:15,to:108},{from:16,to:108},
{from: 5,to:109},{from:17,to:109},
{from: 3,to:110},{from:18,to:110},
{from:101,to:200},{from:103,to:200},
{from:100,to:201},{from:102,to:201},
{from:105,to:202},{from:106,to:202},
{from:104,to:200},{from:107,to:200},
{from:106,to:204},{from:108,to:204},
{from: 13,to:203},{from:110,to:203},
{from:202,to:300},{from:109,to:300},{from:203,to:300},
{from:202,to:301},{from:201,to:301},{from:204,to:301},
{from:200,to:302},{from:201,to:302},{from:109,to:302},
{from:200,to:303},{from:203,to:303},{from:204,to:303},
{from:300,to:400},{from:301,to:400},{from:302,to:400},{from:303,to:400}
],
depths = [
'KB','Level 0','Level 1','Level 2','Result (level 3)'
],
output = $('#output'),
_levelCount = function (level) {
var res = 0;
$.each(facts, function (index, fact) {
if (fact.level === level) {
res++;
}
});
return res;
},
_getIndex = function (d) {
return d.id - (d.level * 100);
},
_x = function (d, i) {
var
one = NODE_SIZE + NODE_SPACING,
offset = _getIndex(d) * one,
levelCount = _levelCount(d.level),
spacing = Math.max(0, ( WIDTH - (one * (levelCount+1)) ) / 2);
return offset + spacing;
},
_y = function (d, i) {
return ((d.level !== undefined ? d.level : i) * 110) + NODE_SIZE * 3;
},
_findById = function (key) {
var res = null;
$.each(facts, function (index, fact) {
if (fact.id === key) {
res = fact;
return false;
}
});
return res;
},
_indexById = function (key) {
var res = -1;
$.each(facts, function (index, fact) {
if (fact.id === key) {
res = index;
return false;
}
});
return res;
},
_selectText = function (select) {
return function selectText(d, i) {
var
labels = d3.selectAll('.label'),
nodes = d3.selectAll('.node'),
links = d3.selectAll('.link'),
parents = [],
filterCurrent = function (ld, li) {
return d.id === ld.id;
},
filterParent = function (ld, li) {
return !!~$.inArray(ld.id, parents);
},
filterLinks = function (ld, li) {
return d.id === ld.to;
};
if (d.id === undefined) {
return;
}
// find parents id
$.each(relationships, function (index, rel) {
if (rel.to === d.id) {
parents.push(rel.from);
}
});
// select current
d3.select(this).classed('selected', select);
// find current and select
labels.filter(filterCurrent).classed('selected', select);
// show parent
nodes.filter(filterParent).classed('selected', select);
// select link
links.filter(filterLinks).classed('selected', select);
// output
if (!select) {
output.empty();
} else {
if (!d.level) {
output.append('<h3>Known from KB</h3>');
} else {
output.append('<h3>Possible parents:</h3>');
$.each(parents, function (index, p) {
var fact = _findById(p),
$fact = $('<div />').text((index+1) + '. ' + fact.text);
output.append($fact);
});
output.append('<h3>Selected child:</h3>');
}
output.append($('<div />').text(d.text));
}
};
},
init = function () {
var svg = d3.select('#root')
.append("svg:svg")
.attr("width", WIDTH)
.attr("height", HEIGHT)
.attr('id','graph'),
vis = svg.append('g').attr('id', 'vis'),
levels = vis.selectAll('.level').data(depths),
links = vis.selectAll('.link').data(relationships),
nodes = vis.selectAll('.node').data(facts),
labels = vis.selectAll('.label').data(facts);
levels.enter()
.append('text')
.attr('class','level')
.text(function (d) { return d; });
links.enter().append('line')
.attr('class','link')
.attr('stroke', function (d, i) { return COLORS(_indexById(d.to)); });
nodes.enter().append('circle')
.attr('class','node')
.attr('r', NODE_SIZE)
.attr('fill', function (d, i) { return COLORS(i); })
.attr('stroke', function (d, i) { return COLORS(i); })
.on('mouseenter', _selectText(true))
.on('mouseleave', _selectText(false));
labels.enter()
.append('text')
.attr('class','label')
.attr('transform', TRANSLATE_TEXT)
.text(function (d) { return d.text; });
levels
.attr('x', 10)
.attr('y', function (d, i) { return _y(d, i) + NODE_SIZE/2; });
links
.attr('x1', function (d, i) { return _x(_findById(d.from), i); })
.attr('y1', function (d, i) { return _y(_findById(d.from), i); })
.attr('x2', function (d, i) { return _x(_findById(d.to), i); })
.attr('y2', function (d, i) { return _y(_findById(d.to), i); });
nodes
.attr('cx', _x)
.attr('cy', _y);
labels
.attr('x', _x)
.attr('y', _y);
};
$(init);
})(window.jQuery, window.d3);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment