diff options
author | Rigel Kent <sendmemail@rigelk.eu> | 2020-03-30 12:06:46 +0200 |
---|---|---|
committer | Chocobozzz <chocobozzz@cpy.re> | 2020-03-31 10:29:24 +0200 |
commit | 3d527ba173a37bd61ec8ad742642bb320d12995c (patch) | |
tree | 4b2890df00b64ff6cdcf96afb652af8abcac3ff5 /client | |
parent | 714bfcc556177dce2b65a1e58babdf2488e9de13 (diff) | |
download | PeerTube-3d527ba173a37bd61ec8ad742642bb320d12995c.tar.gz PeerTube-3d527ba173a37bd61ec8ad742642bb320d12995c.tar.zst PeerTube-3d527ba173a37bd61ec8ad742642bb320d12995c.zip |
Use inner join and document code for viewr stats for channels
Diffstat (limited to 'client')
5 files changed, 33 insertions, 9 deletions
diff --git a/client/package.json b/client/package.json index c6a5fa1bb..52647ce1d 100644 --- a/client/package.json +++ b/client/package.json | |||
@@ -56,6 +56,7 @@ | |||
56 | "@ngx-loading-bar/router": "^4.2.0", | 56 | "@ngx-loading-bar/router": "^4.2.0", |
57 | "@ngx-meta/core": "^8.0.2", | 57 | "@ngx-meta/core": "^8.0.2", |
58 | "@ngx-translate/i18n-polyfill": "^1.0.0", | 58 | "@ngx-translate/i18n-polyfill": "^1.0.0", |
59 | "@types/chart.js": "^2.9.16", | ||
59 | "@types/core-js": "^2.5.2", | 60 | "@types/core-js": "^2.5.2", |
60 | "@types/debug": "^4.1.5", | 61 | "@types/debug": "^4.1.5", |
61 | "@types/hls.js": "^0.12.4", | 62 | "@types/hls.js": "^0.12.4", |
diff --git a/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.html b/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.html index 94e74938b..03d45227e 100644 --- a/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.html +++ b/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.html | |||
@@ -20,7 +20,7 @@ | |||
20 | <div i18n class="video-channel-followers">{videoChannel.followersCount, plural, =1 {1 subscriber} other {{{ videoChannel.followersCount }} subscribers}}</div> | 20 | <div i18n class="video-channel-followers">{videoChannel.followersCount, plural, =1 {1 subscriber} other {{{ videoChannel.followersCount }} subscribers}}</div> |
21 | 21 | ||
22 | <div *ngIf="!isInSmallView" class="w-100 d-flex justify-content-end"> | 22 | <div *ngIf="!isInSmallView" class="w-100 d-flex justify-content-end"> |
23 | <p-chart *ngIf="videoChannelsData && videoChannelsData[i]" type="line" [data]="videoChannelsData[i]" [options]="chartOptions" width="40vw" height="100px"></p-chart> | 23 | <p-chart *ngIf="videoChannelsChartData && videoChannelsChartData[i]" type="line" [data]="videoChannelsChartData[i]" [options]="chartOptions" width="40vw" height="100px"></p-chart> |
24 | </div> | 24 | </div> |
25 | </div> | 25 | </div> |
26 | 26 | ||
diff --git a/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.ts b/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.ts index 27a157621..153fc0127 100644 --- a/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.ts +++ b/client/src/app/+my-account/my-account-video-channels/my-account-video-channels.component.ts | |||
@@ -8,7 +8,8 @@ import { ScreenService } from '@app/shared/misc/screen.service' | |||
8 | import { User } from '@app/shared' | 8 | import { User } from '@app/shared' |
9 | import { flatMap } from 'rxjs/operators' | 9 | import { flatMap } from 'rxjs/operators' |
10 | import { I18n } from '@ngx-translate/i18n-polyfill' | 10 | import { I18n } from '@ngx-translate/i18n-polyfill' |
11 | import { minBy, maxBy } from 'lodash-es' | 11 | import { min, minBy, max, maxBy } from 'lodash-es' |
12 | import { ChartData } from 'chart.js' | ||
12 | 13 | ||
13 | @Component({ | 14 | @Component({ |
14 | selector: 'my-account-video-channels', | 15 | selector: 'my-account-video-channels', |
@@ -17,7 +18,7 @@ import { minBy, maxBy } from 'lodash-es' | |||
17 | }) | 18 | }) |
18 | export class MyAccountVideoChannelsComponent implements OnInit { | 19 | export class MyAccountVideoChannelsComponent implements OnInit { |
19 | videoChannels: VideoChannel[] = [] | 20 | videoChannels: VideoChannel[] = [] |
20 | videoChannelsData: any[] | 21 | videoChannelsChartData: ChartData[] |
21 | videoChannelsMinimumDailyViews = 0 | 22 | videoChannelsMinimumDailyViews = 0 |
22 | videoChannelsMaximumDailyViews: number | 23 | videoChannelsMaximumDailyViews: number |
23 | 24 | ||
@@ -125,7 +126,9 @@ export class MyAccountVideoChannelsComponent implements OnInit { | |||
125 | .pipe(flatMap(() => this.videoChannelService.listAccountVideoChannels(this.user.account, null, true))) | 126 | .pipe(flatMap(() => this.videoChannelService.listAccountVideoChannels(this.user.account, null, true))) |
126 | .subscribe(res => { | 127 | .subscribe(res => { |
127 | this.videoChannels = res.data | 128 | this.videoChannels = res.data |
128 | this.videoChannelsData = this.videoChannels.map(v => ({ | 129 | |
130 | // chart data | ||
131 | this.videoChannelsChartData = this.videoChannels.map(v => ({ | ||
129 | labels: v.viewsPerDay.map(day => day.date.toLocaleDateString()), | 132 | labels: v.viewsPerDay.map(day => day.date.toLocaleDateString()), |
130 | datasets: [ | 133 | datasets: [ |
131 | { | 134 | { |
@@ -135,9 +138,22 @@ export class MyAccountVideoChannelsComponent implements OnInit { | |||
135 | borderColor: "#c6c6c6" | 138 | borderColor: "#c6c6c6" |
136 | } | 139 | } |
137 | ] | 140 | ] |
138 | })) | 141 | } as ChartData)) |
139 | this.videoChannelsMinimumDailyViews = minBy(this.videoChannels.map(v => minBy(v.viewsPerDay, day => day.views)), day => day.views).views | 142 | |
140 | this.videoChannelsMaximumDailyViews = maxBy(this.videoChannels.map(v => maxBy(v.viewsPerDay, day => day.views)), day => day.views).views | 143 | // chart options that depend on chart data: |
144 | // we don't want to skew values and have min at 0, so we define what the floor/ceiling is here | ||
145 | this.videoChannelsMinimumDailyViews = min( | ||
146 | this.videoChannels.map(v => minBy( // compute local minimum daily views for each channel, by their "views" attribute | ||
147 | v.viewsPerDay, | ||
148 | day => day.views | ||
149 | ).views) // the object returned is a ViewPerDate, so we still need to get the views attribute | ||
150 | ) | ||
151 | this.videoChannelsMaximumDailyViews = max( | ||
152 | this.videoChannels.map(v => maxBy( // compute local maximum daily views for each channel, by their "views" attribute | ||
153 | v.viewsPerDay, | ||
154 | day => day.views | ||
155 | ).views) // the object returned is a ViewPerDate, so we still need to get the views attribute | ||
156 | ) | ||
141 | }) | 157 | }) |
142 | } | 158 | } |
143 | } | 159 | } |
diff --git a/client/src/app/shared/video-channel/video-channel.model.ts b/client/src/app/shared/video-channel/video-channel.model.ts index c93af0ca5..617d6d44d 100644 --- a/client/src/app/shared/video-channel/video-channel.model.ts +++ b/client/src/app/shared/video-channel/video-channel.model.ts | |||
@@ -1,4 +1,4 @@ | |||
1 | import { VideoChannel as ServerVideoChannel, viewsPerTime } from '../../../../../shared/models/videos' | 1 | import { VideoChannel as ServerVideoChannel, ViewsPerDate } from '../../../../../shared/models/videos' |
2 | import { Actor } from '../actor/actor.model' | 2 | import { Actor } from '../actor/actor.model' |
3 | import { Account } from '../../../../../shared/models/actors' | 3 | import { Account } from '../../../../../shared/models/actors' |
4 | 4 | ||
@@ -12,7 +12,7 @@ export class VideoChannel extends Actor implements ServerVideoChannel { | |||
12 | ownerAccount?: Account | 12 | ownerAccount?: Account |
13 | ownerBy?: string | 13 | ownerBy?: string |
14 | ownerAvatarUrl?: string | 14 | ownerAvatarUrl?: string |
15 | viewsPerDay?: viewsPerTime[] | 15 | viewsPerDay?: ViewsPerDate[] |
16 | 16 | ||
17 | constructor (hash: ServerVideoChannel) { | 17 | constructor (hash: ServerVideoChannel) { |
18 | super(hash) | 18 | super(hash) |
diff --git a/client/yarn.lock b/client/yarn.lock index b3f38a664..e34da3d6e 100644 --- a/client/yarn.lock +++ b/client/yarn.lock | |||
@@ -1149,6 +1149,13 @@ | |||
1149 | dependencies: | 1149 | dependencies: |
1150 | "@types/node" "*" | 1150 | "@types/node" "*" |
1151 | 1151 | ||
1152 | "@types/chart.js@^2.9.16": | ||
1153 | version "2.9.16" | ||
1154 | resolved "https://registry.yarnpkg.com/@types/chart.js/-/chart.js-2.9.16.tgz#ac9d268fa192c0ec0efd740f802683e3ed97642c" | ||
1155 | integrity sha512-Mofg7xFIeAWME46YMVKHPCyUz2Z0KsVMNE1f4oF3T74mK3RiPQxOm9qzoeNTyMs6lpl4x0tiHL+Wsz2DHCxQlQ== | ||
1156 | dependencies: | ||
1157 | moment "^2.10.2" | ||
1158 | |||
1152 | "@types/core-js@^2.5.2": | 1159 | "@types/core-js@^2.5.2": |
1153 | version "2.5.2" | 1160 | version "2.5.2" |
1154 | resolved "https://registry.yarnpkg.com/@types/core-js/-/core-js-2.5.2.tgz#d4c25420044d4a5b65e00a82fc04b7824b62691f" | 1161 | resolved "https://registry.yarnpkg.com/@types/core-js/-/core-js-2.5.2.tgz#d4c25420044d4a5b65e00a82fc04b7824b62691f" |