Add custom rendering of milestone tasks

If a task is a milestone, the rect shape will be square in the center of
the original width of the rectangular calculated if it weren't a
milestone. The placement of the label text is adjusted accordingly.
Both the rect and the text get a 'milestone' and 'milestoneText' class
accordingly.
The scss rotates the square and scales it a bit down, so that it's a
diamond, which appears to be the defacto standard for milestone icons.
The label text is put in italics.
The rotational transform is done in the scss, so that it's easy for
users to create their own milestone icon-style.
This commit is contained in:
Gijs van Dam 2019-02-01 12:34:55 +08:00
parent a3eef7298e
commit 48f8c3f85a
2 changed files with 48 additions and 11 deletions

View File

@ -98,6 +98,7 @@ export const draw = function (text, id) {
}
function drawRects (theArray, theGap, theTopPad, theSidePad, theBarHeight, theColorScale, w, h) {
//draw background rects covering the entire width of the graph, these form the section rows.
svg.append('g')
.selectAll('rect')
.data(theArray)
@ -120,6 +121,7 @@ export const draw = function (text, id) {
return 'section section0'
})
//draw the rects representing the tasks
const rectangles = svg.append('g')
.selectAll('rect')
.data(theArray)
@ -129,17 +131,26 @@ export const draw = function (text, id) {
.attr('rx', 3)
.attr('ry', 3)
.attr('x', function (d) {
if (d.milestone) {
return timeScale(d.startTime) + theSidePad + (0.5 * (timeScale(d.endTime) - timeScale(d.startTime))) - (0.5* theBarHeight)
}
return timeScale(d.startTime) + theSidePad
})
.attr('y', function (d, i) {
return i * theGap + theTopPad
})
.attr('width', function (d) {
if (d.milestone) {
return theBarHeight
}
return (timeScale(d.endTime) - timeScale(d.startTime))
})
.attr('height', theBarHeight)
.attr('transform-origin', function(d, i) {
return (timeScale(d.startTime) + theSidePad + 0.5 * (timeScale(d.endTime) - timeScale(d.startTime))).toString() + 'px ' + (i * theGap + theTopPad + 0.5* theBarHeight).toString() + 'px'
} )
.attr('class', function (d) {
const res = 'task '
const res = 'task'
let secNum = 0
for (let i = 0; i < categories.length; i++) {
@ -148,37 +159,49 @@ export const draw = function (text, id) {
}
}
let milestone = ''
if (d.milestone) {
milestone = ' milestone'
}
if (d.active) {
if (d.crit) {
return res + ' activeCrit' + secNum
return res + milestone + ' activeCrit' + secNum
} else {
return res + ' active' + secNum
return res + milestone + ' active' + secNum
}
}
if (d.done) {
if (d.crit) {
return res + ' doneCrit' + secNum
return res + milestone + ' doneCrit' + secNum
} else {
return res + ' done' + secNum
return res + milestone + ' done' + secNum
}
}
if (d.crit) {
return res + ' crit' + secNum
return res + milestone + ' crit' + secNum
}
return res + ' task' + secNum
return res + milestone + ' task' + secNum
})
//Append task labels
rectangles.append('text')
.text(function (d) {
return d.task
})
.attr('font-size', conf.fontSize)
.attr('x', function (d) {
const startX = timeScale(d.startTime)
const endX = timeScale(d.endTime)
let startX = timeScale(d.startTime)
let endX = timeScale(d.endTime)
if (d.milestone) {
startX += (0.5 * (timeScale(d.endTime) - timeScale(d.startTime))) - (0.5* theBarHeight)
}
if (d.milestone) {
endX = startX + theBarHeight
}
const textWidth = this.getBBox().width
// Check id text width > width of rectangle
@ -198,7 +221,10 @@ export const draw = function (text, id) {
.attr('text-height', theBarHeight)
.attr('class', function (d) {
const startX = timeScale(d.startTime)
const endX = timeScale(d.endTime)
let endX = timeScale(d.endTime)
if (d.milestone) {
endX = startX + theBarHeight
}
const textWidth = this.getBBox().width
let secNum = 0
for (let i = 0; i < categories.length; i++) {
@ -228,6 +254,10 @@ export const draw = function (text, id) {
}
}
if (d.milestone) {
taskType += ' milestoneText'
}
// Check id text width > width of rectangle
if (textWidth > (endX - startX)) {
if (endX + textWidth + 1.5 * conf.leftPadding > w) {

View File

@ -188,6 +188,13 @@
shape-rendering: crispEdges;
}
.milestone {
transform: rotate(45deg) scale(0.8,0.8);
}
.milestoneText {
font-style: italic;
}
.doneCritText0,
.doneCritText1,
.doneCritText2,