Permalink
Browse files

Introduce GaugeGraphView, allow colouring via styles

There's some fractional improvements in reduced array allocation etc,
but mostly this change is just to remove the duplication of the
graph-generating code that was in TrafficListFragment & GaugeViewHolder.
  • Loading branch information...
rtyley committed Mar 6, 2012
1 parent 02e6586 commit c83ca5ca0559dbbd77d8971cd47b3779cae5df69
@@ -82,12 +82,12 @@
</LinearLayout>
</LinearLayout>
- <LinearLayout
- android:id="@+id/ll_bars"
+ <com.github.mobile.gauges.ui.GaugeGraphView
+ android:id="@+id/gauge_graph"
+ style="@style/GaugeGraphDark"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="25"
- android:minHeight="20dp" >
- </LinearLayout>
+ android:minHeight="20dp" />
</LinearLayout>
@@ -23,10 +23,10 @@
android:paddingRight="10dp"
android:paddingTop="10dp" >
- <LinearLayout
- android:id="@+id/ll_bars"
+ <com.github.mobile.gauges.ui.GaugeGraphView
+ android:id="@+id/gauge_graph"
+ style="@style/GaugeGraphLight"
android:layout_width="fill_parent"
- android:layout_height="120dp" >
- </LinearLayout>
+ android:layout_height="120dp" />
</LinearLayout>
View
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright 2012 GitHub Inc.
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<resources>
+ <declare-styleable name="GaugeGraphView">
+ <attr name="viewsWeekdayColor" format="color" />
+ <attr name="peopleWeekdayColor" format="color" />
+ <attr name="viewsWeekendColor" format="color" />
+ <attr name="peopleWeekendColor" format="color" />
+ </declare-styleable>
+</resources>
@@ -26,17 +26,9 @@
<color name="pager_background">#F4F4F4</color>
<color name="pager_background_alternate">#E7E7E7</color>
<color name="text_link">#20A465</color>
- <color name="graph_views_weekday">#53685E</color>
- <color name="graph_people_weekday">#6E9180</color>
- <color name="graph_views_weekend">#3F544C</color>
- <color name="graph_people_weekend">#5B796B</color>
<color name="table_text">#484848</color>
<color name="table_text_light">#A6A6A6</color>
<color name="table_text_header">#636363</color>
- <color name="traffic_views_weekday">#BADDCC</color>
- <color name="traffic_people_weekday">#97CCB1</color>
- <color name="traffic_views_weekend">#D1E6DC</color>
- <color name="traffic_people_weekend">#BBDDCC</color>
<color name="gauge_background_start">#373737</color>
<color name="gauge_background_end">#272727</color>
<color name="header_background_start">#ECECEC</color>
View
@@ -59,4 +59,17 @@
<item name="android:includeFontPadding">false</item>
</style>
+ <style name="GaugeGraphDark">
+ <item name="viewsWeekdayColor">#53685E</item>
+ <item name="peopleWeekdayColor">#6E9180</item>
+ <item name="viewsWeekendColor">#3F544C</item>
+ <item name="peopleWeekendColor">#5B796B</item>
+ </style>
+
+ <style name="GaugeGraphLight">
+ <item name="viewsWeekdayColor">#BADDCC</item>
+ <item name="peopleWeekdayColor">#97CCB1</item>
+ <item name="viewsWeekendColor">#D1E6DC</item>
+ <item name="peopleWeekendColor">#BBDDCC</item>
+ </style>
</resources>
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2012 GitHub Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.github.mobile.gauges.ui;
+
+import static com.github.mobile.gauges.R.styleable.GaugeGraphView_peopleWeekdayColor;
+import static com.github.mobile.gauges.R.styleable.GaugeGraphView_peopleWeekendColor;
+import static com.github.mobile.gauges.R.styleable.GaugeGraphView_viewsWeekdayColor;
+import static com.github.mobile.gauges.R.styleable.GaugeGraphView_viewsWeekendColor;
+import static java.util.Calendar.DAY_OF_WEEK;
+import static java.util.Calendar.DAY_OF_YEAR;
+import static java.util.Calendar.SATURDAY;
+import static java.util.Calendar.SUNDAY;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.util.AttributeSet;
+import android.widget.LinearLayout;
+
+import com.github.mobile.gauges.R;
+import com.github.mobile.gauges.core.DatedViewSummary;
+
+import java.util.GregorianCalendar;
+import java.util.List;
+
+/**
+ * A styleable graph that shows the recent traffic for a gauge.
+ */
+public class GaugeGraphView extends LinearLayout {
+
+ private static final long[] NO_TRAFFIC = new long[] { 0, 0 };
+
+ private final int[] weekdayColors, weekendColors;
+
+ private long[][] data;
+
+ private int[][] colors;
+
+ public GaugeGraphView(Context ctx, AttributeSet attrs) {
+ super(ctx, attrs);
+ TypedArray array = ctx.obtainStyledAttributes(attrs, R.styleable.GaugeGraphView);
+
+ weekdayColors = new int[] { array.getColor(GaugeGraphView_viewsWeekdayColor, 0),
+ array.getColor(GaugeGraphView_peopleWeekdayColor, 0) };
+ weekendColors = new int[] { array.getColor(GaugeGraphView_viewsWeekendColor, 0),
+ array.getColor(GaugeGraphView_peopleWeekendColor, 0) };
+
+ array.recycle();
+ }
+
+ /**
+ * This should be set before the graph is updated with traffic data, and will not take
+ * effect until {@link #updateGraphWith(List<DatedViewSummary>)} is called.
+ *
+ * @param numDays the number of days to display in the graph, 1 bar per day
+ */
+ public void setNumDays(int numDays) {
+ data = new long[numDays][];
+ colors = new int[numDays][];
+ }
+
+ /**
+ * Updates the graph to display the supplied data, which will be padded or truncated
+ * to match the number of days specifed with {@link #setNumDays(int)}.
+ *
+ * @param trafficData a list of traffic data by day in reverse-chronological order
+ */
+ public void updateGraphWith(List<DatedViewSummary> trafficData) {
+ setBackgroundDrawable(createBarGraphDrawableFor(trafficData));
+ }
+
+ private BarGraphDrawable createBarGraphDrawableFor(List<DatedViewSummary> daySummaries) {
+ GregorianCalendar calendar = new GregorianCalendar();
+ int daySummaryIndex = 0;
+ for (int barIndex = data.length - 1; barIndex >= 0; --barIndex) {
+ if (daySummaryIndex < daySummaries.size()) {
+ DatedViewSummary day = daySummaries.get(daySummaryIndex);
+ calendar.setTime(day.getDate()); // take date from day summary returned by API
+ data[barIndex] = new long[] { day.getViews(), day.getPeople() };
+ } else {
+ calendar.add(DAY_OF_YEAR, -1); // this bar is for the day before that of the prior iteration
+ data[barIndex] = NO_TRAFFIC; // the API returned no traffic data for this day
+ }
+
+ int dayOfWeek = calendar.get(DAY_OF_WEEK);
+ colors[barIndex] = (dayOfWeek == SATURDAY || dayOfWeek == SUNDAY) ? weekendColors : weekdayColors;
+ ++daySummaryIndex;
+ }
+ return new BarGraphDrawable(data, colors);
+ }
+}
@@ -20,6 +20,8 @@
import static com.github.mobile.gauges.IntentConstants.GAUGES;
import static com.github.mobile.gauges.IntentConstants.VIEW_AIR_TRAFFIC;
import static com.github.mobile.gauges.IntentConstants.VIEW_GAUGE;
+import static com.madgag.android.listviews.ReflectiveHolderFactory.reflectiveFactoryFor;
+import static com.madgag.android.listviews.ViewInflator.viewInflatorFor;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.content.Loader;
@@ -33,9 +35,7 @@
import com.github.mobile.gauges.R.layout;
import com.github.mobile.gauges.core.Gauge;
import com.google.inject.Inject;
-import com.madgag.android.listviews.ReflectiveHolderFactory;
import com.madgag.android.listviews.ViewHoldingListAdapter;
-import com.madgag.android.listviews.ViewInflator;
import java.io.Serializable;
import java.util.List;
@@ -82,9 +82,8 @@ public void onListItemClick(ListView list, View view, int position, long id) {
@Override
protected ViewHoldingListAdapter<Gauge> adapterFor(List<Gauge> items) {
- return new ViewHoldingListAdapter<Gauge>(items, ViewInflator.viewInflatorFor(getActivity(),
- layout.gauge_list_item), ReflectiveHolderFactory.reflectiveFactoryFor(GaugeViewHolder.class,
- getActivity().getResources()));
+ return new ViewHoldingListAdapter<Gauge>(items, viewInflatorFor(getActivity(), layout.gauge_list_item),
+ reflectiveFactoryFor(GaugeViewHolder.class));
}
@Override
@@ -16,23 +16,15 @@
package com.github.mobile.gauges.ui;
-import static java.util.Calendar.DAY_OF_WEEK;
-import static java.util.Calendar.DAY_OF_YEAR;
-import static java.util.Calendar.SATURDAY;
-import static java.util.Calendar.SUNDAY;
-import android.content.res.Resources;
import android.view.View;
-import android.widget.LinearLayout;
import android.widget.TextView;
-import com.github.mobile.gauges.R.color;
import com.github.mobile.gauges.R.id;
import com.github.mobile.gauges.core.DatedViewSummary;
import com.github.mobile.gauges.core.Gauge;
import com.madgag.android.listviews.ViewHolder;
import java.text.NumberFormat;
-import java.util.GregorianCalendar;
/**
* View holder for a {@link Gauge}
@@ -47,33 +39,19 @@
private final TextView peopleText;
- private final LinearLayout barGraph;
-
- private final int[] weekendColors;
-
- private final int[] weekdayColors;
-
- private final long[][] data;
-
- private final int[][] colors;
+ private final GaugeGraphView barGraph;
/**
* Create view holder
*
* @param view
- * @param resources
*/
- public GaugeViewHolder(final View view, final Resources resources) {
+ public GaugeViewHolder(final View view) {
nameText = (TextView) view.findViewById(id.tv_gauge_name);
viewsText = (TextView) view.findViewById(id.tv_gauge_views);
peopleText = (TextView) view.findViewById(id.tv_gauge_people);
- barGraph = (LinearLayout) view.findViewById(id.ll_bars);
- data = new long[7][];
- colors = new int[7][];
- weekdayColors = new int[] { resources.getColor(color.graph_views_weekday),
- resources.getColor(color.graph_people_weekday) };
- weekendColors = new int[] { resources.getColor(color.graph_views_weekend),
- resources.getColor(color.graph_people_weekend) };
+ barGraph = (GaugeGraphView) view.findViewById(id.gauge_graph);
+ barGraph.setNumDays(7);
}
public void updateViewFor(final Gauge gauge) {
@@ -88,31 +66,7 @@ public void updateViewFor(final Gauge gauge) {
viewsText.setText(NUMBER_FORMAT.format(viewsToday));
peopleText.setText(NUMBER_FORMAT.format(peopleToday));
- int index = data.length - 1;
- GregorianCalendar calendar = new GregorianCalendar();
- for (DatedViewSummary day : gauge.getRecentDays()) {
- data[index] = new long[] { day.getViews(), day.getPeople() };
- calendar.setTime(day.getDate());
- int dayOfWeek = calendar.get(DAY_OF_WEEK);
- if (dayOfWeek == SATURDAY || dayOfWeek == SUNDAY)
- colors[index] = weekendColors;
- else
- colors[index] = weekdayColors;
- index--;
- if (index < 0)
- break;
- }
- // Fill in any days left if recent days reported less than 7
- while (index >= 0) {
- data[index] = new long[] { 0, 0 };
- calendar.add(DAY_OF_YEAR, -1);
- int dayOfWeek = calendar.get(DAY_OF_WEEK);
- if (dayOfWeek == SATURDAY || dayOfWeek == SUNDAY)
- colors[index] = weekendColors;
- else
- colors[index] = weekdayColors;
- index--;
- }
- barGraph.setBackgroundDrawable(new BarGraphDrawable(data, colors));
+ barGraph.updateGraphWith(gauge.getRecentDays());
}
+
}
Oops, something went wrong.

0 comments on commit c83ca5c

Please sign in to comment.