diff options
author | Tony Rankin <tonyr@tonyrankin.com> | 2015-03-04 13:30:53 -0800 |
---|---|---|
committer | Tony Rankin <tonyr@tonyrankin.com> | 2015-03-04 13:30:53 -0800 |
commit | 9078231f12e8aa21cade34e07fcc886ef85421d3 (patch) | |
tree | d9e94e994dbbbf3fe3ce88577897c6f943519b36 /WordPress/src/main/java/org | |
parent | 1cc181ee7479c62e1be52358d74b572939ed9200 (diff) | |
parent | 067b97e527578c13ea2d17c3dde5002be1807c40 (diff) | |
download | gradle-perf-android-medium-9078231f12e8aa21cade34e07fcc886ef85421d3.tar.gz |
Merge pull request #2377 from wordpress-mobile/issue/2347-new-approach-views-visitors
Stats - New approach on comparing Views and Visitors
Diffstat (limited to 'WordPress/src/main/java/org')
7 files changed, 155 insertions, 37 deletions
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsBarGraph.java b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsBarGraph.java index 2a2bbd71b..1eb405701 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsBarGraph.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsBarGraph.java @@ -110,20 +110,9 @@ class StatsBarGraph extends GraphView { } } - private class HorizontalLabelsBackgroundColor implements IndexDependentColor { - public int get(int index) { - if (mBarPositionToHighlight == index) { - return getResources().getColor(R.color.calypso_orange_dark); - } else { - return Color.WHITE; - } - } - } - private void setProperties() { GraphViewStyle gStyle = getGraphViewStyle(); gStyle.setHorizontalLabelsIndexDependentColor(new HorizontalLabelsColor()); - gStyle.setHorizontalLabelsBackgroundIndexDependentColor(new HorizontalLabelsBackgroundColor()); gStyle.setHorizontalLabelsColor(getResources().getColor(R.color.blue_dark)); gStyle.setVerticalLabelsColor(getResources().getColor(R.color.stats_bar_graph_vertical_label)); gStyle.setTextSize(getResources().getDimensionPixelSize(R.dimen.text_sz_extra_small)); @@ -158,6 +147,10 @@ class StatsBarGraph extends GraphView { double minY, double diffX, double diffY, float horstart, GraphViewSeriesStyle style) { float colwidth = graphwidth / values.length; + int maxColumnSize = getGraphViewStyle().getMaxColumnWidth(); + if (maxColumnSize > 0 && colwidth > maxColumnSize) { + colwidth = maxColumnSize; + } paint.setStrokeWidth(style.thickness); paint.setColor(style.color); @@ -184,9 +177,8 @@ class StatsBarGraph extends GraphView { float bottom = graphheight + border - 1; // Draw the orange selection behind the selected bar - if (mBarPositionToHighlight == i) { - paint.setColor(getResources().getColor(R.color.calypso_orange_dark)); - paint.setAlpha(50); + if (mBarPositionToHighlight == i && style.outerhighlightColor != 0x00ffffff) { + paint.setColor(style.outerhighlightColor); canvas.drawRect(left, 10f, right, bottom, paint); } @@ -204,7 +196,7 @@ class StatsBarGraph extends GraphView { // draw a real bar paint.setAlpha(255); if (mBarPositionToHighlight == i) { - paint.setColor(getResources().getColor(R.color.calypso_orange_dark)); + paint.setColor(style.highlightColor); } else { paint.setColor(style.color); } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsConstants.java b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsConstants.java index 614064b81..267b6a250 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsConstants.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsConstants.java @@ -10,6 +10,6 @@ public class StatsConstants { public static final String STATS_OUTPUT_DATE_MONTH_LONG_FORMAT = "MMMM"; public static final String STATS_OUTPUT_DATE_YEAR_FORMAT = "yyyy"; - + public static final int STATS_GRAPH_BAR_MAX_COLUMN_WIDTH_DP = 100; } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsSinglePostDetailsActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsSinglePostDetailsActivity.java index 70a1d6346..bce095c02 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsSinglePostDetailsActivity.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsSinglePostDetailsActivity.java @@ -342,6 +342,9 @@ public class StatsSinglePostDetailsActivity extends ActionBarActivity mGraphView.addSeries(mCurrentSeriesOnScreen); //mGraphView.getGraphViewStyle().setNumHorizontalLabels(getNumOfHorizontalLabels(dataToShowOnGraph.length)); mGraphView.getGraphViewStyle().setNumHorizontalLabels(dataToShowOnGraph.length); + mGraphView.getGraphViewStyle().setMaxColumnWidth( + DisplayUtils.dpToPx(this, StatsConstants.STATS_GRAPH_BAR_MAX_COLUMN_WIDTH_DP) + ); mGraphView.setHorizontalLabels(horLabels); mGraphView.setGestureListener(this); mSelectedBarGraphIndex = (mSelectedBarGraphIndex != -1) ? mSelectedBarGraphIndex : dataToShowOnGraph.length - 1; diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsUtils.java b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsUtils.java index 42cfbd852..76b1e1f7b 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsUtils.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsUtils.java @@ -5,6 +5,7 @@ import android.content.Context; import android.content.SharedPreferences; import android.preference.PreferenceManager; +import com.android.volley.NetworkResponse; import com.android.volley.VolleyError; import org.json.JSONException; @@ -270,6 +271,20 @@ public class StatsUtils { } } + public static synchronized void logVolleyErrorDetails(final VolleyError volleyError) { + if (volleyError == null) { + AppLog.e(T.STATS, "Tried to log a VolleyError, but the error obj was null!"); + return; + } + if (volleyError.networkResponse != null) { + NetworkResponse networkResponse = volleyError.networkResponse; + AppLog.e(T.STATS, "Network status code: " + networkResponse.statusCode); + if (networkResponse.data != null) { + AppLog.e(T.STATS, "Network data: " + new String(networkResponse.data)); + } + } + AppLog.e(T.STATS, "Volley Error details: " + volleyError.getMessage(), volleyError); + } public static synchronized Serializable parseResponse(StatsService.StatsEndpointsEnum endpointName, String blogID, JSONObject response) throws JSONException { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsViewAllActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsViewAllActivity.java index 7fcb5d93a..05aa95770 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsViewAllActivity.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsViewAllActivity.java @@ -431,10 +431,9 @@ public class StatsViewAllActivity extends ActionBarActivity @Override public void onErrorResponse(final VolleyError volleyError) { - if (volleyError != null) { - AppLog.e(AppLog.T.STATS, "Error while reading Stats details " - + volleyError.getMessage(), volleyError); - } + AppLog.e(AppLog.T.STATS, "Error while reading Stats details!"); + StatsUtils.logVolleyErrorDetails(volleyError); + if (mActivityRef.get() == null || mActivityRef.get().isFinishing()) { return; } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsVisitorsAndViewsFragment.java b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsVisitorsAndViewsFragment.java index 78b7a4961..cfdadb6e0 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsVisitorsAndViewsFragment.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/StatsVisitorsAndViewsFragment.java @@ -6,16 +6,16 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.graphics.drawable.Drawable; +import android.os.Build; import android.os.Bundle; import android.support.v4.content.LocalBroadcastManager; -import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.CheckBox; import android.widget.CheckedTextView; import android.widget.ImageView; import android.widget.LinearLayout; -import android.widget.RadioGroup; import android.widget.TextView; import com.android.volley.VolleyError; @@ -35,7 +35,6 @@ import org.wordpress.android.util.DisplayUtils; import org.wordpress.android.util.FormatUtils; import org.wordpress.android.util.NetworkUtils; import org.wordpress.android.util.StringUtils; -import org.wordpress.android.widgets.TypefaceCache; import java.io.Serializable; import java.text.ParseException; @@ -51,14 +50,21 @@ public class StatsVisitorsAndViewsFragment extends StatsAbstractFragment public static final String TAG = StatsVisitorsAndViewsFragment.class.getSimpleName(); private static final String ARG_SELECTED_GRAPH_BAR = "ARG_SELECTED_GRAPH_BAR"; private static final String ARG_SELECTED_OVERVIEW_ITEM = "ARG_SELECTED_OVERVIEW_ITEM"; + private static final String ARG_CHECKBOX_SELECTED = "ARG_CHECKBOX_SELECTED"; + private LinearLayout mGraphContainer; private StatsBarGraph mGraphView; - private GraphViewSeries mCurrentSeriesOnScreen; private LinearLayout mModuleButtonsContainer; private TextView mDateTextView; private String[] mStatsDate; + private LinearLayout mLegendContainer; + private CheckedTextView mLegendLabel; + private LinearLayout mVisitorsCheckboxContainer; + private CheckBox mVisitorsCheckbox; + private boolean mIsCheckboxChecked; + private OnDateChangeListener mListener; final OverviewLabel[] overviewItems = {OverviewLabel.VIEWS, OverviewLabel.VISITORS, OverviewLabel.LIKES, @@ -92,6 +98,19 @@ public class StatsVisitorsAndViewsFragment extends StatsAbstractFragment mGraphContainer = (LinearLayout) view.findViewById(R.id.stats_bar_chart_fragment_container); mModuleButtonsContainer = (LinearLayout) view.findViewById(R.id.stats_pager_tabs); + mLegendContainer = (LinearLayout) view.findViewById(R.id.stats_legend_container); + mLegendLabel = (CheckedTextView) view.findViewById(R.id.stats_legend_label); + mLegendLabel.setCheckMarkDrawable(null); // Make sure to set a null drawable here. Otherwise the touching area is the same of a TextView + mVisitorsCheckboxContainer = (LinearLayout) view.findViewById(R.id.stats_checkbox_visitors_container); + mVisitorsCheckbox = (CheckBox) view.findViewById(R.id.stats_checkbox_visitors); + mVisitorsCheckbox.setOnClickListener(onCheckboxClicked); + + // Fix an issue on devices with 4.1 or lower, where the Checkbox already uses padding by default internally and overriding it with paddingLeft + // causes the issue report here https://github.com/wordpress-mobile/WordPress-Android/pull/2377#issuecomment-77067993 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { + mVisitorsCheckbox.setPadding(getResources().getDimensionPixelSize(R.dimen.margin_medium), 0, 0, 0); + } + // Make sure we've all the info to build the tab correctly. This is ALWAYS true if (mModuleButtonsContainer.getChildCount() == overviewItems.length) { for (int i = 0; i < mModuleButtonsContainer.getChildCount(); i++) { @@ -213,6 +232,16 @@ public class StatsVisitorsAndViewsFragment extends StatsAbstractFragment } }; + + View.OnClickListener onCheckboxClicked = new View.OnClickListener() { + @Override + public void onClick(View view) { + // Is the view now checked? + mIsCheckboxChecked = ((CheckBox) view).isChecked(); + updateUI(); + } + }; + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -227,6 +256,10 @@ public class StatsVisitorsAndViewsFragment extends StatsAbstractFragment if (savedInstanceState.containsKey(ARG_SELECTED_GRAPH_BAR)) { mSelectedBarGraphBarIndex = savedInstanceState.getInt(ARG_SELECTED_GRAPH_BAR, -1); } + + mIsCheckboxChecked = savedInstanceState.getBoolean(ARG_CHECKBOX_SELECTED, true); + } else { + mIsCheckboxChecked = true; } } @@ -242,6 +275,7 @@ public class StatsVisitorsAndViewsFragment extends StatsAbstractFragment outState.putSerializable(ARG_REST_RESPONSE, mVisitsData); outState.putInt(ARG_SELECTED_GRAPH_BAR, mSelectedBarGraphBarIndex); outState.putInt(ARG_SELECTED_OVERVIEW_ITEM, mSelectedOverviewItemIndex); + outState.putBoolean(ARG_CHECKBOX_SELECTED, mVisitorsCheckbox.isChecked()); super.onSaveInstanceState(outState); } @@ -302,13 +336,34 @@ public class StatsVisitorsAndViewsFragment extends StatsAbstractFragment return; } + // Read the selected Tab in the UI + OverviewLabel selectedStatsType = overviewItems[mSelectedOverviewItemIndex]; + // Update the Legend and enable/disable the visitors checkboxes + mLegendContainer.setVisibility(View.VISIBLE); + mLegendLabel.setText(StringUtils.capitalize(selectedStatsType.getLabel().toLowerCase())); + switch(selectedStatsType) { + case VIEWS: + mVisitorsCheckboxContainer.setVisibility(View.VISIBLE); + mVisitorsCheckbox.setEnabled(true); + mVisitorsCheckbox.setChecked(mIsCheckboxChecked); + break; + default: + mVisitorsCheckboxContainer.setVisibility(View.GONE); + break; + } + + // Setting Up labels and prepare variables that hold series final String[] horLabels = new String[dataToShowOnGraph.length]; mStatsDate = new String[dataToShowOnGraph.length]; - GraphView.GraphViewData[] views = new GraphView.GraphViewData[dataToShowOnGraph.length]; + GraphView.GraphViewData[] mainSeriesItems = new GraphView.GraphViewData[dataToShowOnGraph.length]; - OverviewLabel selectedStatsType = overviewItems[mSelectedOverviewItemIndex]; + GraphView.GraphViewData[] secondarySeriesItems = null; + if (mIsCheckboxChecked && selectedStatsType == OverviewLabel.VIEWS) { + secondarySeriesItems = new GraphView.GraphViewData[dataToShowOnGraph.length]; + } + // Fill series variables with data for (int i = 0; i < dataToShowOnGraph.length; i++) { int currentItemValue = 0; switch(selectedStatsType) { @@ -325,18 +380,17 @@ public class StatsVisitorsAndViewsFragment extends StatsAbstractFragment currentItemValue = dataToShowOnGraph[i].getComments(); break; } - views[i] = new GraphView.GraphViewData(i, currentItemValue); + mainSeriesItems[i] = new GraphView.GraphViewData(i, currentItemValue); + + if (mIsCheckboxChecked && secondarySeriesItems != null) { + secondarySeriesItems[i] = new GraphView.GraphViewData(i, dataToShowOnGraph[i].getVisitors()); + } String currentItemStatsDate = dataToShowOnGraph[i].getPeriod(); horLabels[i] = getDateLabelForBarInGraph(currentItemStatsDate); mStatsDate[i] = currentItemStatsDate; } - mCurrentSeriesOnScreen = new GraphViewSeries(views); - mCurrentSeriesOnScreen.getStyle().color = getResources().getColor(R.color.stats_bar_graph_views); - mCurrentSeriesOnScreen.getStyle().padding = DisplayUtils.dpToPx(getActivity(), 5); - - if (mGraphContainer.getChildCount() >= 1 && mGraphContainer.getChildAt(0) instanceof GraphView) { mGraphView = (StatsBarGraph) mGraphContainer.getChildAt(0); } else { @@ -346,10 +400,44 @@ public class StatsVisitorsAndViewsFragment extends StatsAbstractFragment } mGraphView.removeAllSeries(); - mGraphView.addSeries(mCurrentSeriesOnScreen); - //mGraphView.getGraphViewStyle().setNumHorizontalLabels(getNumOfHorizontalLabels(dataToShowOnGraph.length)); + + GraphViewSeries mainSeriesOnScreen = new GraphViewSeries(mainSeriesItems); + mainSeriesOnScreen.getStyle().color = getResources().getColor(R.color.stats_bar_graph_views); + mainSeriesOnScreen.getStyle().highlightColor = getResources().getColor(R.color.calypso_orange_dark); + mainSeriesOnScreen.getStyle().outerhighlightColor = getResources().getColor(R.color.stats_bar_graph_outer_highlight); + mainSeriesOnScreen.getStyle().padding = DisplayUtils.dpToPx(getActivity(), 5); + mGraphView.addSeries(mainSeriesOnScreen); + + // Add the Visitors series if it's checked in the legend + if (mIsCheckboxChecked && secondarySeriesItems != null && selectedStatsType == OverviewLabel.VIEWS) { + GraphViewSeries secondarySeries = new GraphViewSeries(secondarySeriesItems); + secondarySeries.getStyle().padding = DisplayUtils.dpToPx(getActivity(), 10); + secondarySeries.getStyle().color = getResources().getColor(R.color.stats_bar_graph_views_inner); + secondarySeries.getStyle().highlightColor = getResources().getColor(R.color.orange_dark); + mGraphView.addSeries(secondarySeries); + } + + // Setup the Y-axis on Visitors and Views Tabs. + // Views and Visitors tabs have the exact same Y-axis as shifting from one Y-axis to another defeats + // the purpose of making these bars visually easily to compare. + switch(selectedStatsType) { + case VISITORS: + double maxYValue = getMaxYValueForVisitorsAndView(dataToShowOnGraph); + mGraphView.setManualYAxisBounds(maxYValue, 0d); + break; + default: + mGraphView.setManualYAxis(false); + break; + } + + // Set the Graph Style mGraphView.getGraphViewStyle().setNumHorizontalLabels(dataToShowOnGraph.length); + // Set the maximum size a column can get on the screen in PX + mGraphView.getGraphViewStyle().setMaxColumnWidth( + DisplayUtils.dpToPx(getActivity(), StatsConstants.STATS_GRAPH_BAR_MAX_COLUMN_WIDTH_DP) + ); mGraphView.setHorizontalLabels(horLabels); + mGraphView.setGestureListener(this); int barSelectedOnGraph; @@ -371,6 +459,23 @@ public class StatsVisitorsAndViewsFragment extends StatsAbstractFragment mGraphView.highlightBar(barSelectedOnGraph); } + // Find the max value in Visitors and Views data. + // Only checks the Views data, since Visitors is for sure less-equals than Views. + private double getMaxYValueForVisitorsAndView(final VisitModel[] dataToShowOnGraph) { + if (dataToShowOnGraph == null || dataToShowOnGraph.length == 0) { + return 0d; + } + double largest = Integer.MIN_VALUE; + + for (int i = 0; i < dataToShowOnGraph.length; i++) { + int currentItemValue = dataToShowOnGraph[i].getViews(); + if (currentItemValue > largest) { + largest = currentItemValue; + } + } + return largest; + } + //update the area right below the graph private void updateUIBelowTheGraph(int itemPosition) { if (!isAdded()) { @@ -503,6 +608,11 @@ public class StatsVisitorsAndViewsFragment extends StatsAbstractFragment if (!isAdded()) { return; } + + // Hide the legend + mLegendContainer.setVisibility(View.GONE); + mVisitorsCheckboxContainer.setVisibility(View.GONE); + mSelectedBarGraphBarIndex = -1; Context context = mGraphContainer.getContext(); if (context != null) { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/service/StatsService.java b/WordPress/src/main/java/org/wordpress/android/ui/stats/service/StatsService.java index c1211739d..246c7e5bf 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/stats/service/StatsService.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/service/StatsService.java @@ -6,6 +6,7 @@ import android.os.IBinder; import android.support.v4.content.LocalBroadcastManager; import android.text.TextUtils; +import com.android.volley.NetworkResponse; import com.android.volley.Request; import com.android.volley.VolleyError; import com.wordpress.rest.RestRequest; @@ -303,9 +304,7 @@ public class StatsService extends Service { } mNumberOfFinishedNetworkCalls++; AppLog.e(T.STATS, this.getClass().getName() + " responded with an Error"); - if (volleyError != null) { - AppLog.e(T.STATS, "Error details: \n" + volleyError.getMessage(), volleyError); - } + StatsUtils.logVolleyErrorDetails(volleyError); mResponseObjectModel = volleyError; notifySectionUpdated(); checkAllRequestsFinished(); |