kopia lustrzana https://github.com/SP8EBC/MeteoSystem
improvements in wind speeds plot formatting
rodzic
aaf7021444
commit
070052a158
|
@ -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'
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,15 +8,15 @@
|
|||
android:layout_height="match_parent">
|
||||
|
||||
<com.github.mikephil.charting.charts.LineChart
|
||||
android:id="@+id/chart1"
|
||||
android:id="@+id/chartPlotsWind"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="top|left" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvXMax"
|
||||
android:layout_width="245dp"
|
||||
android:layout_height="48dp"
|
||||
android:id="@+id/textViewPlotsWindTimestamp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="40dp"
|
||||
android:layout_gravity="top|left"
|
||||
android:layout_marginRight="10dp"
|
||||
android:layout_marginBottom="15dp"
|
||||
|
@ -25,10 +25,40 @@
|
|||
android:textAlignment="center"
|
||||
android:textAllCaps="true"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:textSize="24sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textViewPlotsWindMean"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:layout_gravity="left"
|
||||
android:layout_marginTop="40dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:layout_marginBottom="15dp"
|
||||
android:gravity="right"
|
||||
android:text="Avg:"
|
||||
android:textAlignment="textStart"
|
||||
android:textAllCaps="false"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:textSize="30sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textViewPlotsWindGusts"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:layout_gravity="left"
|
||||
android:layout_marginTop="40dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:layout_marginBottom="15dp"
|
||||
android:gravity="right"
|
||||
android:text="Max:"
|
||||
android:textAlignment="textEnd"
|
||||
android:textAllCaps="false"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:textSize="30sp" />
|
||||
|
||||
<SeekBar
|
||||
android:id="@+id/seekBar1"
|
||||
android:id="@+id/seekBarPlotsWind"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:title="@string/add_fav" />
|
||||
<item android:title="@string/delete_fav" />
|
||||
</menu>
|
|
@ -18,7 +18,7 @@
|
|||
<string name="date">Date</string>
|
||||
<string name="add">Add</string>
|
||||
<string name="delete">Delete</string>
|
||||
<string name="delete_fav">Delete from favourities stations list</string>
|
||||
<string name="delete_fav">Delete from favourities</string>
|
||||
<string name="station_not_comm">Warning! This station doesn\'t send any data for longer than 4 hours</string>
|
||||
<string name="station_disabled">Warning! This station has been temporarily disabled or it is not functional for long time</string>
|
||||
<string name="archive_data">Archival Data</string>
|
||||
|
@ -38,4 +38,7 @@
|
|||
<string name="apply">Apply</string>
|
||||
<string name="cancel">Cancel</string>
|
||||
<string name="wind_rose">Wind Rose</string>
|
||||
<string name="mean_value_short">Avg:</string>
|
||||
<string name="max_value_short">Max:</string>
|
||||
<string name="add_fav">Add to favourities</string>
|
||||
</resources>
|
|
@ -38,4 +38,7 @@
|
|||
<string name="apply">-</string>
|
||||
<string name="cancel">-</string>
|
||||
<string name="wind_rose">-</string>
|
||||
<string name="mean_value_short">-</string>
|
||||
<string name="max_value_short">-</string>
|
||||
<string name="add_fav">-</string>
|
||||
</resources>
|
|
@ -38,4 +38,8 @@
|
|||
<string name="apply">-</string>
|
||||
<string name="cancel">-</string>
|
||||
<string name="wind_rose">-</string>
|
||||
<string name="mean_value_short">-</string>
|
||||
<string name="max_value_short">-</string>
|
||||
<string name="add_fav">-</string>
|
||||
|
||||
</resources>
|
|
@ -18,7 +18,7 @@
|
|||
<string name="date">Data</string>
|
||||
<string name="add">Dodaj</string>
|
||||
<string name="delete">Usuń</string>
|
||||
<string name="delete_fav">Usuń z listy ulubionych stacji</string>
|
||||
<string name="delete_fav">Usuń z ulubionych</string>
|
||||
<string name="station_not_comm">Uwaga! Ta stacja nie wysyła żadnych danych dłużej niż od 4 godzin</string>
|
||||
<string name="station_disabled">Uwaga! Stacja została tymczasowo wyłączona bądź nie pracuje od dłuższego czasu</string>
|
||||
<string name="archive_data">Dane Archiwalne</string>
|
||||
|
@ -38,4 +38,7 @@
|
|||
<string name="apply">Zastosuj</string>
|
||||
<string name="cancel">Anuluj</string>
|
||||
<string name="wind_rose">Róża Wiatrów</string>
|
||||
<string name="mean_value_short">Śr:</string>
|
||||
<string name="max_value_short">Max:</string>
|
||||
<string name="add_fav">Dodaj do ulubionych</string>
|
||||
</resources>
|
|
@ -18,7 +18,7 @@
|
|||
<string name="date">Data</string>
|
||||
<string name="add">Dodaj</string>
|
||||
<string name="delete">Usuń</string>
|
||||
<string name="delete_fav">Usuń z listy ulubionych stacji</string>
|
||||
<string name="delete_fav">Usuń z ulubionych</string>
|
||||
<string name="station_not_comm">Uwaga! Ta stacja nie wysyła żadnych danych dłużej niż od 4 godzin</string>
|
||||
<string name="station_disabled">Uwaga! Stacja została tymczasowo wyłączona bądź nie pracuje od dłuższego czasu</string>
|
||||
<string name="archive_data">Dane Archiwalne</string>
|
||||
|
@ -38,4 +38,7 @@
|
|||
<string name="apply">Zastosuj</string>
|
||||
<string name="cancel">Anuluj</string>
|
||||
<string name="wind_rose">Róża Wiatrów</string>
|
||||
<string name="mean_value_short">Śr:</string>
|
||||
<string name="max_value_short">Max:</string>
|
||||
<string name="add_fav">Ddoaj do ulubionych</string>
|
||||
</resources>
|
|
@ -17,7 +17,7 @@
|
|||
<string name="date">Date</string>
|
||||
<string name="add">Add</string>
|
||||
<string name="delete">Delete</string>
|
||||
<string name="delete_fav">Delete from favourities stations list</string>
|
||||
<string name="delete_fav">Delete from favourities</string>
|
||||
<string name="station_not_comm">Warning! This station doesn\'t send any data for longer than 4 hours</string>
|
||||
<string name="station_disabled">Warning! This station has been temporarily disabled or it is not functional for long time</string>
|
||||
<string name="archive_data">Archival Data</string>
|
||||
|
@ -37,4 +37,7 @@
|
|||
<string name="apply">Apply</string>
|
||||
<string name="cancel">Cancel</string>
|
||||
<string name="wind_rose">Wind Rose</string>
|
||||
<string name="mean_value_short">Avg:</string>
|
||||
<string name="max_value_short">Max:</string>
|
||||
<string name="add_fav">Add to favourites</string>
|
||||
</resources>
|
Ładowanie…
Reference in New Issue