From 070052a1582e561d1e48cc675d764ed519933675 Mon Sep 17 00:00:00 2001 From: Mateusz Lubecki Date: Thu, 17 Dec 2020 23:10:45 +0100 Subject: [PATCH] improvements in wind speeds plot formatting --- app/build.gradle | 2 +- .../pogodacc/activity/MainActivity.java | 16 ++- .../activity/StationDetailsActivity.java | 7 ++ .../activity/StationDetailsPlotsWind.java | 116 ++++++++++++++---- .../activity/handler/WindPlotClickEvent.java | 25 +++- .../activity_station_details_plots_wind.xml | 40 +++++- .../main/res/menu/menu_station_details.xml | 6 + app/src/main/res/values-en-rUS/strings.xml | 5 +- app/src/main/res/values-lv-rLV/strings.xml | 3 + app/src/main/res/values-lv/strings.xml | 4 + app/src/main/res/values-pl-rPL/strings.xml | 5 +- app/src/main/res/values-pl/strings.xml | 5 +- app/src/main/res/values/strings.xml | 5 +- 13 files changed, 198 insertions(+), 41 deletions(-) create mode 100644 app/src/main/res/menu/menu_station_details.xml diff --git a/app/build.gradle b/app/build.gradle index a043bde..2257dac 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -47,6 +47,6 @@ dependencies { implementation 'com.squareup.okhttp3:logging-interceptor:3.9.1' implementation 'com.squareup.okhttp3:okhttp:3.9.1' implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0' - + implementation 'com.jakewharton.threetenabp:threetenabp:1.2.1' } \ No newline at end of file diff --git a/app/src/main/java/cc/pogoda/mobile/pogodacc/activity/MainActivity.java b/app/src/main/java/cc/pogoda/mobile/pogodacc/activity/MainActivity.java index 14ebc50..a8c2520 100644 --- a/app/src/main/java/cc/pogoda/mobile/pogodacc/activity/MainActivity.java +++ b/app/src/main/java/cc/pogoda/mobile/pogodacc/activity/MainActivity.java @@ -8,6 +8,8 @@ import android.os.Bundle; import android.view.Menu; import android.widget.ImageButton; +import com.jakewharton.threetenabp.AndroidThreeTen; + import java.util.Locale; import cc.pogoda.mobile.pogodacc.R; @@ -19,12 +21,14 @@ public class MainActivity extends AppCompatActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - Locale locale = new Locale("pl"); - Locale.setDefault(locale); - Resources resources = this.getResources(); - Configuration config = resources.getConfiguration(); - config.setLocale(locale); - resources.updateConfiguration(config, resources.getDisplayMetrics()); + AndroidThreeTen.init(this); + +// Locale locale = new Locale("pl"); +// Locale.setDefault(locale); +// Resources resources = this.getResources(); +// Configuration config = resources.getConfiguration(); +// config.setLocale(locale); +// resources.updateConfiguration(config, resources.getDisplayMetrics()); setContentView(R.layout.activity_main); diff --git a/app/src/main/java/cc/pogoda/mobile/pogodacc/activity/StationDetailsActivity.java b/app/src/main/java/cc/pogoda/mobile/pogodacc/activity/StationDetailsActivity.java index 67d677f..827bd7d 100644 --- a/app/src/main/java/cc/pogoda/mobile/pogodacc/activity/StationDetailsActivity.java +++ b/app/src/main/java/cc/pogoda/mobile/pogodacc/activity/StationDetailsActivity.java @@ -3,6 +3,7 @@ package cc.pogoda.mobile.pogodacc.activity; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; +import android.view.Menu; import android.widget.Button; import android.widget.ImageButton; import android.widget.TextView; @@ -33,6 +34,12 @@ public class StationDetailsActivity extends AppCompatActivity { stationName = null; } + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.menu_station_details, menu); + return true; + } + @Override protected void onCreate(Bundle savedInstanceState) { float station_lat = 0.0f; // szerokość W - E diff --git a/app/src/main/java/cc/pogoda/mobile/pogodacc/activity/StationDetailsPlotsWind.java b/app/src/main/java/cc/pogoda/mobile/pogodacc/activity/StationDetailsPlotsWind.java index 795ec8f..7bb000c 100644 --- a/app/src/main/java/cc/pogoda/mobile/pogodacc/activity/StationDetailsPlotsWind.java +++ b/app/src/main/java/cc/pogoda/mobile/pogodacc/activity/StationDetailsPlotsWind.java @@ -5,6 +5,7 @@ import androidx.appcompat.app.AppCompatActivity; import android.graphics.Color; import android.graphics.Typeface; import android.os.Bundle; +import android.view.Menu; import android.view.MenuItem; import android.widget.SeekBar; import android.widget.TextView; @@ -17,11 +18,16 @@ import com.github.mikephil.charting.data.LineData; import com.github.mikephil.charting.data.LineDataSet; import com.github.mikephil.charting.utils.ColorTemplate; -import java.lang.reflect.Array; +import org.threeten.bp.LocalDateTime; +import org.threeten.bp.ZoneId; +import org.threeten.bp.ZoneOffset; +import org.threeten.bp.ZonedDateTime; +import org.threeten.bp.format.DateTimeFormatter; +import org.threeten.bp.format.FormatStyle; + import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; -import java.util.List; import java.util.Locale; import cc.pogoda.mobile.pogodacc.R; @@ -33,9 +39,11 @@ import cc.pogoda.mobile.pogodacc.type.web.StationData; public class StationDetailsPlotsWind extends AppCompatActivity implements SeekBar.OnSeekBarChangeListener { - private LineChart chart; - private SeekBar seekBarX; - private TextView tvX; + private LineChart chart = null; + private SeekBar seekBarX = null; + private TextView textViewTimestamp = null; + private TextView textViewSpeed = null; + private TextView textViewGusts = null; private LastStationDataDao lastStationDataDao; private WeatherStation station; @@ -51,16 +59,21 @@ public class StationDetailsPlotsWind extends AppCompatActivity implements SeekBa private class ValueFormatter extends com.github.mikephil.charting.formatter.ValueFormatter { - private final SimpleDateFormat mFormat = new SimpleDateFormat("dd MMM HH:mm", Locale.ENGLISH); - - @Override public String getFormattedValue(float value) { - Date date; long millis = (long) value; - date = new Date(millis); - return mFormat.format(date); + + // the web service and the plot always stores the entries as UTC. So first convert epoch timestamp to the LocalDateTime + LocalDateTime utcDateTime = LocalDateTime.ofEpochSecond(millis / 1000, 0, ZoneOffset.UTC); + + // and then shift to the user timezone for convinient display + ZonedDateTime localDateTime = utcDateTime.atZone(ZoneOffset.UTC).withZoneSameInstant(ZoneId.systemDefault()); + + // format only the time to keep X axis clean + String dt = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT).format(localDateTime); + + return dt; } } @@ -80,13 +93,18 @@ public class StationDetailsPlotsWind extends AppCompatActivity implements SeekBa station = (WeatherStation) getIntent().getSerializableExtra("station"); + // download data from web service + this.downloadDataFromWebservice(); + Typeface tfLight = Typeface.MONOSPACE; setTitle("LineChartTime"); - tvX = findViewById(R.id.tvXMax); - seekBarX = findViewById(R.id.seekBar1); - chart = findViewById(R.id.chart1); + textViewTimestamp = findViewById(R.id.textViewPlotsWindTimestamp); + textViewSpeed = findViewById(R.id.textViewPlotsWindMean); + textViewGusts = findViewById(R.id.textViewPlotsWindGusts); + seekBarX = findViewById(R.id.seekBarPlotsWind); + chart = findViewById(R.id.chartPlotsWind); // enable scaling and dragging chart.setDragEnabled(true); @@ -121,16 +139,13 @@ public class StationDetailsPlotsWind extends AppCompatActivity implements SeekBa leftAxis.setDrawGridLines(true); leftAxis.setGranularityEnabled(true); leftAxis.setAxisMinimum(0.0f); - leftAxis.setAxisMaximum(24.0f); + leftAxis.setAxisMaximum(this.findMaxValueForPlotScale()); leftAxis.setYOffset(0.0f); leftAxis.setTextColor(Color.rgb(255, 192, 56)); YAxis rightAxis = chart.getAxisRight(); rightAxis.setEnabled(false); - // download data from web service - this.downloadDataFromWebservice(); - lastDataIndex = valuesWindSpeed.size() - 1; // display only the last data (20% of newest data) @@ -140,6 +155,29 @@ public class StationDetailsPlotsWind extends AppCompatActivity implements SeekBa seekBarX.setProgress(100); } + /** + * This method looks through 'valuesWindGusts' for the maximum value + * @return + */ + protected float findMaxValueForPlotScale() { + float out = 0.0f; + + for (Entry e : valuesWindGusts) { + if (e.getY() > out) { + out = e.getY(); + } + } + + out = (float) Math.ceil(out * 1.3f); + + return out; + } + + /** + * Downloads the data from the web service and stores it as entries ready to be displayed on the + * plot. Web Service gives the data with the epoch timestamp in second resolution, but the plot + * shows the data in millisecond resolution + */ private void downloadDataFromWebservice() { ListOfStationData data = lastStationDataDao.getLastStationData(station.getSystemName()); @@ -155,6 +193,42 @@ public class StationDetailsPlotsWind extends AppCompatActivity implements SeekBa } + /** + * Updates labels placed at the top of the chart with values at the point selected by an user. + * @param date Date & time string in local timezone + */ + public void updateLabels(String date, Entry entry) { + float mean = 0.0f; + float gusts = 0.0f; + + // get a timestamp from the entry + long timestamp = (long) entry.getX(); + + // look for the windspeed coresponding to that timestamp + for (Entry e : valuesWindSpeed) { + // if this is what we are looking for + if (e.getX() == entry.getX()) { + mean = e.getY(); + } + } + + for (Entry e : valuesWindGusts) { + + if (e.getX() == entry.getX()) { + gusts = e.getY(); + } + } + + if (this.textViewGusts != null && this.textViewSpeed != null && this.textViewTimestamp != null) { + this.textViewTimestamp.setText(date); + this.textViewSpeed.setText(getString(R.string.mean_value_short) + String.format(" %.1f", mean)); + this.textViewGusts.setText(getString(R.string.max_value_short) + String.format(" %.1f", gusts)); + } + else { + return; + } + } + /** * * @param from @@ -260,7 +334,7 @@ public class StationDetailsPlotsWind extends AppCompatActivity implements SeekBa // set data chart.setData(line_data); - chart.setDoubleTapToZoomEnabled(true); + chart.setDoubleTapToZoomEnabled(false); chart.setOnChartValueSelectedListener(plotClickEvent); } @@ -287,8 +361,6 @@ public class StationDetailsPlotsWind extends AppCompatActivity implements SeekBa // display only 20% of the set at once int window_size = (int) (valuesWindSpeed.size() * 0.2f); - tvX.setText(String.valueOf(seekBarX.getProgress())); - last_index = (int) ((seekBarX.getProgress() / 100.0f) * valuesWindSpeed.size()); first_index = last_index - window_size; @@ -299,8 +371,6 @@ public class StationDetailsPlotsWind extends AppCompatActivity implements SeekBa this.setData(first_index, last_index, false); - //setData(seekBarX.getProgress(), 50); - // redraw chart.invalidate(); } diff --git a/app/src/main/java/cc/pogoda/mobile/pogodacc/activity/handler/WindPlotClickEvent.java b/app/src/main/java/cc/pogoda/mobile/pogodacc/activity/handler/WindPlotClickEvent.java index b68bc41..f612fc0 100644 --- a/app/src/main/java/cc/pogoda/mobile/pogodacc/activity/handler/WindPlotClickEvent.java +++ b/app/src/main/java/cc/pogoda/mobile/pogodacc/activity/handler/WindPlotClickEvent.java @@ -4,8 +4,14 @@ import com.github.mikephil.charting.data.Entry; import com.github.mikephil.charting.highlight.Highlight; import com.github.mikephil.charting.listener.OnChartValueSelectedListener; -import java.time.LocalDateTime; -import java.util.Calendar; +import org.threeten.bp.LocalDateTime; +import org.threeten.bp.ZoneId; +import org.threeten.bp.ZoneOffset; +import org.threeten.bp.ZonedDateTime; +import org.threeten.bp.format.DateTimeFormatter; +import org.threeten.bp.format.FormatStyle; + +import java.text.SimpleDateFormat; import java.util.Date; import cc.pogoda.mobile.pogodacc.activity.StationDetailsPlotsWind; @@ -24,6 +30,21 @@ public class WindPlotClickEvent implements OnChartValueSelectedListener { float value = e.getX(); long value_int = (long) value; Date date = new Date(value_int); + + // the web service and the plot always stores the entries as UTC. So first convert epoch timestamp to the LocalDateTime + LocalDateTime utcDateTime = LocalDateTime.ofEpochSecond(value_int / 1000, 0, ZoneOffset.UTC); + + // and then shift to the user timezone for convinient display + ZonedDateTime localDateTime = utcDateTime.atZone(ZoneOffset.UTC).withZoneSameInstant(ZoneId.systemDefault()); + + // format the time and date according to current locale + String dt = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM, FormatStyle.SHORT).format(localDateTime); + + // call the function to look for the matching windspeed and gusts vales + // as the 'h' parameter doesn't hold an information about an index in the + // input dataset + parent.updateLabels(dt, e); + return; } diff --git a/app/src/main/res/layout/activity_station_details_plots_wind.xml b/app/src/main/res/layout/activity_station_details_plots_wind.xml index 8307d53..b990f24 100644 --- a/app/src/main/res/layout/activity_station_details_plots_wind.xml +++ b/app/src/main/res/layout/activity_station_details_plots_wind.xml @@ -8,15 +8,15 @@ android:layout_height="match_parent"> + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-en-rUS/strings.xml b/app/src/main/res/values-en-rUS/strings.xml index 66c8ff9..7d49b93 100644 --- a/app/src/main/res/values-en-rUS/strings.xml +++ b/app/src/main/res/values-en-rUS/strings.xml @@ -18,7 +18,7 @@ Date Add Delete - Delete from favourities stations list + Delete from favourities Warning! This station doesn\'t send any data for longer than 4 hours Warning! This station has been temporarily disabled or it is not functional for long time Archival Data @@ -38,4 +38,7 @@ Apply Cancel Wind Rose + Avg: + Max: + Add to favourities \ No newline at end of file diff --git a/app/src/main/res/values-lv-rLV/strings.xml b/app/src/main/res/values-lv-rLV/strings.xml index 59ca448..ad8c145 100644 --- a/app/src/main/res/values-lv-rLV/strings.xml +++ b/app/src/main/res/values-lv-rLV/strings.xml @@ -38,4 +38,7 @@ - - - + - + - + - \ No newline at end of file diff --git a/app/src/main/res/values-lv/strings.xml b/app/src/main/res/values-lv/strings.xml index 59ca448..3a6b9f0 100644 --- a/app/src/main/res/values-lv/strings.xml +++ b/app/src/main/res/values-lv/strings.xml @@ -38,4 +38,8 @@ - - - + - + - + - + \ No newline at end of file diff --git a/app/src/main/res/values-pl-rPL/strings.xml b/app/src/main/res/values-pl-rPL/strings.xml index 4ffc6ae..b01f899 100644 --- a/app/src/main/res/values-pl-rPL/strings.xml +++ b/app/src/main/res/values-pl-rPL/strings.xml @@ -18,7 +18,7 @@ Data Dodaj Usuń - Usuń z listy ulubionych stacji + Usuń z ulubionych Uwaga! Ta stacja nie wysyła żadnych danych dłużej niż od 4 godzin Uwaga! Stacja została tymczasowo wyłączona bądź nie pracuje od dłuższego czasu Dane Archiwalne @@ -38,4 +38,7 @@ Zastosuj Anuluj Róża Wiatrów + Śr: + Max: + Dodaj do ulubionych \ No newline at end of file diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 97dd7ab..8b70f18 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -18,7 +18,7 @@ Data Dodaj Usuń - Usuń z listy ulubionych stacji + Usuń z ulubionych Uwaga! Ta stacja nie wysyła żadnych danych dłużej niż od 4 godzin Uwaga! Stacja została tymczasowo wyłączona bądź nie pracuje od dłuższego czasu Dane Archiwalne @@ -38,4 +38,7 @@ Zastosuj Anuluj Róża Wiatrów + Śr: + Max: + Ddoaj do ulubionych \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a53b3d2..10251c3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -17,7 +17,7 @@ Date Add Delete - Delete from favourities stations list + Delete from favourities Warning! This station doesn\'t send any data for longer than 4 hours Warning! This station has been temporarily disabled or it is not functional for long time Archival Data @@ -37,4 +37,7 @@ Apply Cancel Wind Rose + Avg: + Max: + Add to favourites \ No newline at end of file