/** * Load data * @param \Runalyze\View\Activity\Context $context */ protected function loadData(Activity\Context $context) { if (!$context->trackdata()->has(Trackdata\Object::DISTANCE) || !$context->trackdata()->has(Trackdata\Object::TIME)) { $this->Plot->raiseError(__('No GPS-data available. Can\\\'t compute laps.')); return; } $RawData = $this->computeRounds($context); $num = count($RawData); $Pace = new PaceObject(0, 1); $Pace->setUnit($this->PaceUnit); foreach ($RawData as $key => $val) { $km = $key + 1; if ($num < 30) { $label = $km; } elseif ($num < 50) { $label = $km % 2 == 1 && $km > 0 ? $km : ''; } elseif ($num < 100) { $label = $km % 5 == 0 && $km > 0 ? $km : ''; } else { $label = $km % 10 == 0 && $km > 0 ? $km : ''; } $this->Labels[$key] = array($key, $label); $Pace->setDistance($val['km'])->setTime($val['s']); if ($this->PaceUnit->isTimeFormat()) { $this->Data[$key] = 1000 * round($Pace->secondsPerKm() * $this->PaceUnit->factorForUnit()); } else { $this->Data[$key] = (double) str_replace(',', '.', $Pace->value()); } } $avgPace = new PaceObject($context->activity()->duration(), $context->activity()->distance()); $this->achievedPace = $avgPace->secondsPerKm(); $this->Plot->Data[] = array('label' => $this->title, 'data' => $this->Data); }
/** * 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() : '-'); } } }
/** * 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 ''; }
/** * 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() : '-'); } } }
/** * Calculate and set adjusted temperature * @param \Runalyze\Data\Weather\WindSpeed $windSpeed * @param \Runalyze\Activity\Temperature $temperature * @param \Runalyze\Activity\Pace $activitySpeed * @param null|\Runalyze\Activity\Pace $activitySpeed * @throws \InvalidArgumentException * @see https://en.wikipedia.org/wiki/Wind_chill#North_American_and_United_Kingdom_wind_chill_index */ public function setFrom(WindSpeed $windSpeed, ActivityTemperature $temperature, Pace $activitySpeed = null) { if ($windSpeed->isUnknown() || $temperature->isEmpty()) { throw new \InvalidArgumentException('Wind speed and temperature must be known. Null value(s) given.'); } $kmh = $windSpeed->inKilometerPerHour(); $calc = $temperature->celsius(); if (null !== $activitySpeed) { $kmh = $windSpeed->inKilometerPerHour() + $activitySpeed->asKmPerHour(); } if ($kmh >= 5) { $calc = 13.12 + 0.6215000000000001 * $temperature->celsius() - 11.37 * pow($kmh, 0.16) + 0.3965 * $temperature->celsius() * pow($kmh, 0.16); } $this->AdjustedTemperature = clone $temperature; $this->AdjustedTemperature->set($calc); }
/** * @param int $num * @param enum $paceUnit */ protected function manipulateData($num, $paceUnit) { $paceInTime = $paceUnit == APace::MIN_PER_KM || $paceUnit == APace::MIN_PER_100M || $paceUnit == APace::MIN_PER_500M; $pace = new APace(0, 1, $paceUnit); foreach ($this->Data as $key => $val) { if ($num > 35) { $this->Labels[$key] = array($key, round($this->Labels[$key], 1)); } elseif ($num >= 20) { $this->Labels[$key] = array($key, number_format($this->Labels[$key], 1, '.', '')); } elseif ($num > 10) { $this->Labels[$key] = array($key, $this->Labels[$key] . 'k'); } else { $this->Labels[$key] = array($key, $this->Labels[$key] . ' km'); } $pace->setTime($val); if ($paceInTime) { $this->Data[$key] = 1000 * $pace->secondsPerKm(); if ($paceUnit == APace::MIN_PER_100M) { $this->Data[$key] /= 10; } elseif ($paceUnit == APace::MIN_PER_500M) { $this->Data[$key] /= 2; } } else { $this->Data[$key] = (double) str_replace(',', '.', $pace->value()); } } $this->Plot->Data[] = array('label' => $this->title, 'data' => $this->Data); }
/** * Display rounds */ protected function displayTable() { $this->DemandedPace->setUnit($this->Context->sport()->paceUnit()); $Table = new Table($this->Laps, $this->DemandedTime, $this->DemandedPace, $this->Context->sport()->id() == Configuration::General()->runningSport()); if ($this->LapDistance > 0) { $Table->setAverage($this->Context->dataview()->pace(), new Duration($this->Context->trackdata()->totalTime() / $this->Context->trackdata()->totalDistance() * $this->LapDistance)); } else { $Table->setAverage($this->Context->dataview()->pace()); } $Table->display(); }
/** * Init data * @param \Runalyze\View\Activity\Context $context */ protected function initData(Activity\Context $context) { $this->PaceUnit = $context->sport()->paceUnit(); $this->SplitsAreNotComplete = $this->splitsAreNotComplete($context); $this->loadData($context); if (!empty($this->Data) && ($this->PaceUnit == APace::MIN_PER_KM || $this->PaceUnit == APace::MIN_PER_100M || $this->PaceUnit == APace::MIN_PER_500M)) { $max = Helper::ceilFor(max($this->Data), 30000); $this->Plot->setYAxisTimeFormat('%M:%S'); } else { $max = ceil(max($this->Data)); $pace = new APace(0, 1, $this->PaceUnit); $this->Plot->addYUnit(1, str_replace(' ', '', $pace->appendix()), 1); } $this->Plot->setYLimits(1, 0, $max, false); $this->Plot->setXLabels($this->Labels); $this->Plot->showBars(true); $this->Plot->setYTicks(1, null); $this->Plot->Options['xaxis']['show'] = true; // force to show xaxis-labels, even if no time or distance array is given $this->addAnnotations(); }
/** * @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; }
/** * @param int $num */ protected function manipulateData($num) { $distanceUnit = \Runalyze\Configuration::General()->distanceUnitSystem()->distanceUnit(); $Pace = new PaceObject(0, 1); $Pace->setUnit($this->PaceUnit); foreach ($this->Data as $key => $val) { if ($num > 35) { $this->Labels[$key] = array($key, round($this->Labels[$key], 1)); } elseif ($num >= 15) { $this->Labels[$key] = array($key, number_format($this->Labels[$key], 1, '.', '')); } elseif ($num > 10) { $this->Labels[$key] = array($key, $this->Labels[$key] . $distanceUnit); } else { $this->Labels[$key] = array($key, $this->Labels[$key] . ' ' . $distanceUnit); } $Pace->setTime($val); if ($this->PaceUnit->isTimeFormat()) { $this->Data[$key] = 1000 * round($Pace->secondsPerKm() * $this->PaceUnit->factorForUnit()); } else { $this->Data[$key] = (double) str_replace(',', '.', $Pace->value()); } } $this->Plot->Data[] = array('label' => $this->title, 'data' => $this->Data); }
/** * @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 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 : '-'); } }
/** * 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 : '-'); } }
/** * Display table */ public function displayTable() { if (is_null($this->schuhe)) { $this->initTableData(); } echo '<table id="list-of-all-shoes" class="fullwidth zebra-style"> <thead> <tr> <th class="{sorter: \'x\'} small">' . __('x-times') . '</th> <th class="{sorter: false}"></th> <th>' . __('Name') . '</th> <th class="{sorter: \'germandate\'} small">' . __('since') . '</th> <th class="{sorter: \'distance\'}">Ø km</th> <th>Ø ' . __('Pace') . '</th> <th class="{sorter: \'distance\'} small"><small>' . __('max.') . '</small> km</th> <th class="small"><small>' . __('min.') . '</small> ' . __('Pace') . '</th> <th class="{sorter: \'resulttime\'}">' . __('Time') . '</th> <th class="{sorter: \'distance\'}">' . __('Distance') . '</th> <th>' . __('Weight') . '</th> </tr> </thead> <tbody>'; if (!empty($this->schuhe)) { foreach ($this->schuhe as $schuh) { $Shoe = new Shoe($schuh); $in_use = $Shoe->isInUse() ? '' : ' unimportant'; $Pace = new Pace($Shoe->getTime(), $Shoe->getKmInDatabase()); $MaxPace = new Pace($schuh['pace_in_s'], 1); echo '<tr class="' . $in_use . ' r" style="position: relative"> <td class="small">' . $schuh['num'] . 'x</td> <td>' . $this->editLinkFor($schuh['id']) . '</td> <td class="b l">' . ShoeFactory::getSearchLink($schuh['id']) . '</td> <td class="small">' . $Shoe->getSince() . '</td> <td>' . ($schuh['num'] != 0 ? Distance::format($Shoe->getKmInDatabase() / $schuh['num']) : '-') . '</td> <td>' . ($schuh['num'] != 0 ? $Pace->asMinPerKm() . '/km' : '-') . '</td> <td class="small">' . Distance::format($schuh['dist']) . '</td> <td class="small">' . $MaxPace->asMinPerKm() . '/km' . '</td> <td>' . $Shoe->getTimeString() . '</td> <td>' . $Shoe->getKmString() . '</td> <td class="small">' . $Shoe->getWeightString() . '</td> </tr>'; } } else { echo '<tr><td colspan="9">' . __('You don\'t have any shoes') . '</td></tr>'; } echo '</tbody>'; echo '</table>'; Ajax::createTablesorterFor("#list-of-all-shoes", true); }
/** * Get code * @return string */ private function getCode() { $Code = ' <table class="fullwidth zebra-style c"> <thead> <tr class="b"> <th>' . __('Icon') . '</th> <th>' . Ajax::tooltip(__('Name'), __('Name of the sport')) . '</th> <th>' . Ajax::tooltip(__('kcal/h'), __('Average energy turnover in kilocalories per hour')) . '</th> <th>' . Ajax::tooltip('Ø ' . __('HR'), __('Average heart rate (used for calculation of TRIMP)')) . '</th> <th>' . Ajax::tooltip(__('km'), __('Has a distance')) . '</th> <th>' . Ajax::tooltip(__('Unit'), __('Unit for speed')) . '</th> <th>' . Ajax::tooltip(__('Power'), __('Power is recorded or calculated.')) . '</th> <th>' . Ajax::tooltip(__('Outside'), __('Sport is performed outdoor: activate route, weather, ...')) . '</th> <th>' . Ajax::tooltip(__('Main equipment'), __('Objects of main equipment type can be shown in the activity overview.')) . '</th> <th>' . Ajax::tooltip(__('Calendar view'), __('Mode for displaying activities in calendar')) . '</th> <th>' . Ajax::tooltip(Icon::$CROSS_SMALL, __('A sport can only be deleted if no references exist.')) . '</th> </tr> </thead> <tbody>'; $Sports = SportFactory::AllSports(); $SportCount = SportFactory::CountArray(); foreach ($SportCount as $is => $SC) { if (isset($Sports[$is])) { $Sports[$is]['counts'] = $SC; } } usort($Sports, function ($a, $b) { return !isset($b['counts']) || isset($a['counts']) && (int) $a['counts'] > (int) $b['counts'] ? -1 : 1; }); $Sports[] = array('id' => -1, 'new' => true, 'name' => '', 'img' => 'unknown.gif', 'short' => 0, 'kcal' => '', 'HFavg' => '', 'distances' => 0, 'speed' => Pace::STANDARD, 'power' => 0, 'outside' => '', 'main_equipmenttypeid' => 0); $IconOptions = SportFactory::getIconOptions(); $PaceOptions = Pace::options(); $ShortOptions = array(0 => __('complete row'), 1 => __('only icon')); foreach ($Sports as $Data) { $id = $Data['id']; $isRunning = $id == Runalyze\Configuration::General()->runningSport(); $iconSelect = HTML::selectBox('sport[img][' . $id . ']', $IconOptions, $Data['img'], '', 'fip-select'); $EquipmentTypeOptions = $this->getEquipmentTypeOptions($id); if ($id == -1) { $delete = ''; } elseif (!isset($SportCount[$id]) || $SportCount[$id] == 0) { $delete = '<input type="checkbox" name="sport[delete][' . $id . ']">'; } else { $delete = SearchLink::to('sportid', $id, '<small>(' . $SportCount[$id] . ')</small>'); } $Code .= ' <tr class="' . (isset($Data['new']) ? ' unimportant' : '') . '"> <td>' . $iconSelect . '</td> <td>' . ($isRunning ? '<input type="hidden" name="sport[name][' . $id . ']" value="' . $Data['name'] . '">' . $Data['name'] : '<input type="text" name="sport[name][' . $id . ']" value="' . $Data['name'] . '">') . '</td> <td><input type="text" size="3" name="sport[kcal][' . $id . ']" value="' . $Data['kcal'] . '"></td> <td><input type="text" size="3" name="sport[HFavg][' . $id . ']" value="' . $Data['HFavg'] . '"></td> <td><input type="checkbox" name="sport[distances][' . $id . ']"' . ($Data['distances'] == 1 ? ' checked' : '') . '></td> <td>' . HTML::selectBox('sport[speed][' . $id . ']', $PaceOptions, $Data['speed']) . '</td> <td><input type="checkbox" name="sport[power][' . $id . ']"' . ($Data['power'] == 1 ? ' checked' : '') . '></td> <td><input type="checkbox" name="sport[outside][' . $id . ']"' . ($Data['outside'] == 1 ? ' checked' : '') . '></td> <td>' . HTML::selectBox('sport[main_equipmenttypeid][' . $id . ']', $EquipmentTypeOptions, $Data['main_equipmenttypeid']) . '</td> <td>' . ($isRunning ? '<input type="hidden" name="sport[short][' . $id . ']" value="0">-' : HTML::selectBox('sport[short][' . $id . ']', $ShortOptions, $Data['short'])) . '</td> <td>' . ($isRunning ? '-' : $delete) . '</td> </tr>'; } $Code .= ' </tbody> </table>'; return $Code; }
/** * Compare * Both pace objects must have the same unit and the unit must be comparable. * @param \Runalyze\Activity\Pace $other * @param boolean $raw [optional] * @throws \InvalidArgumentException * @return string */ public function compareTo(Pace $other, $raw = false) { if ($this->unitEnum() != $other->unitEnum()) { throw new \InvalidArgumentException('Pace objects must have the same unit.'); } if ($this->secondsPerKm() == 0 || $other->secondsPerKm() == 0) { return ''; } $comparisonInSecondsPerKm = $this->UnitObject->compare($this->secondsPerKm(), $other->secondsPerKm()); $isPositive = $comparisonInSecondsPerKm >= 0; if ($comparisonInSecondsPerKm == 0 && $this->UnitObject->isTimeFormat()) { return $this->formatComparison('0:00', $isPositive, $raw); } return $this->formatComparison($this->UnitObject->format(abs($comparisonInSecondsPerKm)), $isPositive, $raw); }
/** * 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>'; }
/** * Check for distance marker */ protected function checkForDistanceMarker() { if (!$this->addIconsAndInfo || !$this->hasTrackdataLoop()) { return; } if (round((new Distance($this->TrackdataLoop->distance()))->valueInPreferredUnit(), 2) >= $this->Dist) { $Pace = new Pace($this->TrackdataLoop->time() - $this->Time); $Tooltip = sprintf(__('<strong>%s. %s</strong> in %s'), $this->Dist, Configuration::General()->distanceUnitSystem()->distanceUnit(), $Pace->asMinPerKm()) . '<br>'; $Tooltip .= sprintf(__('<strong>Time:</strong> %s'), Duration::format($this->TrackdataLoop->time())); $this->addMarkerGeohash($this->RouteLoop->geohash(), $this->distIcon($this->Dist), $Tooltip); $this->Dist += 1; $this->Time = $this->TrackdataLoop->time(); } }
/** * Get array for "Tempobereiche" */ private function getPaceArray() { $speed_min = $this->Configuration()->value('lowest_pacegroup'); $speed_max = $this->Configuration()->value('highest_pacegroup'); $speed_step = $this->Configuration()->value('pacegroup_step'); $ceil_corr = $speed_min % $speed_step; if ($this->sportid != Configuration::General()->runningSport()) { $MinMax = DB::getInstance()->query(' SELECT MIN(`s`/`distance`) as `min`, MAX(`s`/`distance`) as `max` FROM `' . PREFIX . 'training` WHERE `sportid`=' . $this->sportid . ' AND ' . PREFIX . 'training.accountid="' . SessionAccountHandler::getId() . '" ' . $this->where_time . ' AND `distance`>0 ')->fetch(); if (!empty($MinMax)) { $speed_min = round((double) $MinMax['max']); $speed_max = round((double) $MinMax['min']); $speed_step = $speed_min == $speed_max ? 1 : round(($speed_min - $speed_max) / 10); $ceil_corr = $speed_min == $speed_max ? 1 : $speed_min % $speed_step; } } $result = DB::getInstance()->query(' SELECT ' . $this->getTimerIndexForQuery() . ' AS `timer`, COUNT(*) AS `num`, SUM(`distance`) AS `distance`, SUM(`s`) AS `s`, FLOOR( (`s`/`distance` - ' . $ceil_corr . ')/' . $speed_step . ')*' . $speed_step . ' + ' . $ceil_corr . ' AS `group` FROM `' . PREFIX . 'training` WHERE `sportid`=' . $this->sportid . ' AND ' . PREFIX . 'training.accountid="' . SessionAccountHandler::getId() . '" ' . $this->where_time . ' AND `distance`>0 GROUP BY `group`, ' . $this->group_time . ' ORDER BY `group` DESC, ' . $this->getTimerForOrderingInQuery() . ' ASC ')->fetchAll(); $speed_data = $this->emptyData; foreach ($result as $dat) { if ($this->sportid == Configuration::General()->runningSport()) { if ($dat['group'] > $speed_min) { $dat['group'] = $speed_min; } else { if ($dat['group'] < $speed_max) { $dat['group'] = $speed_max; } } } $this->setGroupData($speed_data, $dat); $this->setSumData($speed_data, $dat); } $speed_foreach = array(); if (!empty($result)) { $Pace = new Pace(0, 1, SportFactory::getSpeedUnitFor($this->sportid)); for ($speed = $speed_min; $speed > $speed_max - $speed_step; $speed -= $speed_step) { if ($speed <= $speed_max) { $name = '<small>' . __('faster than') . '</small> ' . $Pace->setTime($speed + $speed_step)->valueWithAppendix(); } else { if ($speed == $speed_min) { $name = '<small>' . __('up to') . '</small> ' . $Pace->setTime($speed)->valueWithAppendix(); } else { $name = $Pace->setTime($speed + $speed_step)->value() . ' <small>' . __('to') . '</small> ' . $Pace->setTime($speed)->valueWithAppendix(); } } $speed_foreach[] = array('name' => $name, 'id' => max($speed, $speed_max)); } } return array('name' => __('Pace Zones') . '*', 'array' => $speed_data, 'foreach' => $speed_foreach); }
public function testMethodChaining() { $Pace = new Pace(0, 1, PaceUnit::MIN_PER_KM); $this->assertEquals('3:00', $Pace->setTime(180)->value()); $this->assertEquals('6:00', $Pace->setDistance(0.5)->value()); }
/** * 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); }
/** * 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>'; } }
/** * 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>'; } }
/** * 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>'; }
/** * Display table */ public function displayTable() { if (is_null($this->Equipment)) { $this->initTableData(); } echo '<table id="list-of-all-equipment" class="fullwidth zebra-style"> <thead> <tr> <th class="{sorter: \'x\'} small">' . __('x-times') . '</th> <th>' . __('Name') . '</th> <th class="{sorter: \'germandate\'} small">' . __('since') . '</th> <th class="{sorter: \'distance\'}">Ø ' . Runalyze\Configuration::General()->distanceUnitSystem()->distanceUnit() . '</th> <th>Ø ' . __('Pace') . '</th> <th class="{sorter: \'distance\'} small"><small>' . __('max.') . '</small> ' . Runalyze\Configuration::General()->distanceUnitSystem()->distanceUnit() . '</th> <th class="small"><small>' . __('min.') . '</small> ' . __('Pace') . '</th> <th class="{sorter: \'resulttime\'}">' . __('Time') . '</th> <th class="{sorter: \'distance\'}">' . __('Distance') . '</th> <th>' . __('Notes') . '</th> </tr> </thead> <tbody>'; if (!empty($this->Equipment)) { foreach ($this->Equipment as $data) { $Object = new Model\Equipment\Object($data); $in_use = $Object->isInUse() ? '' : ' unimportant'; $Pace = new Pace($Object->duration(), $Object->distance()); $MaxPace = new Pace($data['pace_in_s'], 1); echo '<tr class="' . $in_use . ' r" style="position: relative"> <td class="small">' . $data['num'] . 'x</td> <td class="b l">' . SearchLink::to('equipmentid', $Object->id(), $Object->name()) . '</td> <td class="small">' . $this->formatData($Object->startDate()) . '</td> <td>' . ($data['num'] != 0 ? Distance::format($Object->distance() / $data['num']) : '-') . '</td> <td>' . ($Object->duration() > 0 ? $Pace->asMinPerKm() . '/km' : '-') . '</td> <td class="small">' . Distance::format($data['dist']) . '</td> <td class="small">' . $MaxPace->asMinPerKm() . '/km' . '</td> <td>' . Duration::format($Object->duration()) . '</td> <td>' . Distance::format($Object->totalDistance()) . '</td> <td class="small">' . $Object->notes() . '</td> </tr>'; } } else { echo '<tr><td colspan="9">' . __('You don\'t have any shoes') . '</td></tr>'; } echo '</tbody>'; echo '</table>'; Ajax::createTablesorterFor("#list-of-all-equipment", true); }
/** * Check for distance marker */ protected function checkForDistanceMarker() { if (!$this->addIconsAndInfo || !$this->hasTrackdataLoop()) { return; } if (round($this->TrackdataLoop->distance(), 2) >= $this->Dist) { $Pace = new Pace($this->TrackdataLoop->time() - $this->Time); $Tooltip = sprintf(__('<strong>%s. km</strong> in %s'), $this->Dist, $Pace->asMinPerKm()) . '<br>'; $Tooltip .= sprintf(__('<strong>Time:</strong> %s'), Duration::format($this->TrackdataLoop->time())); $this->addMarker($this->RouteLoop->latitude(), $this->RouteLoop->longitude(), $this->distIcon($this->Dist), $Tooltip); $this->Dist += 1; $this->Time = $this->TrackdataLoop->time(); } }