1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-12-25 18:15:49 +01:00

Add charts into Sports Activity Details. Improve pingpong icon.

This commit is contained in:
vanous 2020-09-06 21:23:18 +02:00
parent d634457603
commit 7371fb37c2
7 changed files with 274 additions and 103 deletions

View File

@ -23,7 +23,7 @@
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
@ -53,7 +53,8 @@
inkscape:window-x="0"
inkscape:window-y="38"
inkscape:window-maximized="1"
inkscape:current-layer="svg12">
inkscape:current-layer="svg12"
inkscape:document-rotation="0">
<sodipodi:guide
position="17.574052,26.877722"
orientation="0,-1"
@ -96,54 +97,36 @@
id="rect2" />
</g>
<g
id="g1055"
transform="translate(2.5371378,-1.0662573)">
id="g1460">
<path
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;paint-order:fill markers stroke"
id="path879"
sodipodi:type="arc"
sodipodi:arc-type="arc"
sodipodi:open="true"
sodipodi:start="0.57990613"
sodipodi:end="5.706593"
sodipodi:ry="4.9496808"
sodipodi:rx="4.9498253"
sodipodi:cy="-2.7809553"
sodipodi:cx="11.285412"
d="M 15.42601,-0.06880041 A 4.9498253,4.9496808 0 0 1 9.8662919,1.9609384 4.9498253,4.9496808 0 0 1 6.3355933,-2.7891565 4.9498253,4.9496808 0 0 1 9.8820139,-7.5275256 4.9498253,4.9496808 0 0 1 15.434976,-5.4793745"
transform="rotate(70)" />
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;paint-order:fill markers stroke"
d="M 8.9746094 3.6386719 A 4.9498253 4.9496808 70 0 0 7.3242188 3.9335938 A 4.9498253 4.9496808 70 0 0 4.0683594 8.875 A 4.9498253 4.9496808 70 0 0 7.8769531 13.40625 L 12.964844 11.564453 A 4.9498253 4.9496808 70 0 0 12.990234 5.6445312 A 4.9498253 4.9496808 70 0 0 8.9746094 3.6386719 z M 6.5664062 6.8300781 A 1.5 1.5 0 0 1 8.0664062 8.3300781 A 1.5 1.5 0 0 1 6.5664062 9.8300781 A 1.5 1.5 0 0 1 5.0664062 8.3300781 A 1.5 1.5 0 0 1 6.5664062 6.8300781 z " />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 7.3821866,15.25384 8.8768583,19.144697 10.734492,18.468573 9.3596982,14.509489"
d="M 9.9193244,14.187583 11.413996,18.07844 13.27163,17.402316 11.896836,13.443232"
id="path893"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 10.430878,12.618946 c -1.3828921,1.73803 -0.9630282,1.977724 -1.0299969,2.18556"
d="m 12.968016,11.552689 c -1.382892,1.73803 -0.963028,1.977724 -1.029997,2.18556"
id="path899"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 5.3453234,14.469936 c 2.1538725,0.450753 2.0286568,0.932477 2.211948,1.049226"
d="m 7.8824612,13.403679 c 2.1538728,0.450753 2.0286568,0.932477 2.2119478,1.049226"
id="path899-4"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 10.430878,12.618946 -5.0855546,1.85099"
d="m 12.968016,11.552689 -5.0855548,1.85099"
id="path916" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 11.035259,11.555228 4.2170508,14.036853"
d="M 13.572397,10.488971 6.7541886,12.970596"
id="path920" />
</g>
<circle
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.999997;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
id="path930"
cx="6.5668674"
cy="8.329855"
r="1.5" />
<path
style="fill:#feffff;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;paint-order:fill markers stroke"
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;paint-order:fill markers stroke"
id="path879-7"
sodipodi:type="arc"
sodipodi:arc-type="arc"
@ -158,26 +141,27 @@
d="m 6.5814574,-15.795621 a 4.9498253,4.9496808 0 0 1 -5.5597185,2.029738 4.9498253,4.9496808 0 0 1 -3.5306986,-4.750094 4.9498253,4.9496808 0 0 1 3.5464206,-4.73837 4.9498253,4.9496808 0 0 1 5.5529616,2.048152" />
<g
id="g1016"
style="fill:#ffffff;fill-opacity:1;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none"
style="fill:none;fill-opacity:1;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none"
transform="translate(2.7714608,-1.6578345)">
<path
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 10.885327,15.160729 -1.3593007,3.936457 1.8576347,0.676124 1.500166,-3.928054"
id="path893-2"
sodipodi:nodetypes="cccc" />
<path
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 14.911147,15.097075 c -2.176542,0.442503 -2.00898,0.896002 -2.193875,1.012167"
id="path899-2"
sodipodi:nodetypes="cc" />
<path
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 9.8255917,13.246085 c 1.3602233,1.729779 0.9546563,2.018314 1.0200213,2.225566"
id="path899-4-6"
sodipodi:nodetypes="cc" />
<path
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 14.911147,15.097075 9.8255917,13.246085"
id="path916-1" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

