Skip to content
Next
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Switch to GitLab Next
Sign in / Register
Toggle navigation
Minds Frontend
Project
Project
Details
Activity
Releases
Cycle Analytics
Insights
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Locked Files
Issues
850
Issues
850
List
Boards
Labels
Service Desk
Milestones
Merge Requests
46
Merge Requests
46
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Security & Compliance
Security & Compliance
Dependency List
Packages
Packages
List
Container Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Minds
Minds Frontend
Compare Revisions
b4b31d93d5a0135c15c25310efe6c73908097fa4...0f7f70cbe18b2a84a61545527a44b2b738ef2220
Source
0f7f70cbe18b2a84a61545527a44b2b738ef2220
Select Git revision
...
Target
b4b31d93d5a0135c15c25310efe6c73908097fa4
Select Git revision
Compare
Commits (4)
(chore): change e2e to qa and introduce manual qa step
· 82b78175
Mark Harding
authored
12 hours ago
82b78175
(chore): do not allow failure during manual qa
· 69eda7ca
Mark Harding
authored
11 hours ago
69eda7ca
(feat): plotly styles
· 5b4d8490
Olivia Madrid
authored
39 minutes ago
5b4d8490
Merge branch 'master' of gitlab.com:minds/front into entity-centric-metrics
· 0f7f70cb
Olivia Madrid
authored
39 minutes ago
0f7f70cb
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
248 additions
and
84 deletions
+248
-84
.gitlab-ci.yml
.gitlab-ci.yml
+18
-3
chart.component.html
...odules/analytics/v2/components/chart/chart.component.html
+12
-2
chart.component.scss
...odules/analytics/v2/components/chart/chart.component.scss
+31
-1
chart.component.ts
.../modules/analytics/v2/components/chart/chart.component.ts
+177
-66
dashboard.component.html
src/app/modules/analytics/v2/dashboard.component.html
+6
-7
dashboard.component.ts
src/app/modules/analytics/v2/dashboard.component.ts
+4
-5
No files found.
.gitlab-ci.yml
View file @
0f7f70cb
...
...
@@ -9,7 +9,7 @@ stages:
-
prepare
-
review
-
deploy:staging
-
test:e2e
-
qa
-
deploy:canary
-
deploy:production
-
cleanup
...
...
@@ -34,9 +34,13 @@ lint:
-
prettier --check "src/**/*.scss"
-
prettier --check "src/**/*.html"
e2e:chrome:
############
# QA Stage #
############
qa:e2e:
image
:
cypress/browsers:chrome67
stage
:
test:e2e
stage
:
qa
variables
:
CYPRESS_INSTALL_BINARY
:
3.4.1
script
:
...
...
@@ -61,6 +65,17 @@ e2e:chrome:
-
cache/Cypress
allow_failure
:
true
#manual inspection in case of timeouts
qa:manual:
stage
:
qa
script
:
-
echo "Manually approved"
when
:
manual
only
:
refs
:
-
master
-
test/gitlab-ci
allow_failure
:
false
###############
# Build Stage #
###############
...
...
This diff is collapsed.
Click to expand it.
src/app/modules/analytics/v2/components/chart/chart.component.html
View file @
0f7f70cb
<div
class=
"chart-container"
#chartContainer
>
<m-graph
[data]=
"data4"
[layout]=
"layout"
></m-graph>
<div
id=
"chartContainer"
class=
"chart-container"
></div>
<div
id=
"hoverInfo"
class=
"hoverInfo"
[style.top]=
"'closestHoverPointPositionX' + 'px'"
[style.left]=
"'closestHoverPointPositionY' + 'px'"
>
<div
id=
"hoverInfo__x"
class=
"hoverInfo__row--secondary"
>
x
</div>
<div
id=
"hoverInfo__y"
class=
"hoverInfo__row--primary"
>
y
</div>
<div
id=
"hoverInfo__comparisonXy"
class=
"hoverInfo__row--secondary"
>
z
</div>
</div>
<!-- <div *ngIf="(the vm.metric with the visualisation is type=chart)"> -->
This diff is collapsed.
Click to expand it.
src/app/modules/analytics/v2/components/chart/chart.component.scss
View file @
0f7f70cb
plotly-plot
{
m-analytics__chart
{
position
:
relative
;
.js-plotly-plot
,
.plot-container
{
height
:
44vh
;
}
}
#chartContainer
{
position
:
relative
;
g
,
g
>
*
{
cursor
:
default
;
}
}
.hoverInfo
{
// display: none; // TODO: uncomment
padding
:
16px
;
position
:
absolute
;
pointer-events
:
none
;
border-radius
:
2px
;
font-size
:
11px
;
@include
m-theme
()
{
background-color
:
themed
(
$m-white
);
box-shadow
:
0
0
4px
rgba
(
themed
(
$m-black
)
,
0
.3
);
color
:
themed
(
$m-grey-200
);
}
.hoverInfo__row--primary
{
font-size
:
14px
;
font-weight
:
bold
;
@include
m-theme
()
{
color
:
themed
(
$m-grey-500
);
}
}
}
This diff is collapsed.
Click to expand it.
src/app/modules/analytics/v2/components/chart/chart.component.ts
View file @
0f7f70cb
import
{
Component
,
OnInit
,
OnDestroy
,
HostListener
,
ViewChild
,
ElementRef
,
ChangeDetectionStrategy
,
ChangeDetectorRef
,
}
from
'
@angular/core
'
;
import
{
Observable
}
from
'
rxjs
'
;
import
{
Observable
,
Subscription
}
from
'
rxjs
'
;
import
{
AnalyticsDashboardService
,
Category
,
...
...
@@ -22,86 +22,120 @@ import {
UserState
,
}
from
'
../../dashboard.service
'
;
import
*
as
Plotly
from
'
plotly.js
'
;
import
{
Config
,
Data
,
Layout
}
from
'
plotly.js
'
;
// TODO: remove this?
import
{
ThemeService
}
from
'
../../../../../common/services/theme.service
'
;
@
Component
({
selector
:
'
m-analytics__chart
'
,
templateUrl
:
'
chart.component.html
'
,
changeDetection
:
ChangeDetectionStrategy
.
OnPush
,
})
export
class
AnalyticsChartComponent
implements
OnInit
{
export
class
AnalyticsChartComponent
implements
OnInit
,
OnDestroy
{
response
=
this
.
analyticsService
.
getData
();
visualisation
:
Visualisation
;
vm$
:
Observable
<
UserState
>
=
this
.
analyticsService
.
vm$
;
data4
=
[
isDark
:
boolean
=
false
;
themeSubscription
:
Subscription
;
// TODO: make these come from vm$ (or analyticsService.getVisualisation()?);
x1
:
Array
<
any
>
=
[
'
08/30
'
,
'
08/31
'
,
'
09/01
'
,
'
09/02
'
,
'
09/03
'
];
y1
:
Array
<
any
>
=
[
4
,
9
,
16
,
17
,
15
];
y2
:
Array
<
any
>
=
[
3
,
7
,
14
,
18
,
16
];
// x2 would be the actual dates for y2
analyticsPlot
:
any
=
{};
hoverInfoTextX
:
string
;
hoverInfoTextY
:
string
;
hoverInfoTextComparisonXY
:
string
;
closestHoverPointPositionX
:
number
=
0
;
closestHoverPointPositionY
:
number
=
0
;
hoverStyles
:
any
=
{
marker
:
{
size
:
6
,
// size: [40, 60, 80, 100],
},
};
unHoverStyles
:
any
=
{
marker
:
{
size
:
1
,
},
};
globalSegmentSettings
:
any
=
{
type
:
'
scatter
'
,
mode
:
'
lines+markers
'
,
line
:
{
width
:
2
,
color
:
'
#4690df
'
,
},
marker
:
{
size
:
4
,
},
showlegend
:
false
,
hoverinfo
:
'
text
'
,
};
// segmentColors: string[] = ['#555', 'salmon', 'cadetblue', 'gold']; //TODO: add more colors from palette?
// TODO: theme colors array for intra-Plotly styles
responseData
=
[
{
x
:
[
'
08/30
'
,
'
08/31
'
,
'
09/01
'
,
'
09/02
'
,
'
09/03
'
],
y
:
[
4
,
9
,
16
,
17
,
15
],
type
:
'
scatter
'
,
mode
:
'
lines+markers
'
,
line
:
{
color
:
'
#4690df
'
,
width
:
2
,
},
marker
:
{
size
:
1
,
},
showlegend
:
false
,
hovertemplate
:
'
Fri Aug 30th 2019<br>
'
+
'
<b class="test">750 Active Users</b><br>
'
+
'
<span>vs 450 Fri August 23rd</span>
'
+
'
<extra></extra>
'
,
...
this
.
globalSegmentSettings
,
x
:
this
.
x1
,
y
:
this
.
y1
,
},
{
x
:
[
'
08/30
'
,
'
08/31
'
,
'
09/01
'
,
'
09/02
'
,
'
09/03
'
],
y
:
[
3
,
7
,
14
,
18
,
16
],
type
:
'
scatter
'
,
mode
:
'
line
'
,
line
:
{
color
:
'
#ccc
'
,
width
:
2
,
dash
:
'
dot
'
,
},
marker
:
{
size
:
1
,
},
showlegend
:
false
,
hovertemplate
:
'
<extra></extra>
'
,
...
this
.
globalSegmentSettings
,
line
:
{
...
this
.
globalSegmentSettings
,
color
:
'
#ccc
'
,
dash
:
'
dot
'
},
x
:
this
.
x1
,
y
:
this
.
y2
,
hoverinfo
:
'
none
'
,
// nothing is displayed but event still fires
},
];
// *******************************************
// *******************************************
****************************************
// layout: Layout = {
layout
:
any
=
{
width
:
0
,
height
:
0
,
title
:
''
,
hovermode
:
'
closest
'
,
// or False, for historical line
hoverlabel
:
{
bgcolor
:
'
#eee
'
},
// title: '',
hovermode
:
'
closest
'
,
paper_bgcolor
:
'
white
'
,
plot_bgcolor
:
'
white
'
,
font
:
{
family
:
'
Roboto
'
,
},
titlefont
:
{
family
:
'
Roboto
'
,
size
:
24
,
weight
:
'
bold
'
,
},
// titlefont: {
// family: 'Roboto',
// size: 24,
// },
xaxis
:
{
// dtick: 1, //comparison_interval(1, 7, 28, etc.)
automargin
:
true
,
// automargin: true,
tickangle
:
-
45
,
tickfont
:
{
color
:
'
#ccc
'
,
},
// zeroline: false,
showgrid
:
false
,
// gridcolor: 'white' // instead of false?
},
yaxis
:
{
automargin
:
true
,
//
automargin: true,
ticks
:
''
,
showgrid
:
true
,
zeroline
:
true
,
zerolinecolor
:
'
#666
'
,
showticklabels
:
false
,
zerolinecolor
:
'
#222
'
,
// showticklabels: false,
side
:
'
right
'
,
tickfont
:
{
color
:
'
#ccc
'
,
},
},
margin
:
{
t
:
16
,
...
...
@@ -111,26 +145,103 @@ export class AnalyticsChartComponent implements OnInit {
},
};
// *******************************************
@
ViewChild
(
'
chartContainer
'
,
{
static
:
true
})
chartContainer
:
ElementRef
;
// ***********************************************************************************
constructor
(
private
analyticsService
:
AnalyticsDashboardService
)
{}
constructor
(
private
analyticsService
:
AnalyticsDashboardService
,
private
themeService
:
ThemeService
,
protected
cd
:
ChangeDetectorRef
)
{}
ngOnInit
()
{
this
.
applyDimensions
();
this
.
analyticsPlot
=
document
.
getElementById
(
'
chartContainer
'
);
// TODO: make sure these outliers end up with proper m- prefix
const
hoverInfo
=
document
.
getElementById
(
'
hoverInfo
'
);
const
hoverInfoX
=
document
.
getElementById
(
'
hoverInfo__x
'
);
// Date
const
hoverInfoY
=
document
.
getElementById
(
'
hoverInfo__y
'
);
// Value
const
hoverInfoComparisonXy
=
document
.
getElementById
(
'
hoverInfo__comparisonXy
'
);
Plotly
.
plot
(
'
chartContainer
'
,
this
.
responseData
,
this
.
layout
,
{
displayModeBar
:
false
,
});
// ** HOVER *******************************************************
this
.
analyticsPlot
.
on
(
'
plotly_hover
'
,
function
(
eventData
)
{
hoverInfo
.
style
.
display
=
'
block
'
;
Plotly
.
restyle
(
this
.
analyticsPlot
,
this
.
hoverStyles
,
0
);
this
.
hoverInfoXText
=
eventData
.
points
.
map
(
function
(
d
)
{
return
''
+
d
.
x
;
});
this
.
hoverInfoYText
=
eventData
.
points
.
map
(
function
(
d
)
{
return
d
.
y
.
toPrecision
(
3
)
+
'
borks
'
;
});
this
.
hoverInfoComparisonXyText
=
eventData
.
points
.
map
(
function
(
d
)
{
// TODO: how best to connect current with comparison segment data
return
'
vs 700 Tues Oct 1st
'
;
});
console
.
log
(
eventData
);
console
.
log
(
eventData
.
points
[
0
].
data
.
marker
.
size
);
eventData
.
points
[
0
].
data
.
marker
.
size
=
4
;
console
.
log
(
eventData
.
points
[
0
].
data
.
marker
.
size
);
const
xaxis
=
eventData
.
points
[
0
].
xaxis
,
yaxis
=
eventData
.
points
[
0
].
yaxis
;
eventData
.
points
.
forEach
(
function
(
p
)
{
// note: 'l2p' means 'linear to pixel'
console
.
log
(
'
pixel position
'
,
xaxis
.
l2p
(
p
.
x
),
yaxis
.
l2p
(
p
.
y
));
console
.
log
(
'
pixel position
'
,
xaxis
.
l2p
(
p
.
x
),
yaxis
.
l2p
(
p
.
y
));
this
.
closestHoverPointPositionX
=
xaxis
.
l2p
(
p
.
x
);
this
.
closestHoverPointPositionY
=
yaxis
.
l2p
(
p
.
x
);
});
hoverInfoX
.
textContent
=
this
.
hoverInfoXText
.
join
();
hoverInfoY
.
textContent
=
this
.
hoverInfoYText
.
join
();
hoverInfoComparisonXy
.
textContent
=
this
.
hoverInfoComparisonXyText
.
join
();
})
// ** UNHOVER *******************************************************
.
on
(
'
plotly_unhover
'
,
function
(
eventData
)
{
hoverInfo
.
style
.
display
=
'
none
'
;
Plotly
.
restyle
(
this
.
analyticsPlot
,
this
.
unHoverStyles
,
0
);
// eventData.xaxes[0].showline = true;
// eventData.yaxes[0].showline = true;
console
.
log
(
eventData
);
// this.hoverInfoX.textContent = '';
// this.hoverInfoY.textContent = '';
// this.hoverInfoComparisonXy.textContent = '';
});
this
.
themeService
.
isDark$
.
subscribe
(
isDark
=>
(
this
.
isDark
=
isDark
));
}
// TODO: reimplement?
// @HostListener('window:resize')
// applyDimensions() {
// this.layout = {
// ...this.layout,
// width: this.chartContainer.nativeElement.clientWidth,
// height: this.chartContainer.nativeElement.clientHeight - 35,
// };
// }
// this.visualisation = this.response.metrics.find(
// metric => metric.id === this.vm$.metric
// ).visualisation;
detectChanges
()
{
this
.
cd
.
markForCheck
();
this
.
cd
.
detectChanges
();
this
.
themeService
.
applyThemePreference
();
}
@
HostListener
(
'
window:resize
'
)
applyDimensions
()
{
this
.
layout
=
{
...
this
.
layout
,
width
:
this
.
chartContainer
.
nativeElement
.
clientWidth
,
height
:
this
.
chartContainer
.
nativeElement
.
clientHeight
-
35
,
};
ngOnDestroy
()
{
this
.
themeSubscription
.
unsubscribe
();
}
}
This diff is collapsed.
Click to expand it.
src/app/modules/analytics/v2/dashboard.component.html
View file @
0f7f70cb
<div
class=
"page"
*ngIf=
"vm$ | async as vm"
>
<div
class=
"page"
*ngIf=
"vm$ | async as vm"
[ngClass]=
"{ isMobile: isMobile }"
>
<section
class=
"sidebar"
>
<h3>
Analytics
</h3>
<div
class=
"catContainer"
>
...
...
@@ -7,9 +7,9 @@
{{ selectedCat.label }}
</div>
<div
class=
"cat"
*ngFor=
"let cat of cats"
>
<
!-- <
span [ngClass]="{ selected: cat.id === selectedCat.id }">{{
vm$.category
.label
}}</span>
-->
<span
[ngClass]=
"{ selected: cat.id === selectedCat.id }"
>
{{
cat
.label
}}
</span>
</div>
</div>
</section>
...
...
@@ -35,15 +35,14 @@
</div>
<m-analytics
__layout--chart
class=
"m-analytics__layout"
*ngIf=
"selectedCat.type === 'chart'"
></m-analytics
__layout--chart
>
<m-analytics
__layout--table
<
!-- <
m-analytics__layout--table
class="m-analytics__layout"
*ngIf="selectedCat.type === 'table'"
></m-analytics__layout--table>
<m-analytics__layout--summary
class="m-analytics__layout"
*ngIf="selectedCat.type === 'summary'"
></m-analytics
__layout--summary
>
></m-analytics__layout--summary>
-->
</section>
</div>
This diff is collapsed.
Click to expand it.
src/app/modules/analytics/v2/dashboard.component.ts
View file @
0f7f70cb
...
...
@@ -48,8 +48,7 @@ export class AnalyticsDashboardComponent implements OnInit, OnDestroy {
label
:
'
timespan
'
,
options
:
[],
};
// vm$: Observable<UserState> = this.analyticsService.vm$;
vm$
=
this
.
analyticsService
.
vm$
;
vm$
:
Observable
<
UserState
>
=
this
.
analyticsService
.
vm$
;
constructor
(
public
client
:
Client
,
...
...
@@ -63,8 +62,8 @@ export class AnalyticsDashboardComponent implements OnInit, OnDestroy {
this
.
isMobile
=
isMobileOrTablet
();
this
.
title
.
setTitle
(
'
Analytics
'
);
console
.
log
(
this
.
route
);
console
.
log
(
this
.
route
.
snapshot
.
url
);
//
console.log(this.route);
//
console.log(this.route.snapshot.url);
// TODO: implement channel filter
// const {channelGuid} = this.analyticsService.getStateSnapshot();
...
...
@@ -81,7 +80,7 @@ export class AnalyticsDashboardComponent implements OnInit, OnDestroy {
// TODO: something similar for category
this
.
selectedCat
=
this
.
cats
.
find
(
// cat => cat.id === this.vm$.category
;
// cat => cat.id === this.vm$.category
cat
=>
cat
.
id
===
'
traffic
'
);
});
...
...
This diff is collapsed.
Click to expand it.