split workout screen
Gitea Actions Demo / build_and_push (push) Failing after 47s
Details
Gitea Actions Demo / build_and_push (push) Failing after 47s
Details
This commit is contained in:
parent
d29c5b4dad
commit
2c221c50dd
|
|
@ -11,8 +11,8 @@ import axios from 'axios';
|
|||
import { AxiosResponse } from "axios";
|
||||
import { createYmaps } from 'vue-yandex-maps';
|
||||
|
||||
const HOST = "https://cycle-rider.ru";
|
||||
// const HOST = "http://localhost:8000";
|
||||
// const HOST = "https://cycle-rider.ru";
|
||||
const HOST = "http://localhost:8000";
|
||||
|
||||
axios.defaults.baseURL = HOST;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,34 +1,64 @@
|
|||
|
||||
<template>
|
||||
<h1 class="page-title">Tренировка</h1>
|
||||
<yandex-map
|
||||
v-model="map"
|
||||
:settings="{
|
||||
location: {
|
||||
center: mapCenter,
|
||||
zoom: 9,
|
||||
},
|
||||
}"
|
||||
width="100%"
|
||||
height="500px"
|
||||
>
|
||||
<yandex-map-default-scheme-layer/>
|
||||
<yandex-map-default-features-layer/>
|
||||
<yandex-map-feature
|
||||
:settings="{
|
||||
geometry: {
|
||||
type: 'LineString',
|
||||
coordinates: lineCoordinates,
|
||||
},
|
||||
style: {
|
||||
stroke: [{ color: '#007afce6', width: 4 }],
|
||||
},
|
||||
}"
|
||||
/>
|
||||
</yandex-map>
|
||||
<VaButton v-on:click="resetChartZoom()" preset="secondary" color="textPrimary" id="zoom-botton" ><VaZoomOut /></VaButton>
|
||||
<div id="workout-container">
|
||||
<div id="workout-map">
|
||||
<yandex-map v-model="map" :settings="{
|
||||
location: {
|
||||
center: mapCenter,
|
||||
zoom: 9,
|
||||
},
|
||||
}" width="100%" height="350px">
|
||||
<yandex-map-default-scheme-layer />
|
||||
<yandex-map-default-features-layer />
|
||||
<yandex-map-feature :settings="{
|
||||
geometry: {
|
||||
type: 'LineString',
|
||||
coordinates: lineCoordinates,
|
||||
},
|
||||
style: {
|
||||
stroke: [{ color: '#007afce6', width: 4 }],
|
||||
},
|
||||
}" />
|
||||
</yandex-map>
|
||||
</div>
|
||||
<div id="workout-short-data" v-if="workoutItem">
|
||||
<h3>{{ workoutItem.name }}</h3>
|
||||
<div class="workout-item-params" v-if="workoutItem.power">
|
||||
<div class="workout-item-params-name">Средняя мощность:</div>
|
||||
<div class="workout-item-params-value">{{ workoutItem.power }}</div>
|
||||
</div>
|
||||
<div class="workout-item-params" v-if="workoutItem.distantion">
|
||||
<div class="workout-item-params-name">Расстояние:</div>
|
||||
<div class="workout-item-params-value">{{ distConvert(workoutItem.distantion) }}</div>
|
||||
</div>
|
||||
<div class="workout-item-params" v-if="workoutItem.temperature">
|
||||
<div class="workout-item-params-name">Температура:</div>
|
||||
<div class="workout-item-params-value">{{ workoutItem.temperature }}</div>
|
||||
</div>
|
||||
<div class="workout-item-params" v-if="workoutItem.heart_rate">
|
||||
<div class="workout-item-params-name">Средний пульс:</div>
|
||||
<div class="workout-item-params-value">{{ workoutItem.heart_rate }}</div>
|
||||
</div>
|
||||
<div class="workout-item-params" v-if="workoutItem.heart_rate">
|
||||
<div class="workout-item-params-name">Максимальный пульс:</div>
|
||||
<div class="workout-item-params-value">{{ workoutItem.heart_rate }}</div>
|
||||
</div>
|
||||
<div class="workout-item-params" v-if="workoutItem.speed">
|
||||
<div class="workout-item-params-name">Средняя скорость:</div>
|
||||
<div class="workout-item-params-value">{{ speedConvert(workoutItem.speed) }}</div>
|
||||
</div>
|
||||
<div class="workout-item-params" v-if="workoutItem.speed">
|
||||
<div class="workout-item-params-name">Максимальная скорость:</div>
|
||||
<div class="workout-item-params-value">{{ speedConvert(workoutItem.speed || 0) }}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<VaButton v-on:click="resetChartZoom()" preset="secondary" color="textPrimary" id="zoom-botton">
|
||||
<VaZoomOut />
|
||||
</VaButton>
|
||||
<!-- @vue-ignore -->
|
||||
<LineWithLineChart id="chart" ref="chart" :options="chartOptions" :data="data" />
|
||||
<LineWithLineChart id="chart" ref="chart" :options="chartOptions" :data="data" />
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import VaZoomOut from "../../components/icons/VaZoomOut.vue";
|
||||
|
|
@ -40,21 +70,22 @@ import { AxiosResponse, AxiosInstance } from "axios";
|
|||
import { ref, inject, shallowRef } from 'vue'
|
||||
import { useToast } from "vuestic-ui/web-components";
|
||||
import zoomPlugin, { resetZoom } from 'chartjs-plugin-zoom';
|
||||
import {
|
||||
Chart as ChartJS,
|
||||
Title,
|
||||
Tooltip,
|
||||
import {
|
||||
Chart as ChartJS,
|
||||
Title,
|
||||
Tooltip,
|
||||
Legend,
|
||||
LineElement,
|
||||
LineElement,
|
||||
LinearScale,
|
||||
CategoryScale,
|
||||
LogarithmicScale,
|
||||
CategoryScale,
|
||||
LogarithmicScale,
|
||||
PointElement,
|
||||
TimeScale
|
||||
} from 'chart.js'
|
||||
import LineWithLineChart from './components/LineWithLineChart.js'
|
||||
import type { YMap } from '@yandex/ymaps3-types';
|
||||
import { YandexMap, YandexMapDefaultSchemeLayer, YandexMapFeature, YandexMapDefaultFeaturesLayer } from 'vue-yandex-maps';
|
||||
import { WorkoutItem, Attachment, secondsToDuration, distConvert, speedConvert } from "./Definitions.vue";
|
||||
|
||||
//Можно использовать для различных преобразований
|
||||
const map = shallowRef<null | YMap>(null);
|
||||
|
|
@ -62,12 +93,12 @@ const chart = ref();
|
|||
let mapCenter = ref<Array<number>>([37.617644, 55.755819]);
|
||||
let lineCoordinates = ref<Array<Array<number>>>([]);
|
||||
ChartJS.register(
|
||||
Title,
|
||||
Tooltip,
|
||||
Legend,
|
||||
LineElement,
|
||||
CategoryScale,
|
||||
LogarithmicScale,
|
||||
Title,
|
||||
Tooltip,
|
||||
Legend,
|
||||
LineElement,
|
||||
CategoryScale,
|
||||
LogarithmicScale,
|
||||
LinearScale,
|
||||
PointElement,
|
||||
zoomPlugin,
|
||||
|
|
@ -80,47 +111,26 @@ const route = useRoute()
|
|||
|
||||
type ChartDataset = {
|
||||
"radius": number,
|
||||
"label":string ,
|
||||
"backgroundColor":string ,
|
||||
"borderColor":string ,
|
||||
"data":Array<number> ,
|
||||
"label": string,
|
||||
"backgroundColor": string,
|
||||
"borderColor": string,
|
||||
"data": Array<number>,
|
||||
}
|
||||
type ChartData = {
|
||||
"labels":Array<string> ,
|
||||
"datasets":Array<ChartDataset> ,
|
||||
"labels": Array<string>,
|
||||
"datasets": Array<ChartDataset>,
|
||||
}
|
||||
type Attachment = {
|
||||
url: string;
|
||||
}
|
||||
type WorkoutItem = {
|
||||
id: string;
|
||||
name: string;
|
||||
created_by: string;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
description: string;
|
||||
cadence: number;
|
||||
heart_rate: number;
|
||||
temperature: number;
|
||||
speed: number;
|
||||
power: number;
|
||||
duraion_sec: number;
|
||||
distantion: number;
|
||||
attachment: Attachment;
|
||||
latitude: number;
|
||||
longitude: number;
|
||||
};
|
||||
let workoutItem = ref<WorkoutItem>();
|
||||
const data = ref<ChartData>({
|
||||
labels: [],
|
||||
datasets: [],
|
||||
})
|
||||
const chartOptions ={
|
||||
const chartOptions = {
|
||||
responsive: true,
|
||||
scales: {
|
||||
yAxes: {
|
||||
type: 'logarithmic',
|
||||
position: 'right',
|
||||
position: 'right',
|
||||
stacked: true,
|
||||
ticks: {
|
||||
beginAtZero: true
|
||||
|
|
@ -132,9 +142,9 @@ const chartOptions ={
|
|||
x: {
|
||||
type: 'time',
|
||||
time: {
|
||||
displayFormats: {hour: 'HH:mm'}
|
||||
displayFormats: { hour: 'HH:mm' }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
tooltip: {
|
||||
|
|
@ -143,22 +153,22 @@ const chartOptions ={
|
|||
footerMarginTop: 10,
|
||||
displayColors: false,
|
||||
callbacks: {
|
||||
label: function(context: any) {
|
||||
let label = context.dataset.label || '';
|
||||
label: function (context: any) {
|
||||
let label = context.dataset.label || '';
|
||||
|
||||
if (label) {
|
||||
label += ': ';
|
||||
}
|
||||
if (context.parsed.x !== null) {
|
||||
console.log(typeof context)
|
||||
label += new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(context.parsed.y);
|
||||
}
|
||||
return ["Скорость: " + data.value.datasets[0].data[context.dataIndex],
|
||||
"Пульс: " + data.value.datasets[1].data[context.dataIndex],
|
||||
"Мощность: " + data.value.datasets[2].data[context.dataIndex],
|
||||
];
|
||||
if (label) {
|
||||
label += ': ';
|
||||
}
|
||||
if (context.parsed.x !== null) {
|
||||
console.log(typeof context)
|
||||
label += new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(context.parsed.y);
|
||||
}
|
||||
return ["Скорость: " + data.value.datasets[0].data[context.dataIndex],
|
||||
"Пульс: " + data.value.datasets[1].data[context.dataIndex],
|
||||
"Мощность: " + data.value.datasets[2].data[context.dataIndex],
|
||||
];
|
||||
}
|
||||
}
|
||||
},
|
||||
zoom: {
|
||||
zoom: {
|
||||
|
|
@ -174,7 +184,7 @@ const chartOptions ={
|
|||
}
|
||||
}
|
||||
const msToKmh = (ms: number) => ms * 3.6;
|
||||
const axiosAuth= inject('axiosAuth') as AxiosInstance;
|
||||
const axiosAuth = inject('axiosAuth') as AxiosInstance;
|
||||
|
||||
const resetChartZoom = () => {
|
||||
resetZoom(chart.value.chart);
|
||||
|
|
@ -182,64 +192,91 @@ const resetChartZoom = () => {
|
|||
|
||||
const initWorkout = (id: string) => {
|
||||
axiosAuth
|
||||
.get(`/api/v0/workouts/${id}`)
|
||||
.then((response: AxiosResponse) => {
|
||||
workoutItem.value = response.data.workout;
|
||||
let latitude = [];
|
||||
let longitude = [];
|
||||
let times = [];
|
||||
let speed = [];
|
||||
let heart_rate = [];
|
||||
let power = [];
|
||||
for (let i in response.data.results) {
|
||||
response.data.results[i].lang;
|
||||
response.data.results[i].lang;
|
||||
times.push(response.data.results[i].time);
|
||||
speed.push(msToKmh(response.data.results[i].speed));
|
||||
power.push(response.data.results[i].power);
|
||||
heart_rate.push(response.data.results[i].heart_rate);
|
||||
latitude.push(response.data.results[i].latitude);
|
||||
longitude.push(response.data.results[i].longitude);
|
||||
lineCoordinates.value.push([response.data.results[i].longitude, response.data.results[i].latitude]);
|
||||
}
|
||||
console.log(lineCoordinates);
|
||||
mapCenter.value = [longitude[0], latitude[0]];
|
||||
data.value = {
|
||||
labels: times,
|
||||
datasets: [
|
||||
{radius: 0, label: 'Скорость', borderColor: '#00aa00', backgroundColor: '#00aa00',data: speed},
|
||||
{radius: 0, label: 'Пульс',borderColor: '#990000', backgroundColor: '#990000', data: heart_rate,},
|
||||
{radius: 0, label: 'Мощность', borderColor: '#cccccc', backgroundColor: '#cccccc', data: power,},
|
||||
]
|
||||
.get(`/api/v0/workouts/${id}`)
|
||||
.then((response: AxiosResponse) => {
|
||||
workoutItem.value = response.data.workout;
|
||||
let latitude = [];
|
||||
let longitude = [];
|
||||
let times = [];
|
||||
let speed = [];
|
||||
let heart_rate = [];
|
||||
let power = [];
|
||||
for (let i in response.data.results) {
|
||||
response.data.results[i].lang;
|
||||
response.data.results[i].lang;
|
||||
times.push(response.data.results[i].time);
|
||||
speed.push(msToKmh(response.data.results[i].speed));
|
||||
power.push(response.data.results[i].power);
|
||||
heart_rate.push(response.data.results[i].heart_rate);
|
||||
latitude.push(response.data.results[i].latitude);
|
||||
longitude.push(response.data.results[i].longitude);
|
||||
lineCoordinates.value.push([response.data.results[i].longitude, response.data.results[i].latitude]);
|
||||
}
|
||||
console.log(lineCoordinates);
|
||||
mapCenter.value = [longitude[0], latitude[0]];
|
||||
data.value = {
|
||||
labels: times,
|
||||
datasets: [
|
||||
{ radius: 0, label: 'Скорость', borderColor: '#00aa00', backgroundColor: '#00aa00', data: speed },
|
||||
{ radius: 0, label: 'Пульс', borderColor: '#990000', backgroundColor: '#990000', data: heart_rate, },
|
||||
{ radius: 0, label: 'Мощность', borderColor: '#cccccc', backgroundColor: '#cccccc', data: power, },
|
||||
]
|
||||
|
||||
}
|
||||
})
|
||||
.catch((error: any) => {
|
||||
console.log(error);
|
||||
init({
|
||||
message: "Что-то пошло не так.",
|
||||
color: "error",
|
||||
}
|
||||
})
|
||||
.catch((error: any) => {
|
||||
console.log(error);
|
||||
init({
|
||||
message: "Что-то пошло не так.",
|
||||
color: "error",
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
initWorkout(route.params.id as string);
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
.image-container {
|
||||
cursor: pointer;
|
||||
height: 300px;
|
||||
width: 100%;
|
||||
background-position: 50% 50%;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
}
|
||||
#zoom-botton {
|
||||
#zoom-botton {
|
||||
display: block;
|
||||
margin-top: 20px;
|
||||
margin-bottom: -35px;
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
#workout-container {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
#workout-map {
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
#workout-short-data {
|
||||
width: 30%;
|
||||
padding: 0 0 0 20px;
|
||||
}
|
||||
h3 {
|
||||
margin-bottom: 10px;
|
||||
font-size: 20px;
|
||||
font-family: sans-serif;
|
||||
|
||||
}
|
||||
.workout-item-params {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
justify-content:left;
|
||||
color: #333;
|
||||
padding: 0 0 5px 0
|
||||
|
||||
}
|
||||
.workout-item-params-name {
|
||||
font-weight: bold;
|
||||
}
|
||||
.workout-item-params-value {
|
||||
padding: 0 0 0 5px
|
||||
}
|
||||
</style>
|
||||
|
|
@ -34,28 +34,9 @@ import { AxiosResponse, AxiosInstance } from "axios";
|
|||
import { ref, inject } from 'vue';
|
||||
import { useToast } from "vuestic-ui/web-components";
|
||||
import { useRouter } from "vue-router";
|
||||
import { WorkoutItem, Attachment, secondsToDuration, distConvert, speedConvert } from "./Definitions.vue";
|
||||
|
||||
|
||||
type Attachment = {
|
||||
url: string;
|
||||
}
|
||||
type WorkoutItem = {
|
||||
id: string;
|
||||
name: string;
|
||||
created_by: string;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
description: string;
|
||||
cadence: number;
|
||||
heart_rate: number;
|
||||
temperature: number;
|
||||
speed: number;
|
||||
power: number;
|
||||
duraion_sec: number;
|
||||
distantion: number;
|
||||
attachment: Attachment;
|
||||
};
|
||||
|
||||
const { push } = useRouter();
|
||||
const axiosAuth= inject('axiosAuth') as AxiosInstance;
|
||||
let workoutItems = ref<Array<WorkoutItem>>([]);
|
||||
|
|
@ -80,19 +61,6 @@ const deleteItem = (id: string) => {
|
|||
});
|
||||
};
|
||||
|
||||
const secondsToDuration = (seconds: number) => {
|
||||
var hours = Math.floor(seconds / 3600);
|
||||
var minutes = Math.floor((seconds % 3600) / 60);
|
||||
return `${hours} ч. ${minutes} мин.`;
|
||||
}
|
||||
|
||||
const distConvert = (speed: number) => {
|
||||
return Math.round(speed/1000)
|
||||
}
|
||||
|
||||
const speedConvert = (speed: number) => {
|
||||
return Math.round(speed*3.6)
|
||||
}
|
||||
|
||||
|
||||
const openWorkout = (id: string) => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue