octopus.js
var svg = d3.select('body').append('svg')
var skills = [
['D3', 7, 2, 1],
['Angular', 6, 2, 0],
['React', 0, 2, 4],
['', 0, 0, 0],
['Оптимизация производительности', 1, 2, 3],
['Архитектура ПО', 2, 1, 2],
['', 0, 0, 0],
['Подготовка материалов', 2, 1, 0],
['Обучение', 4, 1, 0],
['', 0, 0, 0],
['Формирование ожиданий', 3, 1, 1],
['Переговоры', 1, 1, 2],
['Управление временем', 2, 1, 2],
['Делегирование', 1, 1, 2],
]
var count = skills.length
var skillHeight = 24
var gapHeight = 3
var r = (count * (skillHeight + gapHeight) - gapHeight) / 2
var skillWidth = 30
svg
.attr('width', '100%')
.style('left', '50%')
.attr('height', r * 2 + 2)
svg.append('circle')
.attr('r', r - 1)
.attr('cx', r + 1)
.attr('cy', r + 1)
.attr('stroke', 'black')
.attr('fill', 'white')
svg.append('circle')
.attr('r', 15)
.attr('cx', 70)
.attr('cy', 80)
.attr('stroke', 'black')
.attr('fill', 'white')
.classed('eye', true)
svg.append('rect')
.attr('x', r)
.attr('width', r + 2)
.attr('height', r * 2)
.attr('fill', 'white')
var g = svg.append('g')
for(var i = 0; i < 3; i++)
g
.selectAll('rect.year' + (2014 + i))
.data(skills)
.enter()
.append('rect')
.classed('year' + (2014 + i), true)
.attr('x', function (d) { return r + d3.sum(d3.range(0, i).map(function (s) { return d[1 + s] })) * skillWidth })
.attr('y', function (d, i) { return i * (skillHeight + gapHeight) + 1})
.attr('height', skillHeight)
.attr('width', function (d) { return d[1 + i] * skillWidth })
.attr('fill', 'white')
g
.selectAll('text')
.data(skills)
.enter()
.append('text')
.text(function (d) { return d[0]})
.attr('x', function (d) { return d3.sum(d3.range(0, 3).map(function (s) { return d[1 + s]})) * skillWidth })
.attr('dy', 18)
.attr('dx', 6 + r)
.attr('y', function (d, i) { return i * (skillHeight + gapHeight) + 1})