Feature #44689 » 0001-Use-Open-Color-for-Gantt-charts.patch
| app/assets/stylesheets/gantt.css | ||
|---|---|---|
| 240 | 240 |
inset-inline-start: var(--gantt-today-start); |
| 241 | 241 |
inline-size: 10px; |
| 242 | 242 |
block-size: var(--gantt-content-height); |
| 243 |
border-inline-start: 1px dashed red;
|
|
| 243 |
border-inline-start: 1px dashed var(--oc-red-7);
|
|
| 244 | 244 |
pointer-events: none; |
| 245 | 245 |
} |
| 246 | 246 | |
| ... | ... | |
| 305 | 305 | |
| 306 | 306 |
.gantt-task-late {
|
| 307 | 307 |
block-size: 10px; |
| 308 |
background: var(--oc-red-5) url(/task_late.png);
|
|
| 309 |
border: 1px solid var(--oc-red-5);
|
|
| 308 |
background-color: var(--oc-red-4);
|
|
| 309 |
border: 1px solid var(--oc-red-4);
|
|
| 310 | 310 |
} |
| 311 | 311 | |
| 312 | 312 |
.gantt-task-done {
|
| 313 | 313 |
block-size: 10px; |
| 314 |
background: var(--oc-green-7) url(/task_done.png);
|
|
| 315 |
border: 1px solid var(--oc-green-7);
|
|
| 314 |
background-color: var(--oc-green-6);
|
|
| 315 |
border: 1px solid var(--oc-green-6);
|
|
| 316 | 316 |
} |
| 317 | 317 | |
| 318 | 318 |
.gantt-task-todo {
|
| 319 | 319 |
block-size: 10px; |
| 320 |
background: var(--oc-gray-5) url(/task_todo.png);
|
|
| 320 |
background-color: var(--oc-gray-5);
|
|
| 321 | 321 |
border: 1px solid var(--oc-gray-5); |
| 322 | 322 |
} |
| 323 | 323 | |
| 324 | 324 |
.gantt-task-todo.gantt-task-parent {
|
| 325 |
background: var(--oc-gray-6); |
|
| 326 |
border: 1px solid var(--oc-gray-6); |
|
| 327 |
block-size: 5px; |
|
| 325 |
background-color: var(--oc-gray-6); |
|
| 326 |
border-color: var(--oc-gray-6); |
|
| 328 | 327 |
} |
| 329 | 328 | |
| 330 |
.gantt-task-late.gantt-task-parent, |
|
| 331 |
.gantt-task-done.gantt-task-parent {
|
|
| 329 |
.gantt-task-parent:is(.gantt-task-todo, .gantt-task-late, .gantt-task-done) {
|
|
| 332 | 330 |
block-size: 5px; |
| 333 | 331 |
} |
| 334 | 332 | |
| 335 |
.gantt-task.gantt-task-parent.gantt-task-marker {
|
|
| 336 |
position: absolute; |
|
| 337 |
background: url(/task_parent_end.png) no-repeat 0 0; |
|
| 333 |
.gantt-task-marker {
|
|
| 334 |
background-color: var(--oc-indigo-8); |
|
| 338 | 335 |
inline-size: 8px; |
| 339 |
block-size: 16px;
|
|
| 336 |
block-size: 8px;
|
|
| 340 | 337 |
margin-inline-start: -4px; |
| 338 |
margin-block-start: 1px; |
|
| 339 |
/* Match the filled area and flat tips of the original 8px marker. */ |
|
| 340 |
clip-path: polygon(3.5px 0, 4.5px 0, 8px 3.5px, 8px 4.5px, 4.5px 8px, 3.5px 8px, 0 4.5px, 0 3.5px); |
|
| 341 | 341 |
} |
| 342 | 342 | |
| 343 |
.gantt-row[data-gantt-row-type="version"] .gantt-task-late {
|
|
| 344 |
background: var(--oc-red-5) url(/milestone_late.png); |
|
| 345 |
border: 1px solid var(--oc-red-5); |
|
| 346 |
block-size: 4px; |
|
| 347 |
margin-block-start: 3px; |
|
| 343 |
.gantt-task-parent.gantt-task-marker {
|
|
| 344 |
background-color: var(--oc-gray-6); |
|
| 345 |
block-size: 16px; |
|
| 346 |
margin-block-start: 0; |
|
| 347 |
/* Keep the original body's size and align its top with the bar. */ |
|
| 348 |
clip-path: polygon(0 0, 100% 0, 100% 6px, 50% 9px, 0 6px); |
|
| 348 | 349 |
} |
| 349 | 350 | |
| 350 |
.gantt-row[data-gantt-row-type="version"] .gantt-task-done {
|
|
| 351 |
background: var(--oc-green-7) url(/milestone_done.png); |
|
| 352 |
border: 1px solid var(--oc-green-7); |
|
| 351 |
.gantt-row[data-gantt-row-type="version"] .gantt-task:is(.gantt-task-todo, .gantt-task-late, .gantt-task-done) {
|
|
| 353 | 352 |
block-size: 4px; |
| 354 | 353 |
margin-block-start: 3px; |
| 355 | 354 |
} |
| 356 | 355 | |
| 357 | 356 |
.gantt-row[data-gantt-row-type="version"] .gantt-task-todo {
|
| 358 |
background: var(--oc-white) url(/milestone_todo.png); |
|
| 359 |
border: 1px solid var(--oc-white); |
|
| 360 |
block-size: 4px; |
|
| 361 |
margin-block-start: 3px; |
|
| 357 |
background-color: var(--oc-gray-5); |
|
| 358 |
border-color: transparent; |
|
| 359 |
background-clip: padding-box; |
|
| 362 | 360 |
} |
| 363 | 361 | |
| 364 | 362 |
.gantt-row[data-gantt-row-type="version"] .gantt-task-marker {
|
| 365 |
background-image: url(/version_marker.png); |
|
| 366 |
background-repeat: no-repeat; |
|
| 367 |
border: 0; |
|
| 368 |
margin-inline-start: -4px; |
|
| 369 |
margin-block-start: 1px; |
|
| 363 |
background-color: var(--oc-gray-9); |
|
| 370 | 364 |
} |
| 371 | 365 | |
| 372 |
.gantt-row[data-gantt-row-type="project"] .gantt-task-late {
|
|
| 373 |
background: var(--oc-red-5) url(/milestone_late.png); |
|
| 374 |
border: 1px solid var(--oc-red-5); |
|
| 375 |
block-size: 4px; |
|
| 376 |
margin-block-start: 3px; |
|
| 377 |
} |
|
| 378 | ||
| 379 |
.gantt-row[data-gantt-row-type="project"] .gantt-task-done {
|
|
| 380 |
background: var(--oc-green-7) url(/milestone_done.png); |
|
| 381 |
border: 1px solid var(--oc-green-7); |
|
| 366 |
.gantt-row[data-gantt-row-type="project"] .gantt-task:is(.gantt-task-todo, .gantt-task-late, .gantt-task-done) {
|
|
| 382 | 367 |
block-size: 4px; |
| 383 | 368 |
margin-block-start: 3px; |
| 384 | 369 |
} |
| 385 | 370 | |
| 386 | 371 |
.gantt-row[data-gantt-row-type="project"] .gantt-task-todo {
|
| 387 |
background: var(--oc-white) url(/milestone_todo.png); |
|
| 388 |
border: 1px solid var(--oc-white); |
|
| 389 |
block-size: 4px; |
|
| 390 |
margin-block-start: 3px; |
|
| 391 |
} |
|
| 392 | ||
| 393 |
.gantt-row[data-gantt-row-type="project"] .gantt-task-marker {
|
|
| 394 |
background-image: url(/project_marker.png); |
|
| 395 |
background-repeat: no-repeat; |
|
| 396 |
border: 0; |
|
| 397 |
margin-inline-start: -4px; |
|
| 398 |
margin-block-start: 1px; |
|
| 399 |
} |
|
| 400 | ||
| 401 |
/* RTL adjustment (disabled while Gantt is forced LTR). Enable when RTL is supported. |
|
| 402 |
[dir="rtl"] .gantt-task-marker {
|
|
| 403 |
background-position: right; |
|
| 372 |
background-color: var(--oc-gray-5); |
|
| 373 |
border-color: transparent; |
|
| 374 |
background-clip: padding-box; |
|
| 404 | 375 |
} |
| 405 |
*/ |
|
| 406 | 376 | |
| 407 | 377 |
.version-behind-schedule a, |
| 408 | 378 |
.issue-behind-schedule a {
|
| lib/redmine/helpers/gantt.rb | ||
|---|---|---|
| 36 | 36 |
}, |
| 37 | 37 |
IssueRelation::TYPE_PRECEDES => {
|
| 38 | 38 |
:landscape_margin => 20, |
| 39 |
:color => '#228be6' # oc-blue-6
|
|
| 39 |
:color => '#1c7ed6' # oc-blue-7
|
|
| 40 | 40 |
} |
| 41 | 41 |
}.freeze |
| 42 | 42 | |
| ... | ... | |
| 496 | 496 |
@months.times do |
| 497 | 497 |
width = ((month_f >> 1) - month_f) * zoom |
| 498 | 498 |
gc.fill('white')
|
| 499 |
gc.stroke('grey')
|
|
| 499 |
gc.stroke('#adb5bd') # oc-gray-5
|
|
| 500 | 500 |
gc.strokewidth(1) |
| 501 | 501 |
gc.draw('rectangle %d,%d %d,%d' % [
|
| 502 | 502 |
left, 0, left + width, height |
| ... | ... | |
| 522 | 522 |
week_f = @date_from + (7 - @date_from.cwday + 1) |
| 523 | 523 |
width = (7 - @date_from.cwday + 1) * zoom |
| 524 | 524 |
gc.fill('white')
|
| 525 |
gc.stroke('grey')
|
|
| 525 |
gc.stroke('#adb5bd') # oc-gray-5
|
|
| 526 | 526 |
gc.strokewidth(1) |
| 527 | 527 |
gc.draw('rectangle %d,%d %d,%d' % [
|
| 528 | 528 |
left, header_height, left + width, 2 * header_height + g_height - 1 |
| ... | ... | |
| 532 | 532 |
while week_f <= date_to |
| 533 | 533 |
width = (week_f + 6 <= date_to) ? 7 * zoom : (date_to - week_f + 1) * zoom |
| 534 | 534 |
gc.fill('white')
|
| 535 |
gc.stroke('grey')
|
|
| 535 |
gc.stroke('#adb5bd') # oc-gray-5
|
|
| 536 | 536 |
gc.strokewidth(1) |
| 537 | 537 |
gc.draw('rectangle %d,%d %d,%d' % [
|
| 538 | 538 |
left.round, header_height, left.round + width, 2 * header_height + g_height - 1 |
| ... | ... | |
| 553 | 553 |
height = g_height + header_height - 1 |
| 554 | 554 |
(@date_from..date_to).each do |g_date| |
| 555 | 555 |
width = zoom |
| 556 |
gc.fill(non_working_day?(g_date) ? '#eee' : 'white')
|
|
| 557 |
gc.stroke('#ddd')
|
|
| 556 |
gc.fill(non_working_day?(g_date) ? '#f1f3f5' : 'white') # oc-gray-1
|
|
| 557 |
gc.stroke('#dee2e6') # oc-gray-3
|
|
| 558 | 558 |
gc.strokewidth(1) |
| 559 | 559 |
gc.draw('rectangle %d,%d %d,%d' % [
|
| 560 | 560 |
left, 2 * header_height, left + width, 2 * header_height + g_height - 1 |
| ... | ... | |
| 564 | 564 |
end |
| 565 | 565 |
# border |
| 566 | 566 |
gc.fill('transparent')
|
| 567 |
gc.stroke('grey')
|
|
| 567 |
gc.stroke('#adb5bd') # oc-gray-5
|
|
| 568 | 568 |
gc.strokewidth(1) |
| 569 | 569 |
gc.draw('rectangle %d,%d %d,%d' % [
|
| 570 | 570 |
0, 0, subject_width + g_width, headers_height |
| ... | ... | |
| 580 | 580 |
:subject_width => subject_width, :format => :image) |
| 581 | 581 |
# today red line |
| 582 | 582 |
if User.current.today.between?(@date_from, date_to) |
| 583 |
gc.stroke('red')
|
|
| 583 |
gc.stroke('#f03e3e') # oc-red-7
|
|
| 584 | 584 |
x = (User.current.today - @date_from + 1) * zoom + subject_width |
| 585 | 585 |
gc.draw('line %g,%g %g,%g' % [
|
| 586 | 586 |
x, headers_height, x, headers_height + g_height - 1 |
| ... | ... | |
| 673 | 673 |
width = zoom |
| 674 | 674 |
pdf.SetY(y_start + header_height * 2) |
| 675 | 675 |
pdf.SetX(left) |
| 676 |
pdf.SetTextColor(non_working_day?(g_date) ? 150 : 0) |
|
| 676 |
if non_working_day?(g_date) |
|
| 677 |
pdf.SetTextColor(134, 142, 150) # oc-gray-6 |
|
| 678 |
else |
|
| 679 |
pdf.SetTextColor(0) |
|
| 680 |
end |
|
| 677 | 681 |
pdf.RDMCell(width, height, day_num.day.to_s, "LTR", 0, "C") |
| 678 | 682 |
left = left + width |
| 679 | 683 |
day_num = day_num + 1 |
| ... | ... | |
| 688 | 692 |
width = zoom |
| 689 | 693 |
pdf.SetY(y_start + header_height * (show_day_num ? 3 : 2)) |
| 690 | 694 |
pdf.SetX(left) |
| 691 |
pdf.SetTextColor(non_working_day?(g_date) ? 150 : 0) |
|
| 695 |
if non_working_day?(g_date) |
|
| 696 |
pdf.SetTextColor(134, 142, 150) # oc-gray-6 |
|
| 697 |
else |
|
| 698 |
pdf.SetTextColor(0) |
|
| 699 |
end |
|
| 692 | 700 |
pdf.RDMCell(width, height, day_name(g_date.cwday).first, "LTR", 0, "C") |
| 693 | 701 |
left = left + width |
| 694 | 702 |
end |
| ... | ... | |
| 1033 | 1041 |
width = [1, coords[:bar_end] - coords[:bar_start]].max |
| 1034 | 1042 |
params[:pdf].SetY(params[:top] + 1.5) |
| 1035 | 1043 |
params[:pdf].SetX(params[:subject_width] + coords[:bar_start]) |
| 1036 |
params[:pdf].SetFillColor(200, 200, 200)
|
|
| 1044 |
params[:pdf].SetFillColor(206, 212, 218) # oc-gray-4
|
|
| 1037 | 1045 |
params[:pdf].RDMCell(width, height, "", 0, 0, "", 1) |
| 1038 | 1046 |
if coords[:bar_late_end] |
| 1039 | 1047 |
width = [1, coords[:bar_late_end] - coords[:bar_start]].max |
| 1040 | 1048 |
params[:pdf].SetY(params[:top] + 1.5) |
| 1041 | 1049 |
params[:pdf].SetX(params[:subject_width] + coords[:bar_start]) |
| 1042 |
params[:pdf].SetFillColor(255, 100, 100)
|
|
| 1050 |
params[:pdf].SetFillColor(255, 107, 107) # oc-red-5
|
|
| 1043 | 1051 |
params[:pdf].RDMCell(width, height, "", 0, 0, "", 1) |
| 1044 | 1052 |
end |
| 1045 | 1053 |
if coords[:bar_progress_end] |
| 1046 | 1054 |
width = [1, coords[:bar_progress_end] - coords[:bar_start]].max |
| 1047 | 1055 |
params[:pdf].SetY(params[:top] + 1.5) |
| 1048 | 1056 |
params[:pdf].SetX(params[:subject_width] + coords[:bar_start]) |
| 1049 |
params[:pdf].SetFillColor(90, 200, 90)
|
|
| 1057 |
params[:pdf].SetFillColor(81, 207, 102) # oc-green-5
|
|
| 1050 | 1058 |
params[:pdf].RDMCell(width, height, "", 0, 0, "", 1) |
| 1051 | 1059 |
end |
| 1052 | 1060 |
end |
| ... | ... | |
| 1055 | 1063 |
if coords[:start] |
| 1056 | 1064 |
params[:pdf].SetY(params[:top] + 1) |
| 1057 | 1065 |
params[:pdf].SetX(params[:subject_width] + coords[:start] - 1) |
| 1058 |
params[:pdf].SetFillColor(50, 50, 200)
|
|
| 1066 |
params[:pdf].SetFillColor(54, 79, 199) # oc-indigo-9
|
|
| 1059 | 1067 |
params[:pdf].RDMCell(2, 2, "", 0, 0, "", 1) |
| 1060 | 1068 |
end |
| 1061 | 1069 |
if coords[:end] |
| 1062 | 1070 |
params[:pdf].SetY(params[:top] + 1) |
| 1063 | 1071 |
params[:pdf].SetX(params[:subject_width] + coords[:end] - 1) |
| 1064 |
params[:pdf].SetFillColor(50, 50, 200)
|
|
| 1072 |
params[:pdf].SetFillColor(54, 79, 199) # oc-indigo-9
|
|
| 1065 | 1073 |
params[:pdf].RDMCell(2, 2, "", 0, 0, "", 1) |
| 1066 | 1074 |
end |
| 1067 | 1075 |
end |
| ... | ... | |
| 1079 | 1087 |
height /= 2 if markers |
| 1080 | 1088 |
# Renders the task bar, with progress and late |
| 1081 | 1089 |
if coords[:bar_start] && coords[:bar_end] |
| 1082 |
params[:image].fill('#aaa')
|
|
| 1090 |
params[:image].fill('#adb5bd') # oc-gray-5
|
|
| 1083 | 1091 |
params[:image].draw('rectangle %d,%d %d,%d' % [
|
| 1084 | 1092 |
params[:subject_width] + coords[:bar_start], |
| 1085 | 1093 |
params[:top], |
| ... | ... | |
| 1087 | 1095 |
params[:top] - height |
| 1088 | 1096 |
]) |
| 1089 | 1097 |
if coords[:bar_late_end] |
| 1090 |
params[:image].fill('#f66')
|
|
| 1098 |
params[:image].fill('#ff6b6b') # oc-red-5
|
|
| 1091 | 1099 |
params[:image].draw('rectangle %d,%d %d,%d' % [
|
| 1092 | 1100 |
params[:subject_width] + coords[:bar_start], |
| 1093 | 1101 |
params[:top], |
| ... | ... | |
| 1096 | 1104 |
]) |
| 1097 | 1105 |
end |
| 1098 | 1106 |
if coords[:bar_progress_end] |
| 1099 |
params[:image].fill('#00c600')
|
|
| 1107 |
params[:image].fill('#40c057') # oc-green-6
|
|
| 1100 | 1108 |
params[:image].draw('rectangle %d,%d %d,%d' % [
|
| 1101 | 1109 |
params[:subject_width] + coords[:bar_start], |
| 1102 | 1110 |
params[:top], |
| ... | ... | |
| 1110 | 1118 |
if coords[:start] |
| 1111 | 1119 |
x = params[:subject_width] + coords[:start] |
| 1112 | 1120 |
y = params[:top] - height / 2 |
| 1113 |
params[:image].fill('blue')
|
|
| 1121 |
params[:image].fill('#364fc7') # oc-indigo-9
|
|
| 1114 | 1122 |
params[:image].draw('polygon %d,%d %d,%d %d,%d %d,%d' % [
|
| 1115 | 1123 |
x - 4, y, |
| 1116 | 1124 |
x, y - 4, |
| ... | ... | |
| 1121 | 1129 |
if coords[:end] |
| 1122 | 1130 |
x = params[:subject_width] + coords[:end] |
| 1123 | 1131 |
y = params[:top] - height / 2 |
| 1124 |
params[:image].fill('blue')
|
|
| 1132 |
params[:image].fill('#364fc7') # oc-indigo-9
|
|
| 1125 | 1133 |
params[:image].draw('polygon %d,%d %d,%d %d,%d %d,%d' % [
|
| 1126 | 1134 |
x - 4, y, |
| 1127 | 1135 |
x, y - 4, |
- « Previous
- 1
- 2
- 3
- Next »