Create a gist now

Instantly share code, notes, and snippets.

displaCy.js NLP visualizer Jade/Pug mixin (to use in Node/Express, Harp, etc.)
//- Usage: +displacy({ arcs: [...], words: [...] })
//- Blog post for more info: https://explosion.ai/blog/displacy-js-nlp-visualizer
//- spaCy REST service to generate JSON markup: https://github.com/explosion/spacy-services
- var distance = 200
- var offsetX = 50
- var arrowSpacing = 20
- var arrowWidth = 10
- var arrowStroke = 2
- var wordSpacing = 50
mixin displacy(parse)
- var highestArc = 0
- var levels = parse.arcs.map(function(arc) { return arc.end - arc.start }).sort(function(a, b) { return b - a }).reverse().filter(function(item, pos, self) { return self.indexOf(item) == pos })
- var highestLevel = levels.indexOf(levels.slice(-1)[0]) + 1
- var offsetY = distance / 2 * highestLevel
- var width = offsetX + parse.words.length * distance
- var height = offsetY + 3 * wordSpacing
figure.c-displacy.o-block.u-code-regular&attributes(attributes)
svg.displacy-svg(xmlns="http://www.w3.org/2000/svg" width=width height=height viewBox="0 0 #{width} #{height}" preserveAspectRatio="xMinYMin meet")
each word, i in parse.words
text.displacy-token(y=offsetY + wordSpacing text-anchor="middle" fill="currentColor")
tspan.displacy-word(x=offsetX + i * distance )=word.text
tspan.displacy-tag(x=offsetX + i * distance dy="2em" text-anchor="middle" style="font-size: 0.75em")=word.tag
each arc, i in parse.arcs
- var level = levels.indexOf(arc.end - arc.start) + 1
- var id = "arrow" + i
- var startX = offsetX + arc.start * distance + arrowSpacing * (highestLevel - level) / 4
- var startY = offsetY
- var end = offsetX + level * distance + arc.start * distance - arrowSpacing * (highestLevel - level) / 4
- var curve = offsetY - level * distance / 2
- if(curve == 0 && levels.length > 5) curve = -distance
path.displacy-arrow(id=id d="M#{startX},#{startY} C#{startX},#{curve} #{end},#{curve} #{end},#{startY}" stroke-width=arrowStroke + "px" fill="none" stroke="currentColor" class=arc.style)
text(dy="1em")
textPath.displacy-label(xlink:href="#" + id startOffset="50%" fill="currentColor" text-anchor="middle" style="font-size: 0.75em")=arc.label
path.displacy-arrowhead(d=(arc.dir == "left" ? "M#{startX},#{startY + 2} L#{startX - arrowWidth + 2},#{startY - arrowWidth} #{startX + arrowWidth - 2},#{startY - arrowWidth}" : "M#{end},#{startY + 2} L#{end + arrowWidth - 2},#{startY - arrowWidth} #{end - arrowWidth + 2},#{startY - arrowWidth}") fill="currentColor" class=arc.style)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment