feat: align design with figma
This commit is contained in:
parent
0cefc57624
commit
901f78e717
@ -149,7 +149,7 @@ export default class Bar {
|
||||
$date_highlight.classList.add('date-highlight')
|
||||
$date_highlight.style.height = this.height * 0.8 + 'px'
|
||||
$date_highlight.style.width = this.width + 'px'
|
||||
$date_highlight.style.top = this.gantt.options.header_height - 19 + 'px'
|
||||
$date_highlight.style.top = this.gantt.options.header_height - 24 + 'px'
|
||||
$date_highlight.style.left = x + 'px'
|
||||
this.$date_highlight = $date_highlight
|
||||
this.gantt.$lower_header.prepend($date_highlight)
|
||||
|
||||
117
src/gantt.scss
117
src/gantt.scss
@ -3,21 +3,27 @@
|
||||
$bar-color: #fff !default;
|
||||
$bar-color-important: #94c4f4 !default;
|
||||
$bar-stroke: #fff !default;
|
||||
$border-color: #e0e0e0 !default;
|
||||
$dark-stroke-color: #e0e0e0 !default;
|
||||
$stroke-color: #EBEEF0 !default;
|
||||
$light-bg: #f5f5f5 !default;
|
||||
$light-border-color: #ebeff2 !default;
|
||||
$light-yellow: #f6e796 !default;
|
||||
$holiday-color: #f3f4f7 !default;
|
||||
$holiday-color: #F9FAFA !default;
|
||||
$text-muted: #666 !default;
|
||||
$text-grey: #98A1A9;
|
||||
$text-light: #fff !default;
|
||||
$text-dark: #111 !default;
|
||||
$progress-important: #2c94ec !default;
|
||||
$progress: #dedfe0 !default;
|
||||
$progress: #EBEEF0 !default;
|
||||
$handle-color: #dcdce4 !default;
|
||||
$handle-color-important: #94c4f4 !default;
|
||||
$light-blue: #c4c4e9 !default;
|
||||
$middle-blue: #62B2F9 !default;
|
||||
$dark-blue: #2c94ec !default;
|
||||
|
||||
|
||||
.gantt-container {
|
||||
line-height: 14.5px;
|
||||
|
||||
.grid-header {
|
||||
background-color: #ffffff;
|
||||
position: sticky;
|
||||
@ -27,12 +33,20 @@ $light-blue: #c4c4e9 !default;
|
||||
|
||||
.lower-text,
|
||||
.upper-text {
|
||||
font-size: 14px;
|
||||
text-anchor: middle;
|
||||
color: $text-muted;
|
||||
color: $text-dark;
|
||||
}
|
||||
|
||||
.upper-header {
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.lower-header {
|
||||
height: 56px;
|
||||
}
|
||||
|
||||
.lower-text {
|
||||
font-size: 14px;
|
||||
position: absolute;
|
||||
width: fit-content;
|
||||
}
|
||||
@ -40,6 +54,8 @@ $light-blue: #c4c4e9 !default;
|
||||
.upper-text {
|
||||
position: absolute;
|
||||
width: fit-content;
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.current-upper {
|
||||
@ -49,32 +65,51 @@ $light-blue: #c4c4e9 !default;
|
||||
.side-header {
|
||||
position: fixed;
|
||||
padding: 0 10px;
|
||||
margin-right: 10px;
|
||||
background: white;
|
||||
line-height: 20px;
|
||||
font-weight: 400;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.today-button,
|
||||
.viewmode-select {
|
||||
background-color: $text-light;
|
||||
border: 1px solid black;
|
||||
.today-button {
|
||||
background: #F4F5F6;
|
||||
border: none;
|
||||
color: $text-dark;
|
||||
padding: 4px 10px;
|
||||
font-size: 14px;
|
||||
border-radius: 5px;
|
||||
border-radius: 8px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.viewmode-select {
|
||||
padding: 3px 5px;
|
||||
margin-right: 4px;
|
||||
background: #F4F5F6;
|
||||
text-align: center;
|
||||
outline: none !important;
|
||||
padding: 4px 8px;
|
||||
border-radius: 6px;
|
||||
// display: block;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.date-highlight {
|
||||
background-color: $text-muted;
|
||||
background-color: $progress;
|
||||
border-radius: 12px;
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
opacity: 0.4;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.current-highlight {
|
||||
position: absolute;
|
||||
background: $dark-blue;
|
||||
width: 1px;
|
||||
}
|
||||
|
||||
.current-date-highlight {
|
||||
background: $dark-blue;
|
||||
color: $text-light;
|
||||
padding: 4px;
|
||||
border-radius: 200px;
|
||||
}
|
||||
}
|
||||
|
||||
.gantt {
|
||||
@ -101,38 +136,19 @@ $light-blue: #c4c4e9 !default;
|
||||
}
|
||||
|
||||
.tick {
|
||||
stroke: $border-color;
|
||||
stroke: $stroke-color;
|
||||
stroke-width: 0.2;
|
||||
|
||||
&.thick {
|
||||
stroke: #000;
|
||||
stroke-width: 0.5;
|
||||
stroke: $dark-stroke-color;
|
||||
stroke-width: 0.7;
|
||||
}
|
||||
}
|
||||
|
||||
.today-highlight {
|
||||
fill: $light-yellow;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.week-highlight {
|
||||
fill: $light-yellow;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.holiday-highlight {
|
||||
fill: $holiday-color;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.month-highlight {
|
||||
fill: $light-yellow;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.year-highlight {
|
||||
fill: $light-yellow;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.arrow {
|
||||
@ -148,14 +164,10 @@ $light-blue: #c4c4e9 !default;
|
||||
transition: stroke-width 0.3s ease;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.bar-progress {
|
||||
fill: $progress;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.bar-expected-progress {
|
||||
fill: $light-blue;
|
||||
}
|
||||
@ -176,7 +188,7 @@ $light-blue: #c4c4e9 !default;
|
||||
dominant-baseline: central;
|
||||
// text-anchor: middle;
|
||||
font-family: Helvetica;
|
||||
font-size: 14px;
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
|
||||
&.big {
|
||||
@ -191,7 +203,7 @@ $light-blue: #c4c4e9 !default;
|
||||
}
|
||||
|
||||
.bar-progress {
|
||||
fill: $progress-important;
|
||||
fill: $dark-blue;
|
||||
}
|
||||
|
||||
.bar-label {
|
||||
@ -257,27 +269,24 @@ $light-blue: #c4c4e9 !default;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background: rgba(0, 0, 0);
|
||||
padding: 0;
|
||||
color: #959da5;
|
||||
border-radius: 3px;
|
||||
border: 1px solid rgba(0, 0, 0);
|
||||
background: #171B1F;
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
width: max-content;
|
||||
|
||||
&.hidden {
|
||||
opacity: 0 !important;
|
||||
}
|
||||
|
||||
|
||||
.title {
|
||||
border-bottom: 1px solid $progress;
|
||||
padding: 10px;
|
||||
margin-bottom: 5px;
|
||||
text-align: center;
|
||||
color: $text-light;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
padding: 10px;
|
||||
color: #dfe2e5;
|
||||
color: $text-grey;
|
||||
}
|
||||
|
||||
.pointer {
|
||||
|
||||
144
src/index.js
144
src/index.js
@ -85,7 +85,7 @@ export default class Gantt {
|
||||
|
||||
setup_options(options) {
|
||||
const default_options = {
|
||||
header_height: 50,
|
||||
header_height: 65,
|
||||
column_width: 30,
|
||||
step: 24,
|
||||
view_modes: [...Object.values(VIEW_MODE)],
|
||||
@ -340,6 +340,7 @@ export default class Gantt {
|
||||
this.make_grid();
|
||||
this.make_dates();
|
||||
this.make_bars();
|
||||
this.make_grid_extras();
|
||||
this.make_arrows();
|
||||
this.map_arrows_on_bars();
|
||||
this.set_width();
|
||||
@ -363,8 +364,11 @@ export default class Gantt {
|
||||
this.make_grid_background();
|
||||
this.make_grid_rows();
|
||||
this.make_grid_header();
|
||||
this.make_grid_ticks();
|
||||
}
|
||||
|
||||
make_grid_extras() {
|
||||
this.make_grid_highlights();
|
||||
this.make_grid_ticks();
|
||||
}
|
||||
|
||||
make_grid_background() {
|
||||
@ -391,14 +395,13 @@ export default class Gantt {
|
||||
|
||||
make_grid_rows() {
|
||||
const rows_layer = createSVG("g", { append_to: this.layers.grid });
|
||||
const lines_layer = createSVG("g", { append_to: this.layers.grid });
|
||||
|
||||
const row_width = this.dates.length * this.options.column_width;
|
||||
const row_height = this.options.bar_height + this.options.padding;
|
||||
|
||||
let row_y = this.options.header_height + this.options.padding / 2;
|
||||
|
||||
for (let task of this.tasks) {
|
||||
for (let _ of this.tasks) {
|
||||
createSVG("rect", {
|
||||
x: 0,
|
||||
y: row_y,
|
||||
@ -408,14 +411,7 @@ export default class Gantt {
|
||||
append_to: rows_layer,
|
||||
});
|
||||
if (this.options.lines === 'both' || this.options.lines === 'horizontal') {
|
||||
createSVG("line", {
|
||||
x1: 0,
|
||||
y1: row_y + row_height,
|
||||
x2: row_width,
|
||||
y2: row_y + row_height,
|
||||
class: "row-line",
|
||||
append_to: lines_layer,
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
row_y += this.options.bar_height + this.options.padding;
|
||||
@ -445,10 +441,13 @@ export default class Gantt {
|
||||
this.$lower_header = $lower_header
|
||||
this.$header.appendChild($lower_header)
|
||||
|
||||
this.make_side_header()
|
||||
}
|
||||
|
||||
make_side_header() {
|
||||
let $side_header = document.createElement('div')
|
||||
$side_header.classList.add('side-header')
|
||||
|
||||
|
||||
// Create view mode change select
|
||||
const $select = document.createElement("select");
|
||||
$select.classList.add('viewmode-select')
|
||||
@ -473,19 +472,40 @@ export default class Gantt {
|
||||
$side_header.appendChild($today_button)
|
||||
|
||||
this.$header.appendChild($side_header)
|
||||
const { left, y } = $header.getBoundingClientRect();
|
||||
const { left, y } = this.$header.getBoundingClientRect();
|
||||
const width = Math.min(this.$header.clientWidth, this.$container.clientWidth)
|
||||
$side_header.style.left = left + this.$container.scrollLeft + width - $side_header.clientWidth + 'px';
|
||||
$side_header.style.top = y + 5 + 'px';
|
||||
$side_header.style.top = y + 20 + 'px';
|
||||
}
|
||||
|
||||
make_grid_ticks() {
|
||||
if (this.options.lines !== 'both' && this.options.lines !== 'vertical') return
|
||||
if (!['both', 'vertical', 'horizontal'].includes(this.options.lines)) return
|
||||
let tick_x = 0;
|
||||
let tick_y = this.options.header_height + this.options.padding / 2;
|
||||
let tick_height =
|
||||
(this.options.bar_height + this.options.padding) * this.tasks.length;
|
||||
|
||||
let $lines_layer = createSVG("g", { class: 'lines_layer', append_to: this.layers.grid });
|
||||
|
||||
|
||||
let row_y = this.options.header_height + this.options.padding / 2;
|
||||
|
||||
const row_width = this.dates.length * this.options.column_width;
|
||||
const row_height = this.options.bar_height + this.options.padding;
|
||||
if (this.options.lines !== 'vertical') {
|
||||
for (let _ of this.tasks) {
|
||||
createSVG("line", {
|
||||
x1: 0,
|
||||
y1: row_y + row_height,
|
||||
x2: row_width,
|
||||
y2: row_y + row_height,
|
||||
class: "row-line",
|
||||
append_to: $lines_layer,
|
||||
});
|
||||
row_y += row_height;
|
||||
}
|
||||
}
|
||||
if (this.options.lines === 'horizontal') return;
|
||||
for (let date of this.dates) {
|
||||
let tick_class = "tick";
|
||||
// thick tick for monday
|
||||
@ -542,14 +562,16 @@ export default class Gantt {
|
||||
|
||||
//compute the horizontal x distance
|
||||
computeGridHighlightDimensions(view_mode) {
|
||||
let xDist = 0;
|
||||
let x = this.options.column_width / 2;
|
||||
|
||||
if (this.view_is(VIEW_MODE.DAY)) {
|
||||
return (
|
||||
(date_utils.diff(date_utils.today(), this.gantt_start, "hour") /
|
||||
this.options.step) *
|
||||
this.options.column_width
|
||||
);
|
||||
let today = date_utils.today()
|
||||
return {
|
||||
x: x +
|
||||
(date_utils.diff(today, this.gantt_start, "hour") / this.options.step) *
|
||||
this.options.column_width,
|
||||
date: today
|
||||
}
|
||||
}
|
||||
|
||||
for (let date of this.dates) {
|
||||
@ -568,12 +590,11 @@ export default class Gantt {
|
||||
break;
|
||||
}
|
||||
if (todayDate >= startDate && todayDate <= endDate) {
|
||||
break;
|
||||
return { x, date: startDate }
|
||||
} else {
|
||||
xDist += this.options.column_width;
|
||||
x += this.options.column_width;
|
||||
}
|
||||
}
|
||||
return xDist;
|
||||
}
|
||||
|
||||
make_grid_highlights() {
|
||||
@ -585,49 +606,43 @@ export default class Gantt {
|
||||
this.view_is(VIEW_MODE.MONTH) ||
|
||||
this.view_is(VIEW_MODE.YEAR)
|
||||
) {
|
||||
const x = this.computeGridHighlightDimensions(this.options.view_mode);
|
||||
const y = 0;
|
||||
const width = this.options.column_width;
|
||||
const height =
|
||||
(this.options.bar_height + this.options.padding) * this.tasks.length +
|
||||
this.options.header_height +
|
||||
this.options.padding / 2;
|
||||
// Used as we must find the _end_ of session if view is not Day
|
||||
const { x: left, date } = this.computeGridHighlightDimensions(this.options.view_mode)
|
||||
const top = this.options.header_height + this.options.padding / 2;
|
||||
const height = (this.options.bar_height + this.options.padding) * this.tasks.length;
|
||||
this.create_el({ top, left, height, classes: 'current-highlight', append_to: this.$container })
|
||||
let $today = document.getElementById(date_utils.format(date).replaceAll(' ', '_'))
|
||||
|
||||
let className = "";
|
||||
switch (this.options.view_mode) {
|
||||
case VIEW_MODE.DAY:
|
||||
className = "today-highlight";
|
||||
break;
|
||||
case VIEW_MODE.WEEK:
|
||||
className = "week-highlight";
|
||||
break;
|
||||
case VIEW_MODE.MONTH:
|
||||
className = "month-highlight";
|
||||
break;
|
||||
case VIEW_MODE.YEAR:
|
||||
className = "year-highlight";
|
||||
break;
|
||||
}
|
||||
createSVG("rect", {
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height,
|
||||
class: className,
|
||||
append_to: this.layers.grid,
|
||||
});
|
||||
$today.classList.add('current-date-highlight')
|
||||
$today.style.top = +$today.style.top.slice(0, -2) - 4 + 'px'
|
||||
$today.style.left = +$today.style.left.slice(0, -2) - 4 + 'px'
|
||||
}
|
||||
}
|
||||
|
||||
create_el({ left, top, width, height, id, classes, append_to }) {
|
||||
let $el = document.createElement("div");
|
||||
$el.classList.add(classes)
|
||||
$el.style.top = top + 'px'
|
||||
$el.style.left = left + 'px'
|
||||
if (id) $el.id = id
|
||||
if (width) $el.style.width = height + 'px'
|
||||
if (height) $el.style.height = height + 'px'
|
||||
append_to.appendChild($el)
|
||||
return $el
|
||||
}
|
||||
|
||||
make_dates() {
|
||||
this.upper_texts_x = {}
|
||||
this.get_dates_to_draw().forEach((date, i) => {
|
||||
let $lower_text = document.createElement('div');
|
||||
$lower_text.classList.add('lower-text')
|
||||
let $lower_text = this.create_el({
|
||||
left: date.lower_x,
|
||||
top: date.lower_y,
|
||||
id: date.formatted_date,
|
||||
classes: 'lower-text',
|
||||
append_to: this.$lower_header
|
||||
})
|
||||
$lower_text.innerText = date.lower_text
|
||||
this.$lower_header.appendChild($lower_text)
|
||||
$lower_text.style.left = date.lower_x - (true ? $lower_text.clientWidth / 2 : 0) + 'px'
|
||||
$lower_text.style.top = date.lower_y + 'px'
|
||||
$lower_text.style.left = +$lower_text.style.left.slice(0, -2) - $lower_text.clientWidth / 2 + 'px'
|
||||
|
||||
if (date.upper_text) {
|
||||
this.upper_texts_x[date.upper_text] = date.upper_x
|
||||
@ -708,8 +723,8 @@ export default class Gantt {
|
||||
x: last_date_info
|
||||
? last_date_info.base_pos_x + last_date_info.column_width
|
||||
: 0,
|
||||
lower_y: this.options.header_height - 15,
|
||||
upper_y: this.options.header_height - 40,
|
||||
lower_y: this.options.header_height - 20,
|
||||
upper_y: this.options.header_height - 50,
|
||||
};
|
||||
const x_pos = {
|
||||
Hour_lower: column_width / 2,
|
||||
@ -729,6 +744,7 @@ export default class Gantt {
|
||||
};
|
||||
return {
|
||||
date,
|
||||
formatted_date: date_utils.format(date).replaceAll(' ', '_'),
|
||||
column_width,
|
||||
base_pos_x: base_pos.x,
|
||||
upper_text: date_text[`${this.options.view_mode}_upper`],
|
||||
@ -907,13 +923,13 @@ export default class Gantt {
|
||||
if ($current) {
|
||||
$current.classList.remove('current-upper')
|
||||
$current.style.left = this.upper_texts_x[$current.textContent] + 'px';
|
||||
$current.style.top = this.options.header_height - 40 + 'px';
|
||||
$current.style.top = this.options.header_height - 50 + 'px';
|
||||
}
|
||||
|
||||
$el.classList.add('current-upper')
|
||||
let dimensions = this.$svg.getBoundingClientRect()
|
||||
$el.style.left = dimensions.x + this.$container.scrollLeft + 10 + 'px';
|
||||
$el.style.top = dimensions.y + this.options.header_height - 40 + 'px';
|
||||
$el.style.top = dimensions.y + this.options.header_height - 50 + 'px';
|
||||
}
|
||||
|
||||
Array.prototype.forEach.call(elements, function (el, i) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user