/* * 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; /** * Create graph view from context and attributes * * @param context * @param attrs */ public GaugeGraphView(Context context, AttributeSet attrs) { super(context, attrs); TypedArray array = context.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)} 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 */ @SuppressWarnings("deprecation") 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); } }