Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
m
Affluence
Affluence Front
Commits
162b4c08
Commit
162b4c08
authored
May 20, 2020
by
Léonard Treille
Browse files
Improve tooltip and refactor vertical bar build
parent
205e34f3
Changes
14
Hide whitespace changes
Inline
Side-by-side
src/app/app.module.ts
View file @
162b4c08
...
...
@@ -49,6 +49,7 @@ import { SearchInputComponent } from './features/search/search-input/search-inpu
import
{
SearchListComponent
}
from
'
./features/search/search-list/search-list.component
'
;
import
{
SearchItemDirective
}
from
'
./features/search/search-item.directive
'
;
import
{
IdPipe
}
from
'
./pipes/id.pipe
'
;
import
{
ChartTooltipDirective
}
from
'
./components/chart/chart-tooltip.directive
'
;
@
NgModule
({
declarations
:
[
...
...
@@ -78,7 +79,8 @@ import { IdPipe } from './pipes/id.pipe';
SearchInputComponent
,
SearchListComponent
,
SearchItemDirective
,
IdPipe
IdPipe
,
ChartTooltipDirective
],
imports
:
[
BrowserModule
,
...
...
src/app/components/chart/chart-tooltip.directive.ts
0 → 100644
View file @
162b4c08
import
{
Directive
}
from
'
@angular/core
'
;
@
Directive
({
selector
:
'
[appChartTooltip]
'
})
export
class
ChartTooltipDirective
{
constructor
()
{
}
}
src/app/components/chart/chart.component.html
0 → 100644
View file @
162b4c08
<div
class=
"chart-tooltip"
#tooltip
*ngIf=
"tooltipVisible && !tooltipDisabled"
[ngStyle]=
"{'top.px': tooltipTopPosition, 'left.px': tooltipLeftPosition}"
[class.fixed]=
"tooltipFixed"
>
<ng-container
*ngTemplateOutlet=
"tooltipTemplate; context:{$implicit: {x: tooltipXValue, y: tooltipYValue}}"
></ng-container>
</div>
<div
class=
"loader-wrapper"
>
<mat-spinner
mode=
"indeterminate"
diameter=
"64"
*ngIf=
"dataset.options.ghost && !dataset.options.unavailable"
></mat-spinner>
</div>
<p
class=
"empty-message"
*ngIf=
"dataset?.options?.empty"
>
Aucune donnée
</p>
<p
class=
"unavailable-message"
*ngIf=
"dataset?.options?.unavailable"
>
Données non disponibles
</p>
src/app/components/chart/chart.component.scss
0 → 100644
View file @
162b4c08
:host
{
display
:
block
;
position
:
relative
;
}
.loader-wrapper
{
position
:
absolute
;
top
:
50%
;
left
:
50%
;
transform
:
translate
(
-50%
,
-50%
);
}
src/app/components/chart/chart.component.ts
View file @
162b4c08
import
{
Component
,
OnInit
,
ElementRef
,
Input
,
OnChanges
,
SimpleChanges
,
Optional
,
Inject
,
OnDestroy
,
HostListener
,
ViewChild
,
AfterViewInit
,
HostBinding
}
from
'
@angular/core
'
;
import
{
Component
,
OnInit
,
ElementRef
,
Input
,
OnChanges
,
SimpleChanges
,
Optional
,
Inject
,
OnDestroy
,
HostListener
,
ViewChild
,
AfterViewInit
,
HostBinding
,
ContentChild
,
TemplateRef
}
from
'
@angular/core
'
;
import
*
as
d3
from
'
d3
'
;
import
{
Subject
,
fromEvent
,
merge
}
from
'
rxjs
'
;
import
{
debounceTime
,
takeUntil
,
tap
}
from
'
rxjs/operators
'
;
import
{
Dataset
,
ChartType
,
ChartContext
,
Point
}
from
'
./chart.model
'
;
import
{
ChartTooltipDirective
}
from
'
./chart-tooltip.directive
'
;
@
Component
({
selector
:
'
app-chart
'
,
template
:
`
<div class="chart-tooltip" #tooltip *ngIf="tooltipVisible && !tooltipDisabled" [ngStyle]="{'top.px': tooltipTopPosition, 'left.px': tooltipLeftPosition}" [class.fixed]="tooltipFixed">
<span class="x">{{ tooltipXValue }}</span><br>
<span class="y">{{ tooltipYValue }}</span>
</div>
<div class="loader-wrapper">
<mat-spinner mode="indeterminate" diameter="64" *ngIf="dataset.options.ghost && !dataset.options.unavailable"></mat-spinner>
</div>
<p class="empty-message" *ngIf="dataset?.options?.empty">Aucune donnée</p>
<p class="unavailable-message" *ngIf="dataset?.options?.unavailable">Données non disponibles</p>
`
,
styles
:
[
'
:host {display: block; position: relative;}
'
,
'
.loader-wrapper { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); }
'
]
templateUrl
:
'
./chart.component.html
'
,
styleUrls
:
[
'
./chart.component.scss
'
]
})
export
class
ChartComponent
implements
OnInit
,
OnChanges
,
OnDestroy
,
AfterViewInit
{
...
...
@@ -39,6 +27,8 @@ export class ChartComponent implements OnInit, OnChanges, OnDestroy, AfterViewIn
@
ViewChild
(
'
tooltip
'
)
tooltip
:
ElementRef
<
HTMLElement
>
;
@
ContentChild
(
ChartTooltipDirective
,
{
read
:
TemplateRef
})
tooltipTemplate
:
TemplateRef
<
any
>
;
private
chart
:
d3
.
Selection
;
private
chartTypes
:
ChartType
[];
private
unsubscriber
=
new
Subject
<
void
>
();
...
...
src/app/components/chart/types/BaseChartType.ts
View file @
162b4c08
...
...
@@ -110,17 +110,8 @@ export abstract class BaseChartType {
.
attr
(
'
transform
'
,
`translate(0,
${
context
.
height
-
(
paddingBottom
*
2
)}
)`
)
.
call
(
axisX
);
const
fakeData
=
[];
if
(
dataset
.
points
.
length
)
{
fakeData
.
push
(
'
y
'
);
}
const
yAxisSelection
=
context
.
chart
.
selectAll
(
'
.y-axis
'
).
data
(
fakeData
);
yAxisSelection
.
transition
(
this
.
transitionDuration
)
.
call
(
axisY
)
.
selectAll
(
'
.full-width-line
'
)
.
attr
(
'
x1
'
,
-
6
)
.
attr
(
'
x2
'
,
context
.
width
-
(
paddingRight
*
2
)
+
6
);
const
yAxisSelection
=
context
.
chart
.
selectAll
(
'
.y-axis
'
).
data
([
'
y
'
]);
yAxisSelection
.
enter
()
.
append
(
'
g
'
)
...
...
@@ -131,11 +122,16 @@ export abstract class BaseChartType {
.
append
(
'
line
'
)
.
attr
(
'
class
'
,
'
full-width-line
'
)
.
attr
(
'
x1
'
,
-
6
)
.
attr
(
'
x2
'
,
0
)
.
style
(
'
opacity
'
,
0
)
.
transition
(
this
.
transitionDuration
)
.
delay
((
p
:
Point
,
i
:
number
)
=>
i
*
this
.
axisLineStaggerTime
)
.
style
(
'
opacity
'
,
1
)
.
attr
(
'
x2
'
,
context
.
width
-
(
paddingRight
*
3
));
const
select
=
yAxisSelection
.
call
(
axisY
);
const
ticks
=
select
.
selectAll
(
'
.tick
'
);
const
customLines
=
ticks
.
selectAll
(
'
.full-width-line
'
).
data
([
'
y
'
])
customLines
.
enter
()
.
append
(
'
line
'
)
.
attr
(
'
class
'
,
'
full-width-line
'
)
.
attr
(
'
x1
'
,
-
6
)
.
attr
(
'
x2
'
,
context
.
width
-
(
paddingRight
*
3
));
this
.
displayAxis
=
true
;
}
...
...
src/app/components/chart/types/vertical-bar.chart-type.ts
View file @
162b4c08
...
...
@@ -64,7 +64,8 @@ export class VerticalBarChartType extends BaseChartType implements ChartType {
}
return
classes
;
})
.
style
(
'
opacity
'
,
dataset
.
options
.
ghost
?
0.3
:
0.9
);
.
style
(
'
opacity
'
,
dataset
.
options
.
ghost
?
0.3
:
0.9
)
.
attr
(
'
data-point
'
,
p
=>
JSON
.
stringify
(
p
));
barsSelection
.
enter
()
.
append
(
'
path
'
)
.
attr
(
'
class
'
,
p
=>
{
...
...
src/app/components/detail-prochainspassages/detail-prochainspassages.component.ts
View file @
162b4c08
...
...
@@ -57,7 +57,7 @@ export class DetailProchainspassagesComponent implements OnInit, OnDestroy {
constructor
(
private
realtimeDataService
:
RealtimeDataService
,
private
appVisibilityService
:
AppVisibilityService
,
p
ublic
dialog
:
MatDialog
p
rivate
dialog
:
MatDialog
)
{
}
ngOnInit
()
{
...
...
@@ -138,8 +138,7 @@ export class DetailProchainspassagesComponent implements OnInit, OnDestroy {
openChartDialog
(
obj
:
NextStop
)
{
this
.
dialog
.
open
(
OccupancyChartDialogComponent
,
{
data
:
obj
,
minWidth
:
'
300px
'
,
maxWidth
:
'
100vw
'
panelClass
:
'
occupancy-chart-dialog
'
,
});
}
...
...
src/app/features/occupancy/occupancy-chart-dialog/occupancy-chart-dialog.component.html
View file @
162b4c08
<h1
mat-dialog-title
>
Fréquentation en temps normal
</h1>
<div
mat-dialog-content
>
<app-chart
type=
"vertical-bar"
[dataset]=
"data | occupancyDataset:axis | async"
[tooltipOnClick]=
"true"
></app-chart>
<app-chart
type=
"vertical-bar"
[dataset]=
"data | occupancyDataset:axis | async"
[tooltipOnClick]=
"true"
>
<p
*appChartTooltip=
"let values"
>
<b>
{{ values.y }} personnes
</b><br>
avaient été enregistrées à la montée entre {{ values.x }}.
</p>
</app-chart>
</div>
src/app/features/occupancy/occupancy-chart-dialog/occupancy-chart-dialog.component.scss
View file @
162b4c08
...
...
@@ -11,3 +11,7 @@ app-chart {
margin-top
:
$spacing
*
5
;
box-sizing
:
border-box
;
}
p
{
margin
:
0
;
}
src/app/features/occupancy/occupancy-chart-dialog/occupancy-chart-dialog.component.ts
View file @
162b4c08
...
...
@@ -15,17 +15,14 @@ export class OccupancyChartDialogComponent implements OnInit {
let
end
=
''
;
dataset
.
points
.
forEach
(
group
=>
{
group
.
forEach
((
p
,
i
,
list
)
=>
{
if
(
p
.
x
===
point
.
x
&&
p
.
y
===
point
.
y
)
{
if
(
p
.
x
===
point
.
x
)
{
end
=
list
[
i
+
1
]
?
list
[
i
+
1
].
x
as
string
:
'
23:59
'
;
}
});
});
return
`
Entre
${
value
.
split
(
'
:
'
).
join
(
'
h
'
)}
et
${
end
.
split
(
'
:
'
).
join
(
'
h
'
)}
:
`
;
return
`
${
value
.
split
(
'
:
'
).
join
(
'
h
'
)}
et
${
end
.
split
(
'
:
'
).
join
(
'
h
'
)}
`
;
},
},
y
:
{
tooltipFormatter
:
(
value
,
point
:
Point
,
dataset
:
Dataset
)
=>
`
${
value
}
personnes`
,
}
};
constructor
(@
Inject
(
MAT_DIALOG_DATA
)
public
data
:
NextStop
)
{
}
...
...
src/app/features/occupancy/occupancy-dataset.pipe.ts
View file @
162b4c08
...
...
@@ -54,6 +54,8 @@ export class OccupancyDatasetPipe implements PipeTransform {
}
};
if
(
!
isEmpty
)
{
// Add a fake value to display the last column correctly.
points
.
push
({
x
:
'
23:59
'
,
y
:
0
});
dataset
.
points
=
[
points
];
}
}
else
{
...
...
src/styles/components/_chart.scss
View file @
162b4c08
...
...
@@ -62,7 +62,7 @@
&
::after
{
content
:
""
;
position
:
absolute
;
bottom
:
0
;
bottom
:
1px
;
left
:
50%
;
transform
:
translate
(
-50%
,
100%
);
width
:
0
;
...
...
@@ -71,10 +71,10 @@
border-right
:
8px
solid
transparent
;
body
.dark-theme
&
{
border-top
:
8px
solid
rgba
(
dark-color-overlay
(
16
)
,
0
.9
);
border-top
:
8px
solid
rgba
(
dark-color-overlay
(
16
)
,
0
.9
9
);
}
body
.light-theme
&
{
border-top
:
8px
solid
rgba
(
light-color-overlay
(
16
)
,
0
.9
);
border-top
:
8px
solid
rgba
(
light-color-overlay
(
16
)
,
0
.9
9
);
}
}
}
...
...
@@ -85,7 +85,7 @@
}
body
.dark-theme
&
{
background
:
rgba
(
dark-color-overlay
(
16
)
,
0
.9
);
background
:
rgba
(
dark-color-overlay
(
16
)
,
0
.9
9
);
span
{
&
.x
{
...
...
@@ -98,7 +98,7 @@
}
}
body
.light-theme
&
{
background
:
rgba
(
light-color-overlay
(
1
)
,
0
.9
);
background
:
rgba
(
light-color-overlay
(
1
)
,
0
.9
9
);
span
{
&
.x
{
...
...
src/styles/components/_dialog.scss
View file @
162b4c08
...
...
@@ -22,3 +22,11 @@
}
}
}
.cdk-overlay-pane.occupancy-chart-dialog
{
width
:
90%
;
@media
screen
and
(
min-width
:
$mpwa-breakpoint
+
1px
)
{
width
:
50vw
;
}
}
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