@ -0,0 +1,176 @@
/* Copyright (C) 2015-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti, Dikay900, Pavel Elagin
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.github.mikephil.charting.charts.Chart;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.LegendEntry;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.charts.AbstractChartFragment;
import nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsData;
import nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsHost;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
public class ActivitySummariesChartFragment extends AbstractChartFragment {
private static final Logger LOG = LoggerFactory.getLogger(ActivitySummariesChartFragment.class);
private LineChart mChart;
private int startTime;
private int endTime;
private GBDevice gbDevice;
public void setDateAndGetData(GBDevice gbDevice, long startTime, long endTime) {
this.startTime = (int) startTime;
this.endTime = (int) endTime;
this.gbDevice = gbDevice;
populate_charts_data();
}
private void populate_charts_data() {
try (DBHandler handler = GBApplication.acquireDB()) {
int LEGEND_TEXT_COLOR = GBApplication.getTextColor(getContext());
List<? extends ActivitySample> samples = getSamples(handler, gbDevice, this.startTime, this.endTime);
DefaultChartsData dcd = refresh(this.gbDevice, samples);
mChart.getLegend().setTextColor(LEGEND_TEXT_COLOR);
mChart.setData(null); // workaround for https://github.com/PhilJay/MPAndroidChart/issues/2317
mChart.getXAxis().setValueFormatter(dcd.getXValueFormatter());
mChart.setData((LineData) dcd.getData());
mChart.invalidate();
} catch (Exception e) {
LOG.error("unable to get charts data", e);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
init();
View rootView = inflater.inflate(R.layout.fragment_charts, container, false);
mChart = rootView.findViewById(R.id.activitysleepchart);
setupChart();
populate_charts_data();
return rootView;
}
@Override
public String getTitle() {
return getString(R.string.activity_sleepchart_activity_and_sleep);
}
private void setupChart() {
mChart.setBackgroundColor(BACKGROUND_COLOR);
mChart.getDescription().setTextColor(DESCRIPTION_COLOR);
configureBarLineChartDefaults(mChart);
XAxis x = mChart.getXAxis();
x.setDrawLabels(true);
x.setDrawGridLines(false);
x.setEnabled(true);
x.setTextColor(CHART_TEXT_COLOR);
x.setDrawLimitLinesBehindData(true);
YAxis y = mChart.getAxisLeft();
y.setDrawGridLines(false);
// y.setDrawLabels(false);
// TODO: make fixed max value optional
y.setAxisMaximum(1f);
y.setAxisMinimum(0);
y.setDrawTopYLabelEntry(false);
y.setTextColor(CHART_TEXT_COLOR);
// y.setLabelCount(5);
y.setEnabled(true);
YAxis yAxisRight = mChart.getAxisRight();
yAxisRight.setDrawGridLines(false);
yAxisRight.setEnabled(supportsHeartrate(gbDevice));
yAxisRight.setDrawLabels(true);
yAxisRight.setDrawTopYLabelEntry(true);
yAxisRight.setTextColor(CHART_TEXT_COLOR);
yAxisRight.setAxisMaximum(HeartRateUtils.getInstance().getMaxHeartRate());
yAxisRight.setAxisMinimum(HeartRateUtils.getInstance().getMinHeartRate());
}
@Override
protected List<? extends ActivitySample> getSamples(DBHandler db, GBDevice device, int tsFrom, int tsTo) {
return getAllSamples(db, device, tsFrom, tsTo);
}
@Override
protected void setupLegend(Chart chart) {
List<LegendEntry> legendEntries = new ArrayList<>(5);
LegendEntry activityEntry = new LegendEntry();
activityEntry.label = akActivity.label;
activityEntry.formColor = akActivity.color;
legendEntries.add(activityEntry);
if (supportsHeartrate(gbDevice)) {
LegendEntry hrEntry = new LegendEntry();
hrEntry.label = HEARTRATE_LABEL;
hrEntry.formColor = HEARTRATE_COLOR;
legendEntries.add(hrEntry);
}
chart.getLegend().setCustom(legendEntries);
chart.getLegend().setWordWrapEnabled(true);
chart.getLegend().setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER);
}
@Override
protected ChartsData refreshInBackground(ChartsHost chartsHost, DBHandler db, GBDevice device) {
return null;
}
@Override
protected void renderCharts() {
}
protected Entry createLineEntry(float value, int xValue) {
return new Entry(xValue, value);
}
@Override
protected void updateChartsnUIThread(ChartsData chartsData) {
}
}

View File

@ -67,7 +67,6 @@ import nodomain.freeyourgadget.gadgetbridge.util.AndroidUtils;
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
import nodomain.freeyourgadget.gadgetbridge.util.SwipeEvents;
//import nodomain.freeyourgadget.gadgetbridge.util.OnSwipeTouchListener;
public class ActivitySummaryDetail extends AbstractGBActivity {
@ -123,6 +122,13 @@ public class ActivitySummaryDetail extends AbstractGBActivity {
this,
R.anim.bounceright);
final ActivitySummariesChartFragment activitySummariesChartFragment = new ActivitySummariesChartFragment();
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragmentHolder, activitySummariesChartFragment)
.commit();
layout.setOnTouchListener(new SwipeEvents(this) {
@Override
public void onSwipeRight() {
@ -131,6 +137,7 @@ public class ActivitySummaryDetail extends AbstractGBActivity {
currentItem = newItem;
makeSummaryHeader(newItem);
makeSummaryContent(newItem);
activitySummariesChartFragment.setDateAndGetData(gbDevice, currentItem.getStartTime().getTime()/1000, currentItem.getEndTime().getTime()/1000);
layout.startAnimation(animFadeRight);
} else {
@ -145,6 +152,7 @@ public class ActivitySummaryDetail extends AbstractGBActivity {
currentItem = newItem;
makeSummaryHeader(newItem);
makeSummaryContent(newItem);
activitySummariesChartFragment.setDateAndGetData(gbDevice, currentItem.getStartTime().getTime()/1000, currentItem.getEndTime().getTime()/1000);
layout.startAnimation(animFadeLeft);
} else {
layout.startAnimation(animBounceLeft);
@ -156,8 +164,10 @@ public class ActivitySummaryDetail extends AbstractGBActivity {
if (currentItem != null) {
makeSummaryHeader(currentItem);
makeSummaryContent(currentItem);
activitySummariesChartFragment.setDateAndGetData(gbDevice, currentItem.getStartTime().getTime()/1000, currentItem.getEndTime().getTime()/1000);
}
//allows long-press.switch of data being in raw form or recalculated
ImageView activity_icon = findViewById(R.id.item_image);
activity_icon.setOnLongClickListener(new View.OnLongClickListener() {

View File

@ -420,7 +420,7 @@ public abstract class AbstractChartFragment extends AbstractGBFragment {
*/
protected abstract void renderCharts();
protected DefaultChartsData<LineData> refresh(GBDevice gbDevice, List<? extends ActivitySample> samples) {
public DefaultChartsData<LineData> refresh(GBDevice gbDevice, List<? extends ActivitySample> samples) {
// Calendar cal = GregorianCalendar.getInstance();
// cal.clear();
TimestampTranslation tsTranslation = new TimestampTranslation();
@ -844,7 +844,7 @@ public abstract class AbstractChartFragment extends AbstractGBFragment {
* It does this so that the large timestamp values can be used
* floating point values, where the mantissa is just 24 bits.
*/
protected static class TimestampTranslation {
public static class TimestampTranslation {
private int tsOffset = -1;
public int shorten(int timestamp) {

View File

@ -4,17 +4,17 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M7.8778,13.4059A4.9498,4.9497 70.0081,0 1,4.0689 8.8757,4.9498 4.9497,70.0081 0,1 7.325,3.9333 4.9498,4.9497 70.0081,0 1,12.9905 5.6452,4.9498 4.9497,70.0081 0,1 12.9651,11.5638"
android:pathData="M8.9746,3.6387A4.9498,4.9497 70,0 0,7.3242 3.9336A4.9498,4.9497 70,0 0,4.0684 8.875A4.9498,4.9497 70,0 0,7.877 13.4063L12.9648,11.5645A4.9498,4.9497 70,0 0,12.9902 5.6445A4.9498,4.9497 70,0 0,8.9746 3.6387zM6.5664,6.8301A1.5,1.5 0,0 1,8.0664 8.3301A1.5,1.5 0,0 1,6.5664 9.8301A1.5,1.5 0,0 1,5.0664 8.3301A1.5,1.5 0,0 1,6.5664 6.8301z"
android:strokeWidth="1"
android:fillColor="@color/secondarytext"
android:strokeColor="@color/secondarytext"
android:fillColor="#000000"
android:strokeColor="#000000"
android:strokeLineCap="square"/>
<path
android:pathData="M9.9193,14.1876 L11.414,18.0784 13.2716,17.4023 11.8968,13.4432"
android:strokeLineJoin="miter"
android:strokeWidth="1"
android:fillColor="#00000000"
android:strokeColor="@color/secondarytext"
android:strokeColor="#000000"
android:fillType="evenOdd"
android:strokeLineCap="butt"/>
<path
@ -22,7 +22,7 @@
android:strokeLineJoin="miter"
android:strokeWidth="1"
android:fillColor="#00000000"
android:strokeColor="@color/secondarytext"
android:strokeColor="#000000"
android:fillType="evenOdd"
android:strokeLineCap="butt"/>
<path
@ -30,7 +30,7 @@
android:strokeLineJoin="miter"
android:strokeWidth="1"
android:fillColor="#00000000"
android:strokeColor="@color/secondarytext"
android:strokeColor="#000000"
android:fillType="evenOdd"
android:strokeLineCap="butt"/>
<path
@ -38,7 +38,7 @@
android:strokeLineJoin="miter"
android:strokeWidth="1"
android:fillColor="#00000000"
android:strokeColor="@color/secondarytext"
android:strokeColor="#000000"
android:fillType="evenOdd"
android:strokeLineCap="butt"/>
<path
@ -46,51 +46,45 @@
android:strokeLineJoin="miter"
android:strokeWidth="1"
android:fillColor="#00000000"
android:strokeColor="@color/secondarytext"
android:strokeColor="#000000"
android:fillType="evenOdd"
android:strokeLineCap="butt"/>
<path
android:pathData="M6.5669,8.3299m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0"
android:strokeWidth="0.999997"
android:fillColor="#ffffff"
android:strokeColor="#00000000"
android:strokeLineCap="square"/>
<path
android:pathData="m12.592,11.587a4.9498,4.9497 110.0081,0 1,-0.0058 -5.9186,4.9498 4.9497,110.0081 0,1 5.6712,-1.6931 4.9498,4.9497 110.0081,0 1,3.2397 4.9532,4.9498 4.9497,110.0081 0,1 -3.8239,4.5176"
android:strokeWidth="1"
android:fillColor="#feffff"
android:strokeColor="@color/secondarytext"
android:fillColor="#00000000"
android:strokeColor="#000000"
android:strokeLineCap="square"/>
<path
android:pathData="m13.6568,13.5029 l-1.3593,3.9365 1.8576,0.6761 1.5002,-3.9281"
android:strokeLineJoin="miter"
android:strokeWidth="1"
android:fillColor="#ffffff"
android:strokeColor="@color/secondarytext"
android:fillColor="#00000000"
android:strokeColor="#000000"
android:fillType="evenOdd"
android:strokeLineCap="butt"/>
<path
android:pathData="m17.6826,13.4392c-2.1765,0.4425 -2.009,0.896 -2.1939,1.0122"
android:strokeLineJoin="miter"
android:strokeWidth="1"
android:fillColor="#ffffff"
android:strokeColor="@color/secondarytext"
android:fillColor="#00000000"
android:strokeColor="#000000"
android:fillType="evenOdd"
android:strokeLineCap="butt"/>
<path
android:pathData="m12.5971,11.5883c1.3602,1.7298 0.9547,2.0183 1.02,2.2256"
android:strokeLineJoin="miter"
android:strokeWidth="1"
android:fillColor="#ffffff"
android:strokeColor="@color/secondarytext"
android:fillColor="#00000000"
android:strokeColor="#000000"
android:fillType="evenOdd"
android:strokeLineCap="butt"/>
<path
android:pathData="M17.6826,13.4392 L12.5971,11.5883"
android:strokeLineJoin="miter"
android:strokeWidth="1"
android:fillColor="#ffffff"
android:strokeColor="@color/secondarytext"
android:fillColor="#00000000"
android:strokeColor="#000000"
android:fillType="evenOdd"
android:strokeLineCap="butt"/>
</vector>

View File

@ -165,6 +165,13 @@
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<FrameLayout
android:id="@+id/fragmentHolder"
android:layout_width="match_parent"
android:layout_height="300dp">
</FrameLayout>
<Button
android:id="@+id/showTrack"
android:layout_width="match_parent"