|
sequence = 'Sul tagliere gli agli taglia, non tagliare la tovaglia: la tovaglia non è aglio e tagliarla è un grave sbaglio' |
|
|
|
matches = [{'length': 8, 'source': 46, 'subsequence': 'tovaglia', 'target': 59}, |
|
{'length': 7, 'source': 34, 'subsequence': 'tagliar', 'target': 82}, |
|
{'length': 6, 'source': 22, 'subsequence': 'taglia', 'target': 34}, |
|
{'length': 5, 'source': 74, 'subsequence': 'aglio', 'target': 105}, |
|
{'length': 5, 'source': 4, 'subsequence': 'tagli', 'target': 22}, |
|
{'length': 5, 'source': 35, 'subsequence': 'aglia', 'target': 49}, |
|
{'length': 5, 'source': 62, 'subsequence': 'aglia', 'target': 83}, |
|
{'length': 4, 'source': 5, 'subsequence': 'agli', 'target': 17}, |
|
{'length': 4, 'source': 17, 'subsequence': 'agli', 'target': 23}, |
|
{'length': 4, 'source': 62, 'subsequence': 'agli', 'target': 74}, |
|
{'length': 4, 'source': 74, 'subsequence': 'agli', 'target': 83}, |
|
{'length': 4, 'source': 83, 'subsequence': 'agli', 'target': 105}, |
|
{'length': 3, 'source': 30, 'subsequence': 'non', 'target': 68}, |
|
{'length': 3, 'source': 6, 'subsequence': 'gli', 'target': 13}, |
|
{'length': 3, 'source': 13, 'subsequence': 'gli', 'target': 18}, |
|
{'length': 2, 'source': 43, 'subsequence': 'la', 'target': 56}, |
|
{'length': 2, 'source': 56, 'subsequence': 'la', 'target': 89}, |
|
{'length': 2, 'source': 10, 'subsequence': 're', 'target': 40}] |
|
|
|
svg = d3.select('svg') |
|
width = svg.node().getBoundingClientRect().width |
|
height = svg.node().getBoundingClientRect().height |
|
|
|
# translate the viewBox to have (0,0) at the center of the vis |
|
svg |
|
.attr |
|
viewBox: "#{-width/2} #{-height+60} #{width} #{height}" |
|
|
|
width -= 60 |
|
|
|
x = d3.scale.ordinal() |
|
.domain([0..sequence.length]) |
|
.rangeBands([-width/2,width/2]) |
|
|
|
characters = svg.selectAll('.character') |
|
.data(sequence) |
|
|
|
characters.enter().append('text') |
|
.text (d) -> d |
|
.attr |
|
class: 'character' |
|
x: (d,i) -> x(i) + x.rangeBand()/2 |
|
dy: '1em' |
|
|
|
arcs = svg.selectAll('.arc') |
|
.data(matches.filter (m) -> m.length > 1) |
|
|
|
enter_arcs = arcs.enter().append('path') |
|
.attr |
|
class: 'arc' |
|
d: (match) -> |
|
start_left = x(match.source) |
|
start_right = x(match.source + match.length) |
|
end_left = x(match.target) |
|
end_right = x(match.target + match.length) |
|
big_radius = (end_right-start_left)/2 |
|
small_radius = (end_left-start_right)/2 |
|
return "M#{start_left} 0 A#{big_radius} #{big_radius} 0 1 1 #{end_right} 0 L#{end_left} 0 A#{small_radius} #{small_radius} 0 1 0 #{start_right} 0 z" |
|
|
|
# subsequence selection |
|
subsequence = svg.append 'text' |
|
.attr |
|
class: 'subsequence' |
|
y: -350 |
|
|
|
enter_arcs.on 'click', (d1) -> |
|
subsequence |
|
.text d1.subsequence |
|
|
|
svg.selectAll('.arc') |
|
.classed 'selected', (d2) -> d1.subsequence is d2.subsequence |
|
.classed 'dimmed', (d2) -> d1.subsequence isnt d2.subsequence |
|
|
|
d3.event.stopPropagation() |
|
|
|
svg.on 'click', () -> |
|
subsequence |
|
.text '' |
|
|
|
svg.selectAll('.arc') |
|
.classed 'selected', false |
|
.classed 'dimmed', false |
|
|