/** * Init data */ protected function initData() { $Zones = $this->computeZones(); $Pace = new Pace(0, 0, $this->Context->sport()->paceUnit()); foreach ($Zones as $hf => $Info) { if ($Info['time'] > parent::MINIMUM_TIME_IN_ZONE) { $Pace->setTime($Info['time']); $Pace->setDistance($Info['distance']); $this->Data[] = array('zone' => '< ' . $hf . ' %', 'time' => $Info['time'], 'distance' => $Info['distance'], 'average' => $Pace->value() > 0 ? $Pace->valueWithAppendix() : '-'); } } }
/** * @return string */ protected function tableFooter() { $Code = '<tbody>'; $Code .= '<tr class="no-zebra"><td colspan="4" class="r">' . __('Average') . ':</td>'; $Code .= '<td class="c">' . ($this->AverageTime != null ? $this->AverageTime->string() : '') . '</td>'; $Code .= '<td></td>'; $Code .= '<td class="c">' . ($this->AveragePace != null ? $this->AveragePace->valueWithAppendix() : '') . '</td>'; $Code .= '<td colspan="4"></td>'; $Code .= '</tr>'; $Code .= '</tbody>'; $Code .= '</table>'; return $Code; }
/** * Get string to display this dataset value * @param \Runalyze\Dataset\Context $context * @return string */ public function stringFor(Context $context) { if ($context->activity()->distance() > 0) { if ($context->hasData(self::DURATION_SUM_WITH_DISTANCE_KEY)) { if ($context->data(self::DURATION_SUM_WITH_DISTANCE_KEY) > 0) { $Pace = new Activity\Pace($context->data(self::DURATION_SUM_WITH_DISTANCE_KEY), $context->activity()->distance(), $context->hasSport() ? $context->sport()->paceUnitEnum() : Activity\Pace::STANDARD); return $Pace->valueWithAppendix(); } return ''; } return $context->dataview()->pace()->valueWithAppendix(); } return ''; }
/** * @return string */ protected function tableFooter() { $Code = '<tbody>'; $Code .= '<tr class="no-zebra"><td colspan="4" class="r">' . __('Average') . ':</td>'; $Code .= '<td class="c">' . ($this->AverageTime != null ? $this->AverageTime->string() : '') . '</td>'; $Code .= $this->DemandedTime->isZero() ? '' : '<td></td>'; $Code .= '<td class="c">' . ($this->AveragePace != null ? $this->AveragePace->valueWithAppendix() : '') . '</td>'; $Code .= $this->DemandedPace->isEmpty() ? '' : '<td></td>'; $Code .= '<td colspan="' . (3 + count($this->AdditionalKeys)) . '"></td>'; $Code .= '</tr>'; $Code .= '</tbody>'; $Code .= '</table>'; $Code .= $this->checkboxToToggleInactiveSplits(); return $Code; }
/** * Init data */ protected function initData() { $this->paceUnit = $this->Context->sport()->paceUnit(); $Zones = $this->computeZones(); $hrMax = Runalyze\Configuration::Data()->HRmax(); $Pace = new Pace(0, 1, $this->paceUnit); $HR = new HeartRate(0, Runalyze\Context::Athlete()); foreach ($Zones as $paceInSeconds => $Info) { if ($Info['time'] > parent::MINIMUM_TIME_IN_ZONE) { $Pace->setTime($paceInSeconds); $HR->setBPM($Info['time'] > 0 ? $Info['hr'] / $Info['time'] : 0); $this->Data[] = array('zone' => $paceInSeconds == 0 ? __('faster') : '> ' . $Pace->valueWithAppendix(), 'time' => $Info['time'], 'distance' => $Info['distance'], 'average' => $HR->asBPM() > 0 ? $HR->string() : '-'); } } }
/** * Show prognosis for a given distance * @param double $distance */ protected function showPrognosis($distance) { $PB = new PersonalBest($distance); $PBTime = $PB->exists() ? Duration::format($PB->seconds()) : '-'; $Prognosis = new Duration($this->Prognosis->inSeconds($distance)); $Distance = new Distance($distance); $Pace = new Pace($Prognosis->seconds(), $distance, Pace::MIN_PER_KM); echo '<p> <span class="right"> ' . sprintf(__('<small>from</small> %s <small>to</small> <strong>%s</strong>'), $PBTime, $Prognosis->string(Duration::FORMAT_AUTO, 0)) . ' <small>(' . $Pace->valueWithAppendix() . ')</small> </span> <strong>' . $Distance->string(Distance::FORMAT_AUTO, 1) . '</strong> </p>'; }
/** * Init calculations */ protected function runCalculations() { foreach ($this->Distances as $km) { $Prognosis = $this->PrognosisObject->inSeconds($km); $PB = new PersonalBest($km, DB::getInstance(), false); $PB->lookupWithDetails(); $VDOTprognosis = new VDOT(); $VDOTprognosis->fromPace($km, $Prognosis); $VDOTpb = new VDOT(); $VDOTpb->fromPace($km, $PB->seconds()); $PacePrognosis = new Pace($Prognosis, $km, Pace::MIN_PER_KM); $PacePB = new Pace($PB->seconds(), $km, Pace::MIN_PER_KM); $DateWithLink = Ajax::trainingLink($PB->activityId(), date('d.m.Y', $PB->timestamp()), true); $this->Prognoses[] = array('distance' => Distance::format($km, $km <= 3), 'prognosis' => Duration::format($Prognosis), 'prognosis-pace' => $PacePrognosis->valueWithAppendix(), 'prognosis-vdot' => $VDOTprognosis->uncorrectedValue(), 'diff' => !$PB->exists() ? '-' : ($PB->seconds() > $Prognosis ? '+ ' : '- ') . Duration::format(abs(round($PB->seconds() - $Prognosis))), 'diff-class' => $PB->seconds() > $Prognosis ? 'plus' : 'minus', 'pb' => $PB->seconds() > 0 ? Duration::format($PB->seconds()) : '-', 'pb-pace' => $PB->seconds() > 0 ? $PacePB->valueWithAppendix() : '-', 'pb-vdot' => $PB->seconds() > 0 ? $VDOTpb->uncorrectedValue() : '-', 'pb-date' => $PB->seconds() > 0 ? $DateWithLink : '-'); } }
/** * Display the table with general records */ private function displayRekorde() { foreach ($this->rekorde as $rekord) { echo '<table class="fullwidth zebra-style">'; echo '<thead><tr><th colspan="11" class="l">' . $rekord['name'] . '</th></tr></thead>'; echo '<tbody>'; $output = false; $sports = DB::getInstance()->query($rekord['sportquery'])->fetchAll(); $Request = DB::getInstance()->prepare($rekord['datquery']); foreach ($sports as $sport) { $Request->bindValue('sportid', $sport['id']); $Request->execute(); $data = $Request->fetchAll(); if (!empty($data)) { $output = true; echo '<tr class="r">'; echo '<td class="b l">' . Icon::getSportIconForGif($sport['img'], $sport['name']) . ' ' . $sport['name'] . '</td>'; $j = 0; foreach ($data as $j => $dat) { if ($rekord['speed']) { $Pace = new Pace($dat['s'], $dat['distance'], SportFactory::getSpeedUnitFor($sport['id'])); $code = $Pace->valueWithAppendix(); } else { $code = $dat['distance'] != 0 ? Distance::format($dat['distance']) : Duration::format($dat['s']); } echo '<td class="small"><span title="' . date("d.m.Y", $dat['time']) . '"> ' . Ajax::trainingLink($dat['id'], $code) . ' </span></td>'; } for (; $j < 9; $j++) { echo HTML::emptyTD(); } echo '</tr>'; } } if (!$output) { echo '<tr><td colspan="11"><em>' . __('No data available') . '</em></td></tr>'; } echo '</tbody>'; echo '</table>'; } }
/** * Get content for a given dataset * @param string $name * @return string */ public function getDataset($name) { switch ($name) { case 'sportid': if (!is_null($this->Sport)) { return $this->Sport->icon()->code(); } return ''; case 'typeid': if (!is_null($this->Type)) { if ($this->Type->isQualitySession()) { return '<strong>' . $this->Type->abbreviation() . '</strong>'; } return $this->Type->abbreviation(); } return ''; case 'time': return $this->Dataview->daytime(); case 'distance': return $this->Dataview->distance() . $this->distanceComparison(); case 's': return $this->Dataview->duration()->string(); case 'pace': if ($this->Activity->distance() > 0) { if (isset($this->ActivityData['s_sum_with_distance'])) { if ($this->ActivityData['s_sum_with_distance'] > 0) { $Pace = new Pace($this->ActivityData['s_sum_with_distance'], $this->Activity->distance(), SportFactory::getSpeedUnitFor($this->Activity->sportid())); return $Pace->valueWithAppendix(); } return ''; } return $this->Dataview->pace()->valueWithAppendix(); } return ''; case 'elevation': if ($this->Activity->elevation() > 0) { return $this->Dataview->elevation()->string(); } return ''; case 'kcal': return $this->Dataview->calories(); case 'pulse_avg': if ($this->Activity->hrAvg() > 0) { return $this->Dataview->hrAvg()->string(); } return ''; case 'pulse_max': if ($this->Activity->hrMax() > 0) { return $this->Dataview->hrMax()->string(); } return ''; case 'trimp': return $this->Dataview->trimp(); case 'cadence': if ($this->Dataview->cadence()->value() > 0) { return $this->Dataview->cadence()->asString(); } return ''; case 'stride_length': if ($this->Dataview->strideLength()->value() > 0) { return $this->Dataview->strideLength()->string(); } return ''; case 'groundcontact': return $this->Dataview->groundcontact(); case 'vertical_oscillation': return $this->Dataview->verticalOscillation(); case 'power': return $this->Dataview->power(); case 'temperature': if (!$this->Activity->weather()->temperature()->isUnknown() && (is_null($this->Sport) || $this->Sport->isOutside())) { return Temperature::format($this->Activity->weather()->temperature()->value(), true, false); } return ''; case 'weatherid': if (!$this->Activity->weather()->isEmpty() && (is_null($this->Sport) || $this->Sport->isOutside())) { return $this->Activity->weather()->condition()->icon()->code(); } return ''; case 'routeid': if ($this->Activity->get(Activity\Object::ROUTEID) > 0) { return $this->cut($this->Factory->route($this->Activity->get(Activity\Object::ROUTEID))->name()); } return ''; case 'splits': if (!$this->Activity->splits()->isEmpty()) { if ($this->Activity->splits()->hasActiveAndInactiveLaps() || round($this->Activity->splits()->totalDistance()) != round($this->Activity->distance()) || !is_null($this->Type) && $this->Type->id() == Configuration::General()->competitionType()) { // TODO: Icon with tooltip? $Icon = new Icon(Icon::CLOCK); return $Icon->code(); } } return ''; case 'comment': return $this->cut($this->Activity->comment()); case 'partner': return $this->cut($this->Activity->partner()->asString()); case 'abc': return $this->Dataview->abcIcon(); case 'vdoticon': if (!is_null($this->Sport) && $this->Sport->id() == Configuration::General()->runningSport()) { return $this->Dataview->vdotIcon(); } return ''; case 'vdot': if (!is_null($this->Sport) && $this->Sport->id() == Configuration::General()->runningSport() && $this->Activity->vdotByHeartRate() > 0) { if (!$this->Activity->usesVDOT()) { return '<span class="unimportant">' . $this->Dataview->vdot()->value() . '</span>'; } return $this->Dataview->vdot()->value(); } return ''; case 'jd_intensity': if (!is_null($this->Sport) && $this->Sport->id() == Configuration::General()->runningSport()) { return $this->Dataview->jdIntensityWithStresscolor(); } return ''; case 'fit_vdot_estimate': if (!is_null($this->Sport) && $this->Sport->id() == Configuration::General()->runningSport()) { return $this->Dataview->fitVdotEstimate(); } return ''; case 'fit_recovery_time': return $this->Dataview->fitRecoveryTime(); case 'fit_hrv_analysis': return $this->Dataview->fitHRVscore(); } return ''; }
/** * Initialize line-data-array for 'Tempo' * @param array $dat */ private function initTempoData($dat) { $Pace = new Pace($dat['s_sum_with_distance'], $dat['distance'], SportFactory::getSpeedUnitFor($this->sportid)); $text = $dat['s_sum_with_distance'] == 0 ? NBSP : $Pace->valueWithAppendix(); $this->TempoData[] = array('i' => $dat['i'], 'text' => $text); }
/** * Init calculations */ protected function runCalculations() { if (!$this->PrognosisObject->isValid()) { return; } foreach ($this->Distances as $km) { $Prognosis = $this->PrognosisObject->inSeconds($km); $PB = new PersonalBest($km, DB::getInstance(), false); $PB->lookupWithDetails(); $VDOTprognosis = new VDOT(); $VDOTprognosis->fromPace($km, $Prognosis); $VDOTpb = new VDOT(); $VDOTpb->fromPace($km, $PB->seconds()); $PacePrognosis = new Pace($Prognosis, $km, SportFactory::getSpeedUnitFor(Configuration::General()->runningSport())); $PacePB = new Pace($PB->seconds(), $km, SportFactory::getSpeedUnitFor(Configuration::General()->runningSport())); $DateWithLink = Ajax::trainingLink($PB->activityId(), date('d.m.Y', $PB->timestamp()), true); $this->Prognoses[] = array('distance' => (new Distance($km))->stringAuto(), 'prognosis' => Duration::format($Prognosis), 'prognosis-pace' => $PacePrognosis->valueWithAppendix(), 'prognosis-vdot' => $VDOTprognosis->uncorrectedValue(), 'diff' => !$PB->exists() ? '-' : ($PB->seconds() > $Prognosis ? '+ ' : '- ') . Duration::format(abs(round($PB->seconds() - $Prognosis))), 'diff-class' => $PB->seconds() > $Prognosis ? 'plus' : 'minus', 'pb' => $PB->seconds() > 0 ? Duration::format($PB->seconds()) : '-', 'pb-pace' => $PB->seconds() > 0 ? $PacePB->valueWithAppendix() : '-', 'pb-vdot' => $PB->seconds() > 0 ? $VDOTpb->uncorrectedValue() : '-', 'pb-date' => $PB->seconds() > 0 ? $DateWithLink : '-'); } }
/** * Show prognosis for a given distance * @param double $distance */ protected function showPrognosis($distance) { $PB = new PersonalBest($distance); $PB->lookupWithDetails(); $PBTime = $PB->exists() ? Duration::format($PB->seconds()) : '-'; $PBString = $PB->exists() ? Ajax::trainingLink($PB->activityId(), $PBTime, true) : $PBTime; $Prognosis = new Duration($this->Prognosis->inSeconds($distance)); $Distance = new Distance($distance); $Pace = new Pace($Prognosis->seconds(), $distance, SportFactory::getSpeedUnitFor(Configuration::General()->runningSport())); echo '<p> <span class="right"> ' . sprintf(__('<small>from</small> %s <small>to</small> <strong>%s</strong>'), $PBString, $Prognosis->string(Duration::FORMAT_AUTO, 0)) . ' <small>(' . $Pace->valueWithAppendix() . ')</small> </span> <strong>' . $Distance->stringAuto(true, 1) . '</strong> </p>'; }
/** * Set halfs of competition */ private function setHalfsOfCompetitionToCode() { if (empty($this->Halfs)) { return; } $this->Code .= '<tr class="no-zebra"><td colspan="5"> </td></tr>'; $this->Code .= '<tr class="b bottom-spacer no-zebra"><td colspan="5">' . __('1st/2nd Half') . '</td></tr>'; $totalTime = 0; $totalDist = 0; foreach ($this->Halfs as $Half) { $totalTime += $Half['s']; $totalDist += $Half['km']; } $TotalPace = new Pace($totalTime, $totalDist, $this->PaceUnit); for ($i = 0, $num = count($this->Halfs); $i < $num; $i++) { $Pace = new Pace($this->Halfs[$i]['s'], $this->Halfs[$i]['km'], $this->PaceUnit); $this->Code .= '<tr class="r"> <td></td> <td>' . Distance::format($this->Halfs[$i]['km'], true, 2) . '</td> <td>' . Duration::format($this->Halfs[$i]['s']) . '</td> <td>' . $Pace->valueWithAppendix() . '</td> <td>' . $Pace->compareTo($TotalPace) . '</td> </tr>'; } }
public function testMinPer100m() { $Pace = new Pace(123, 0.1, PaceUnit::MIN_PER_100M); $this->assertEquals('2:03/100m', $Pace->valueWithAppendix()); }