Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
1a230346
Commit
1a230346
authored
Mar 29, 2017
by
Mike Greiling
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
implement burndown chart basic outline
parent
767d9a79
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
162 additions
and
0 deletions
+162
-0
app/assets/javascripts/burndown_chart/burndown_chart.js
app/assets/javascripts/burndown_chart/burndown_chart.js
+104
-0
app/assets/javascripts/burndown_chart/index.js
app/assets/javascripts/burndown_chart/index.js
+13
-0
app/assets/javascripts/burndown_chart/test_data.json
app/assets/javascripts/burndown_chart/test_data.json
+17
-0
app/assets/stylesheets/pages/milestone.scss
app/assets/stylesheets/pages/milestone.scss
+25
-0
app/views/shared/milestones/_burndown.html.haml
app/views/shared/milestones/_burndown.html.haml
+3
-0
No files found.
app/assets/javascripts/burndown_chart/burndown_chart.js
0 → 100644
View file @
1a230346
import
d3
from
'
d3
'
;
const
margin
=
{
top
:
5
,
right
:
15
,
bottom
:
30
,
left
:
40
};
const
parseDate
=
d3
.
time
.
format
(
'
%Y-%m-%d
'
).
parse
;
export
default
class
BurndownChart
{
constructor
({
container
,
startDate
,
dueDate
})
{
this
.
canvas
=
d3
.
select
(
container
).
append
(
'
svg
'
)
.
attr
(
'
height
'
,
'
100%
'
)
.
attr
(
'
width
'
,
'
100%
'
);
// create svg nodes
this
.
chartGroup
=
this
.
canvas
.
append
(
'
g
'
).
attr
(
'
class
'
,
'
chart
'
);
this
.
xAxisGroup
=
this
.
chartGroup
.
append
(
'
g
'
).
attr
(
'
class
'
,
'
x axis
'
);
this
.
yAxisGroup
=
this
.
chartGroup
.
append
(
'
g
'
).
attr
(
'
class
'
,
'
y axis
'
);
// parse start and due dates
this
.
startDate
=
parseDate
(
startDate
);
this
.
dueDate
=
parseDate
(
dueDate
);
// get width and height
const
dimensions
=
this
.
canvas
.
node
().
getBoundingClientRect
();
this
.
width
=
dimensions
.
width
;
this
.
height
=
dimensions
.
height
;
this
.
chartWidth
=
this
.
width
-
(
margin
.
left
+
margin
.
right
);
this
.
chartHeight
=
this
.
height
-
(
margin
.
top
+
margin
.
bottom
);
// set default scale domains
this
.
xMax
=
this
.
dueDate
;
this
.
yMax
=
1
;
// create scales
this
.
xScale
=
d3
.
time
.
scale
()
.
range
([
0
,
this
.
chartWidth
])
.
domain
([
this
.
startDate
,
this
.
xMax
]);
this
.
yScale
=
d3
.
scale
.
linear
()
.
range
([
this
.
chartHeight
,
0
])
.
domain
([
0
,
this
.
yMax
]);
// create axes
this
.
xAxis
=
d3
.
svg
.
axis
()
.
scale
(
this
.
xScale
)
.
orient
(
'
bottom
'
)
.
tickFormat
(
d3
.
time
.
format
(
'
%b %-d
'
))
.
tickPadding
(
6
)
.
tickSize
(
4
,
0
);
this
.
yAxis
=
d3
.
svg
.
axis
()
.
scale
(
this
.
yScale
)
.
orient
(
'
left
'
)
.
tickPadding
(
6
)
.
tickSize
(
4
,
0
);
// render the chart
this
.
render
();
}
// set data and force re-render
setData
(
data
)
{
this
.
data
=
data
.
map
(
datum
=>
({
date
:
parseDate
(
datum
[
0
]),
value
:
parseInt
(
datum
[
1
],
10
),
})).
sort
((
a
,
b
)
=>
(
a
.
date
-
b
.
date
));
// adjust axis domain to correspond with data
this
.
xMax
=
Math
.
max
(
d3
.
max
(
this
.
data
,
d
=>
d
.
date
),
this
.
dueDate
);
this
.
yMax
=
Math
.
max
(
d3
.
max
(
this
.
data
,
d
=>
d
.
value
),
1
);
this
.
xScale
.
domain
([
this
.
startDate
,
this
.
xMax
]);
this
.
yScale
.
domain
([
0
,
this
.
yMax
]);
this
.
render
();
}
// reset width and height to match the svg element, then re-render if necessary
resize
()
{
const
dimensions
=
this
.
canvas
.
node
().
getBoundingClientRect
();
if
(
this
.
width
!==
dimensions
.
width
||
this
.
height
!==
dimensions
.
height
)
{
this
.
width
=
dimensions
.
width
;
this
.
height
=
dimensions
.
height
;
// adjust axis range to correspond with chart size
this
.
chartWidth
=
this
.
width
-
(
margin
.
left
+
margin
.
right
);
this
.
chartHeight
=
this
.
height
-
(
margin
.
top
+
margin
.
bottom
);
this
.
xScale
.
range
([
0
,
this
.
chartWidth
]);
this
.
yScale
.
range
([
this
.
chartHeight
,
0
]);
this
.
render
();
}
}
render
()
{
this
.
xAxis
.
ticks
(
Math
.
floor
(
this
.
chartWidth
/
120
));
this
.
yAxis
.
ticks
(
Math
.
min
(
Math
.
floor
(
this
.
chartHeight
/
60
),
this
.
yMax
));
this
.
chartGroup
.
attr
(
'
transform
'
,
`translate(
${
margin
.
left
}
,
${
margin
.
top
}
)`
);
this
.
xAxisGroup
.
attr
(
'
transform
'
,
`translate(0,
${
this
.
chartHeight
}
)`
);
this
.
xAxisGroup
.
call
(
this
.
xAxis
);
this
.
yAxisGroup
.
call
(
this
.
yAxis
);
}
}
app/assets/javascripts/burndown_chart/index.js
View file @
1a230346
import
Cookies
from
'
js-cookie
'
;
import
BurndownChart
from
'
./burndown_chart
'
;
import
testData
from
'
./test_data.json
'
;
$
(()
=>
{
// handle hint dismissal
const
hint
=
$
(
'
.burndown-hint
'
);
hint
.
on
(
'
click
'
,
'
.dismiss-icon
'
,
()
=>
{
hint
.
hide
();
Cookies
.
set
(
'
hide_burndown_message
'
,
'
true
'
);
});
// render chart
const
chart
=
new
BurndownChart
({
container
:
'
.burndown-chart
'
,
startDate
:
'
2017-03-01
'
,
dueDate
:
'
2017-03-31
'
,
});
chart
.
setData
(
testData
);
window
.
addEventListener
(
'
resize
'
,
()
=>
chart
.
resize
());
});
app/assets/javascripts/burndown_chart/test_data.json
0 → 100644
View file @
1a230346
[
[
"2017-03-01"
,
"54"
],
[
"2017-03-02"
,
"52"
],
[
"2017-03-03"
,
"51"
],
[
"2017-03-04"
,
"47"
],
[
"2017-03-05"
,
"48"
],
[
"2017-03-06"
,
"44"
],
[
"2017-03-07"
,
"41"
],
[
"2017-03-08"
,
"35"
],
[
"2017-03-09"
,
"32"
],
[
"2017-03-10"
,
"32"
],
[
"2017-03-11"
,
"31"
],
[
"2017-03-12"
,
"29"
],
[
"2017-03-13"
,
"26"
],
[
"2017-03-14"
,
"23"
],
[
"2017-03-15"
,
"20"
]
]
app/assets/stylesheets/pages/milestone.scss
View file @
1a230346
...
...
@@ -245,3 +245,28 @@
}
}
}
$burndown-chart-axis-color
:
#aaa
;
.burndown-chart
{
width
:
100%
;
height
:
400px
;
margin-top
:
30px
;
@media
(
max-width
:
$screen-sm-max
)
{
height
:
320px
;
}
@media
(
max-width
:
$screen-xs-max
)
{
height
:
220px
;
}
.axis
{
line
,
path
{
fill
:
none
;
stroke
:
$burndown-chart-axis-color
;
shape-rendering
:
crispEdges
;
}
}
}
app/views/shared/milestones/_burndown.html.haml
View file @
1a230346
...
...
@@ -20,3 +20,6 @@
this milestone and the chart will appear here, always up-to-date.
=
link_to
"Add start and due date"
,
edit_namespace_project_milestone_path
(
project
.
namespace
,
project
,
milestone
),
class:
'btn'
-
if
can_generate_chart
.burndown-chart
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment