Пример #1
0
 /**
  * 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' => '&lt;&nbsp;' . $hf . '&nbsp;&#37;', 'time' => $Info['time'], 'distance' => $Info['distance'], 'average' => $Pace->value() > 0 ? $Pace->valueWithAppendix() : '-');
         }
     }
 }
Пример #3
0
 /**
  * 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 '';
 }
Пример #4
0
 /**
  * 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') : '&gt; ' . $Pace->valueWithAppendix(), 'time' => $Info['time'], 'distance' => $Info['distance'], 'average' => $HR->asBPM() > 0 ? $HR->string() : '-');
         }
     }
 }
Пример #5
0
 /**
  * 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);
 }
Пример #6
0
 /**
  * @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);
 }
Пример #7
0
 /**
  * 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();
 }
Пример #8
0
 /**
  * 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('&nbsp;', '', $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();
 }
Пример #9
0
 /**
  * @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;
 }
Пример #10
0
 /**
  * @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);
 }
Пример #11
0
 /**
  * @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\'}">&Oslash; km</th>
					<th>&Oslash; ' . __('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);
    }
Пример #15
0
    /**
     * 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('&Oslash;&nbsp;' . __('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;
    }
Пример #16
0
 /**
  * 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>';
    }
Пример #18
0
 /**
  * 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>&nbsp;' . $Pace->setTime($speed + $speed_step)->valueWithAppendix();
                } else {
                    if ($speed == $speed_min) {
                        $name = '<small>' . __('up to') . '</small>&nbsp;' . $Pace->setTime($speed)->valueWithAppendix();
                    } else {
                        $name = $Pace->setTime($speed + $speed_step)->value() . ' <small>' . __('to') . '</small>&nbsp;' . $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);
    }
Пример #20
0
 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());
 }
Пример #21
0
 /**
  * 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);
 }
Пример #23
0
    /**
     * Set halfs of competition
     */
    private function setHalfsOfCompetitionToCode()
    {
        if (empty($this->Halfs)) {
            return;
        }
        $this->Code .= '<tr class="no-zebra"><td colspan="5">&nbsp;</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\'}">&Oslash; ' . Runalyze\Configuration::General()->distanceUnitSystem()->distanceUnit() . '</th>
					<th>&Oslash; ' . __('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);
    }
Пример #27
0
 /**
  * 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();
     }
 }