time series, artist breakdown, start and end date
This commit is contained in:
parent
079e126648
commit
a1bd1ab62d
@ -22,19 +22,37 @@
|
|||||||
:track="lastfmTrack"
|
:track="lastfmTrack"
|
||||||
:username="playCount.username"
|
:username="playCount.username"
|
||||||
v-if="playCount !== null && playCount !== undefined"></play-count-card>
|
v-if="playCount !== null && playCount !== undefined"></play-count-card>
|
||||||
|
|
||||||
|
<info-card v-for="card in cards" :html="card.content"></info-card>
|
||||||
|
|
||||||
|
<artist-breakdown :play_count="playCount"
|
||||||
|
v-if="playCount !== null && playCount !== undefined"></artist-breakdown>
|
||||||
|
|
||||||
|
<play-count-chart-card-comb :data_points="combinedData"
|
||||||
|
:chart_id="'combined'"
|
||||||
|
:earliest_date="earliestDate"
|
||||||
|
v-if="showArtistChart"></play-count-chart-card-comb>
|
||||||
<play-count-chart-card :data_points="playCount.trackCountData"
|
<play-count-chart-card :data_points="playCount.trackCountData"
|
||||||
:title="currentlyPlaying.track.name"
|
:title="trackGraphTitle"
|
||||||
:chart_id="'track'"
|
:chart_id="'track'"
|
||||||
|
:earliest_date="earliestDate"
|
||||||
|
:latest_date="latestDate"
|
||||||
|
:colour="'#7a99c2'"
|
||||||
v-if="showTrackChart"></play-count-chart-card>
|
v-if="showTrackChart"></play-count-chart-card>
|
||||||
<play-count-chart-card :data_points="playCount.albumCountData"
|
<play-count-chart-card :data_points="playCount.albumCountData"
|
||||||
:title="currentlyPlaying.track.album.name"
|
:title="albumGraphTitle"
|
||||||
:chart_id="'album'"
|
:chart_id="'album'"
|
||||||
|
:earliest_date="earliestDate"
|
||||||
|
:latest_date="latestDate"
|
||||||
|
:colour="'#a34c77'"
|
||||||
v-if="showAlbumChart"></play-count-chart-card>
|
v-if="showAlbumChart"></play-count-chart-card>
|
||||||
<play-count-chart-card :data_points="playCount.artistCountData"
|
<play-count-chart-card :data_points="playCount.artistCountData"
|
||||||
:title="lastfmArtist"
|
:title="artistGraphTitle"
|
||||||
:chart_id="'artist'"
|
:chart_id="'artist'"
|
||||||
|
:earliest_date="earliestDate"
|
||||||
|
:latest_date="latestDate"
|
||||||
|
:colour="'#598556'"
|
||||||
v-if="showArtistChart"></play-count-chart-card>
|
v-if="showArtistChart"></play-count-chart-card>
|
||||||
<info-card v-for="card in cards" :html="card.content"></info-card>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -9,6 +9,11 @@
|
|||||||
"Selector": {
|
"Selector": {
|
||||||
"Redis": {
|
"Redis": {
|
||||||
"enabled": true
|
"enabled": true
|
||||||
|
},
|
||||||
|
"Now": {
|
||||||
|
"ArtistResampleWindow": "14.00:00:00",
|
||||||
|
"AlbumResampleWindow": "14.00:00:00",
|
||||||
|
"TrackResampleWindow": "14.00:00:00"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"AllowedHosts": "*"
|
"AllowedHosts": "*"
|
||||||
|
43
Selector.Web/package-lock.json
generated
43
Selector.Web/package-lock.json
generated
@ -12,9 +12,12 @@
|
|||||||
"@microsoft/signalr": "^6.0.0",
|
"@microsoft/signalr": "^6.0.0",
|
||||||
"bootstrap": "^5.1.3",
|
"bootstrap": "^5.1.3",
|
||||||
"chart.js": "^3.6.0",
|
"chart.js": "^3.6.0",
|
||||||
|
"chartjs-adapter-luxon": "^1.1.0",
|
||||||
|
"luxon": "^2.4.0",
|
||||||
"vue": "^3.2.22"
|
"vue": "^3.2.22"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/luxon": "^2.3.2",
|
||||||
"clean-webpack-plugin": "^4.0.0",
|
"clean-webpack-plugin": "^4.0.0",
|
||||||
"file-loader": "^6.2.0",
|
"file-loader": "^6.2.0",
|
||||||
"sass": "^1.44.0",
|
"sass": "^1.44.0",
|
||||||
@ -111,6 +114,12 @@
|
|||||||
"integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==",
|
"integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/luxon": {
|
||||||
|
"version": "2.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-2.3.2.tgz",
|
||||||
|
"integrity": "sha512-WOehptuhKIXukSUUkRgGbj2c997Uv/iUgYgII8U7XLJqq9W2oF0kQ6frEznRQbdurioz+L/cdaIm4GutTQfgmA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/@types/minimatch": {
|
"node_modules/@types/minimatch": {
|
||||||
"version": "3.0.5",
|
"version": "3.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz",
|
||||||
@ -707,6 +716,15 @@
|
|||||||
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.6.2.tgz",
|
||||||
"integrity": "sha512-Xz7f/fgtVltfQYWq0zL1Xbv7N2inpG+B54p3D5FSvpCdy3sM+oZhbqa42eNuYXltaVvajgX5UpKCU2GeeJIgxg=="
|
"integrity": "sha512-Xz7f/fgtVltfQYWq0zL1Xbv7N2inpG+B54p3D5FSvpCdy3sM+oZhbqa42eNuYXltaVvajgX5UpKCU2GeeJIgxg=="
|
||||||
},
|
},
|
||||||
|
"node_modules/chartjs-adapter-luxon": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/chartjs-adapter-luxon/-/chartjs-adapter-luxon-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-CS+xBWEyXYVLBZ3dSY/MwlSXhz8er4JjkApazY84ft/++oOLsmkt6TaXBCsUFudum7QdoYmpxiL/gSp20+emkw==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"chart.js": "^3.0.0",
|
||||||
|
"luxon": "^1.0.0 || ^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/chokidar": {
|
"node_modules/chokidar": {
|
||||||
"version": "3.5.2",
|
"version": "3.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz",
|
||||||
@ -1568,6 +1586,14 @@
|
|||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/luxon": {
|
||||||
|
"version": "2.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/luxon/-/luxon-2.4.0.tgz",
|
||||||
|
"integrity": "sha512-w+NAwWOUL5hO0SgwOHsMBAmZ15SoknmQXhSO0hIbJCAmPKSsGeK8MlmhYh2w6Iib38IxN2M+/ooXWLbeis7GuA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/magic-string": {
|
"node_modules/magic-string": {
|
||||||
"version": "0.25.7",
|
"version": "0.25.7",
|
||||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",
|
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",
|
||||||
@ -2879,6 +2905,12 @@
|
|||||||
"integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==",
|
"integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"@types/luxon": {
|
||||||
|
"version": "2.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-2.3.2.tgz",
|
||||||
|
"integrity": "sha512-WOehptuhKIXukSUUkRgGbj2c997Uv/iUgYgII8U7XLJqq9W2oF0kQ6frEznRQbdurioz+L/cdaIm4GutTQfgmA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"@types/minimatch": {
|
"@types/minimatch": {
|
||||||
"version": "3.0.5",
|
"version": "3.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz",
|
||||||
@ -3385,6 +3417,12 @@
|
|||||||
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.6.2.tgz",
|
||||||
"integrity": "sha512-Xz7f/fgtVltfQYWq0zL1Xbv7N2inpG+B54p3D5FSvpCdy3sM+oZhbqa42eNuYXltaVvajgX5UpKCU2GeeJIgxg=="
|
"integrity": "sha512-Xz7f/fgtVltfQYWq0zL1Xbv7N2inpG+B54p3D5FSvpCdy3sM+oZhbqa42eNuYXltaVvajgX5UpKCU2GeeJIgxg=="
|
||||||
},
|
},
|
||||||
|
"chartjs-adapter-luxon": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/chartjs-adapter-luxon/-/chartjs-adapter-luxon-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-CS+xBWEyXYVLBZ3dSY/MwlSXhz8er4JjkApazY84ft/++oOLsmkt6TaXBCsUFudum7QdoYmpxiL/gSp20+emkw==",
|
||||||
|
"requires": {}
|
||||||
|
},
|
||||||
"chokidar": {
|
"chokidar": {
|
||||||
"version": "3.5.2",
|
"version": "3.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz",
|
||||||
@ -4026,6 +4064,11 @@
|
|||||||
"yallist": "^4.0.0"
|
"yallist": "^4.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"luxon": {
|
||||||
|
"version": "2.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/luxon/-/luxon-2.4.0.tgz",
|
||||||
|
"integrity": "sha512-w+NAwWOUL5hO0SgwOHsMBAmZ15SoknmQXhSO0hIbJCAmPKSsGeK8MlmhYh2w6Iib38IxN2M+/ooXWLbeis7GuA=="
|
||||||
|
},
|
||||||
"magic-string": {
|
"magic-string": {
|
||||||
"version": "0.25.7",
|
"version": "0.25.7",
|
||||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",
|
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",
|
||||||
|
@ -23,9 +23,12 @@
|
|||||||
"@microsoft/signalr": "^6.0.0",
|
"@microsoft/signalr": "^6.0.0",
|
||||||
"bootstrap": "^5.1.3",
|
"bootstrap": "^5.1.3",
|
||||||
"chart.js": "^3.6.0",
|
"chart.js": "^3.6.0",
|
||||||
|
"chartjs-adapter-luxon": "^1.1.0",
|
||||||
|
"luxon": "^2.4.0",
|
||||||
"vue": "^3.2.22"
|
"vue": "^3.2.22"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/luxon": "^2.3.2",
|
||||||
"clean-webpack-plugin": "^4.0.0",
|
"clean-webpack-plugin": "^4.0.0",
|
||||||
"file-loader": "^6.2.0",
|
"file-loader": "^6.2.0",
|
||||||
"sass": "^1.44.0",
|
"sass": "^1.44.0",
|
||||||
|
71
Selector.Web/scripts/Now/ArtistBreakdownGraph.ts
Normal file
71
Selector.Web/scripts/Now/ArtistBreakdownGraph.ts
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
import * as Vue from "vue";
|
||||||
|
import { Chart, DoughnutController, ArcElement } from "chart.js";
|
||||||
|
import { PlayCount } from "scripts/HubInterfaces";
|
||||||
|
|
||||||
|
Chart.register(DoughnutController, ArcElement);
|
||||||
|
|
||||||
|
const pieColours = ['#7a99c2',
|
||||||
|
'#a34c77',
|
||||||
|
'#598556',
|
||||||
|
];
|
||||||
|
|
||||||
|
export let ArtistBreakdownChartCard: Vue.Component = {
|
||||||
|
props: ['play_count'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
trackPercent() {
|
||||||
|
return this.play_count.track * 100 / this.play_count.artist
|
||||||
|
},
|
||||||
|
albumPercent() {
|
||||||
|
return this.play_count.album * 100 / this.play_count.artist
|
||||||
|
},
|
||||||
|
albumDiff() {
|
||||||
|
return this.albumPercent - this.trackPercent;
|
||||||
|
},
|
||||||
|
artistPercent() {
|
||||||
|
return 100 - this.albumDiff + this.trackPercent;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
template:
|
||||||
|
`
|
||||||
|
<div class="card info-card">
|
||||||
|
<canvas id="artist-breakdown"></canvas>
|
||||||
|
<lastfm-logo />
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
mounted() {
|
||||||
|
new Chart(`artist-breakdown`, {
|
||||||
|
type: "doughnut",
|
||||||
|
data: {
|
||||||
|
labels: [ "track", "album", "artist" ],
|
||||||
|
datasets: [{
|
||||||
|
data: [ this.trackPercent, this.albumDiff, this.artistPercent ],
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
plugins: {
|
||||||
|
legend : {
|
||||||
|
display : true,
|
||||||
|
labels: {
|
||||||
|
color: 'white'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
layout: {
|
||||||
|
padding: 20
|
||||||
|
},
|
||||||
|
elements: {
|
||||||
|
arc : {
|
||||||
|
backgroundColor: pieColours,
|
||||||
|
borderWidth: 2,
|
||||||
|
borderColor: 'rgb(0, 0, 0)'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -1,24 +1,22 @@
|
|||||||
import * as Vue from "vue";
|
import * as Vue from "vue";
|
||||||
import { Chart, PointElement, LineElement, LineController, CategoryScale, LinearScale, TimeSeriesScale } from "chart.js";
|
import { Chart, PointElement, LineElement, LineController, CategoryScale, LinearScale, TimeSeriesScale } from "chart.js";
|
||||||
|
import 'chartjs-adapter-luxon';
|
||||||
import { CountSample } from "scripts/HubInterfaces";
|
import { CountSample } from "scripts/HubInterfaces";
|
||||||
|
import { ScrobbleDataSeries } from "scripts/now";
|
||||||
|
|
||||||
Chart.register(LineController, CategoryScale, LinearScale, TimeSeriesScale, PointElement, LineElement);
|
Chart.register(LineController, CategoryScale, LinearScale, TimeSeriesScale, PointElement, LineElement);
|
||||||
|
|
||||||
const months = ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"];
|
const months = ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"];
|
||||||
|
|
||||||
export let PlayCountChartCard: Vue.Component = {
|
export let PlayCountChartCard: Vue.Component = {
|
||||||
props: ['data_points', 'title', 'chart_id', 'link'],
|
props: ['data_points', 'title', 'chart_id', 'link', 'earliest_date', 'latest_date', 'colour'],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
chartData: {
|
chartData: {
|
||||||
labels: this.data_points.map((e: CountSample) => {
|
|
||||||
var date = new Date(e.timeStamp);
|
|
||||||
|
|
||||||
return `${months[date.getMonth()]} ${date.getFullYear()}`;
|
|
||||||
}),
|
|
||||||
datasets: [{
|
datasets: [{
|
||||||
// label: '# of Votes',
|
data: this.data_points.map((e: CountSample) => {
|
||||||
data: this.data_points.map((e: CountSample) => e.value),
|
return {x: e.timeStamp, y: e.value};
|
||||||
|
}),
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -43,25 +41,85 @@ export let PlayCountChartCard: Vue.Component = {
|
|||||||
options: {
|
options: {
|
||||||
elements: {
|
elements: {
|
||||||
line: {
|
line: {
|
||||||
borderWidth: 4,
|
borderWidth: 5,
|
||||||
borderColor: "#a34c77",
|
borderColor: this.colour,
|
||||||
backgroundColor: "#727272",
|
|
||||||
borderCapStyle: "round",
|
borderCapStyle: "round",
|
||||||
borderJoinStyle: "round"
|
borderJoinStyle: "round"
|
||||||
},
|
},
|
||||||
// point: {
|
point: {
|
||||||
// radius: 4,
|
radius: 0
|
||||||
// pointStyle: "circle",
|
}
|
||||||
// borderColor: "black",
|
|
||||||
// backgroundColor: "white"
|
|
||||||
// }
|
|
||||||
},
|
},
|
||||||
scales: {
|
scales: {
|
||||||
yAxis: {
|
yAxis: {
|
||||||
suggestedMin: 0
|
suggestedMin: 0
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'time',
|
||||||
|
min: this.earliest_date,
|
||||||
|
max: this.latest_date
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export let CombinedPlayCountChartCard: Vue.Component = {
|
||||||
|
props: ['data_points', 'title', 'chart_id', 'link', 'earliest_date'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
chartData: {
|
||||||
|
datasets: this.data_points.map((series: ScrobbleDataSeries) => {
|
||||||
|
return {
|
||||||
|
label: series.label,
|
||||||
|
borderColor: series.colour,
|
||||||
|
data: series.data.map((e: CountSample) => {
|
||||||
|
return {x: e.timeStamp, y: e.value};
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
chartId() {
|
||||||
|
return "play-count-chart-" + this.chart_id;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
template:
|
||||||
|
`
|
||||||
|
<div class="card info-card chart-card">
|
||||||
|
<canvas :id="chartId"></canvas>
|
||||||
|
<lastfm-logo :link="link" />
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
mounted() {
|
||||||
|
new Chart(`play-count-chart-${this.chart_id}`, {
|
||||||
|
type: "line",
|
||||||
|
data: this.chartData,
|
||||||
|
options: {
|
||||||
|
elements: {
|
||||||
|
line: {
|
||||||
|
borderWidth: 5,
|
||||||
|
borderColor: "#a34c77",
|
||||||
|
borderCapStyle: "round",
|
||||||
|
borderJoinStyle: "round"
|
||||||
|
},
|
||||||
|
point: {
|
||||||
|
radius: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
scales: {
|
||||||
|
yAxis: {
|
||||||
|
suggestedMin: 0
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'time',
|
||||||
|
min: this.earliest_date
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
import * as signalR from "@microsoft/signalr";
|
import * as signalR from "@microsoft/signalr";
|
||||||
import * as Vue from "vue";
|
import * as Vue from "vue";
|
||||||
import { TrackAudioFeatures, PlayCount, CurrentlyPlayingDTO } from "./HubInterfaces";
|
import { TrackAudioFeatures, PlayCount, CurrentlyPlayingDTO, CountSample } from "./HubInterfaces";
|
||||||
import NowPlayingCard from "./Now/NowPlayingCard";
|
import NowPlayingCard from "./Now/NowPlayingCard";
|
||||||
import { AudioFeatureCard, AudioFeatureChartCard, PopularityCard, SpotifyLogoLink } from "./Now/Spotify";
|
import { AudioFeatureCard, AudioFeatureChartCard, PopularityCard, SpotifyLogoLink } from "./Now/Spotify";
|
||||||
import { PlayCountChartCard } from "./Now/PlayCountGraph";
|
import { PlayCountChartCard, CombinedPlayCountChartCard } from "./Now/PlayCountGraph";
|
||||||
|
import { ArtistBreakdownChartCard } from "./Now/ArtistBreakdownGraph";
|
||||||
import { PlayCountCard, LastFmLogoLink } from "./Now/LastFm";
|
import { PlayCountCard, LastFmLogoLink } from "./Now/LastFm";
|
||||||
import BaseInfoCard from "./Now/BaseInfoCard";
|
import BaseInfoCard from "./Now/BaseInfoCard";
|
||||||
|
import { DateTime } from "luxon";
|
||||||
|
|
||||||
const connection = new signalR.HubConnectionBuilder()
|
const connection = new signalR.HubConnectionBuilder()
|
||||||
.withUrl("/hub")
|
.withUrl("/hub")
|
||||||
@ -28,6 +30,12 @@ interface NowPlaying {
|
|||||||
cards: InfoCard[]
|
cards: InfoCard[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ScrobbleDataSeries {
|
||||||
|
label: string,
|
||||||
|
colour: string,
|
||||||
|
data: CountSample[]
|
||||||
|
}
|
||||||
|
|
||||||
const app = Vue.createApp({
|
const app = Vue.createApp({
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -46,14 +54,6 @@ const app = Vue.createApp({
|
|||||||
album_artist: this.currentlyPlaying.track.album.artists[0].name,
|
album_artist: this.currentlyPlaying.track.album.artists[0].name,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
lastfmArtist(){
|
|
||||||
|
|
||||||
// if(this.currentlyPlaying.track.artists[0].length > 0)
|
|
||||||
{
|
|
||||||
return this.currentlyPlaying.track.artists[0].name;
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
},
|
|
||||||
showArtistChart(){
|
showArtistChart(){
|
||||||
return this.playCount !== null && this.playCount !== undefined && this.playCount.artistCountData.length > 3;
|
return this.playCount !== null && this.playCount !== undefined && this.playCount.artistCountData.length > 3;
|
||||||
},
|
},
|
||||||
@ -62,6 +62,33 @@ const app = Vue.createApp({
|
|||||||
},
|
},
|
||||||
showTrackChart(){
|
showTrackChart(){
|
||||||
return this.playCount !== null && this.playCount !== undefined && this.playCount.trackCountData.length > 3;
|
return this.playCount !== null && this.playCount !== undefined && this.playCount.trackCountData.length > 3;
|
||||||
|
},
|
||||||
|
earliestDate(){
|
||||||
|
return this.playCount.artistCountData[0].timeStamp;
|
||||||
|
},
|
||||||
|
latestDate(){
|
||||||
|
return this.playCount.artistCountData.at(-1).timeStamp;
|
||||||
|
},
|
||||||
|
trackGraphTitle() { return `${this.currentlyPlaying.track.name} 🎵`},
|
||||||
|
albumGraphTitle() { return `${this.currentlyPlaying.track.album.name} 💿`},
|
||||||
|
artistGraphTitle() { return `${this.currentlyPlaying.track.artists[0].name} 🎤`},
|
||||||
|
combinedData(){
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: "artist",
|
||||||
|
colour: "#598556",
|
||||||
|
data: this.playCount.artistCountData
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "album",
|
||||||
|
colour: "#a34c77",
|
||||||
|
data: this.playCount.albumCountData
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "track",
|
||||||
|
colour: "#7a99c2",
|
||||||
|
data: this.playCount.trackCountData
|
||||||
|
}];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
@ -123,4 +150,6 @@ app.component("spotify-logo", SpotifyLogoLink);
|
|||||||
app.component("lastfm-logo", LastFmLogoLink);
|
app.component("lastfm-logo", LastFmLogoLink);
|
||||||
app.component("play-count-card", PlayCountCard);
|
app.component("play-count-card", PlayCountCard);
|
||||||
app.component("play-count-chart-card", PlayCountChartCard);
|
app.component("play-count-chart-card", PlayCountChartCard);
|
||||||
|
app.component("play-count-chart-card-comb", CombinedPlayCountChartCard);
|
||||||
|
app.component("artist-breakdown", ArtistBreakdownChartCard);
|
||||||
const vm = app.mount('#app');
|
const vm = app.mount('#app');
|
@ -5,9 +5,9 @@ namespace Selector
|
|||||||
{
|
{
|
||||||
public const string Key = "Now";
|
public const string Key = "Now";
|
||||||
|
|
||||||
public TimeSpan ArtistResampleWindow { get; set; } = TimeSpan.FromDays(30);
|
public TimeSpan ArtistResampleWindow { get; set; } = TimeSpan.FromDays(7);
|
||||||
public TimeSpan AlbumResampleWindow { get; set; } = TimeSpan.FromDays(30);
|
public TimeSpan AlbumResampleWindow { get; set; } = TimeSpan.FromDays(7);
|
||||||
public TimeSpan TrackResampleWindow { get; set; } = TimeSpan.FromDays(30);
|
public TimeSpan TrackResampleWindow { get; set; } = TimeSpan.FromDays(7);
|
||||||
|
|
||||||
public TimeSpan ArtistDensityWindow { get; set; } = TimeSpan.FromDays(10);
|
public TimeSpan ArtistDensityWindow { get; set; } = TimeSpan.FromDays(10);
|
||||||
public decimal ArtistDensityThreshold { get; set; } = 5;
|
public decimal ArtistDensityThreshold { get; set; } = 5;
|
||||||
|
Loading…
Reference in New Issue
Block a user