Merge "Improve X axis labels in battery chart (1)"
This commit is contained in:
committed by
Android (Google) Code Review
commit
ebb5a056d2
@@ -279,15 +279,17 @@ public class BatteryChartPreferenceControllerV2 extends AbstractPreferenceContro
|
|||||||
batteryLevelData.getDailyBatteryLevels().getLevels(),
|
batteryLevelData.getDailyBatteryLevels().getLevels(),
|
||||||
generateTimestampDayOfWeekTexts(
|
generateTimestampDayOfWeekTexts(
|
||||||
mContext, batteryLevelData.getDailyBatteryLevels().getTimestamps()),
|
mContext, batteryLevelData.getDailyBatteryLevels().getTimestamps()),
|
||||||
mDailyChartIndex);
|
mDailyChartIndex,
|
||||||
|
BatteryChartViewModel.AxisLabelPosition.CENTER_OF_TRAPEZOIDS);
|
||||||
mHourlyViewModels = new ArrayList<>();
|
mHourlyViewModels = new ArrayList<>();
|
||||||
for (BatteryLevelData.PeriodBatteryLevelData perDayData :
|
for (BatteryLevelData.PeriodBatteryLevelData hourlyBatteryLevelsPerDay :
|
||||||
batteryLevelData.getHourlyBatteryLevelsPerDay()) {
|
batteryLevelData.getHourlyBatteryLevelsPerDay()) {
|
||||||
mHourlyViewModels.add(new BatteryChartViewModel(
|
mHourlyViewModels.add(new BatteryChartViewModel(
|
||||||
perDayData.getLevels(),
|
hourlyBatteryLevelsPerDay.getLevels(),
|
||||||
generateTimestampHourTexts(
|
generateTimestampHourTexts(
|
||||||
mContext, perDayData.getTimestamps()),
|
mContext, hourlyBatteryLevelsPerDay.getTimestamps()),
|
||||||
mHourlyChartIndex));
|
mHourlyChartIndex,
|
||||||
|
BatteryChartViewModel.AxisLabelPosition.BETWEEN_TRAPEZOIDS));
|
||||||
}
|
}
|
||||||
refreshUi();
|
refreshUi();
|
||||||
// TODO: Loads item icon and label and build mBatteryIndexedMap.
|
// TODO: Loads item icon and label and build mBatteryIndexedMap.
|
||||||
|
@@ -33,23 +33,31 @@ class BatteryChartViewModel {
|
|||||||
// We need at least 2 levels to draw a trapezoid.
|
// We need at least 2 levels to draw a trapezoid.
|
||||||
private static final int MIN_LEVELS_DATA_SIZE = 2;
|
private static final int MIN_LEVELS_DATA_SIZE = 2;
|
||||||
|
|
||||||
|
enum AxisLabelPosition {
|
||||||
|
BETWEEN_TRAPEZOIDS,
|
||||||
|
CENTER_OF_TRAPEZOIDS,
|
||||||
|
}
|
||||||
|
|
||||||
private final List<Integer> mLevels;
|
private final List<Integer> mLevels;
|
||||||
private final List<String> mTexts;
|
private final List<String> mTexts;
|
||||||
|
private final AxisLabelPosition mAxisLabelPosition;
|
||||||
private int mSelectedIndex;
|
private int mSelectedIndex;
|
||||||
|
|
||||||
BatteryChartViewModel(
|
BatteryChartViewModel(
|
||||||
@NonNull List<Integer> levels, @NonNull List<String> texts, int selectedIndex) {
|
@NonNull List<Integer> levels, @NonNull List<String> texts, int selectedIndex,
|
||||||
|
@NonNull AxisLabelPosition axisLabelPosition) {
|
||||||
Preconditions.checkArgument(
|
Preconditions.checkArgument(
|
||||||
levels.size() == texts.size()
|
levels.size() == texts.size()
|
||||||
&& levels.size() >= MIN_LEVELS_DATA_SIZE
|
&& levels.size() >= MIN_LEVELS_DATA_SIZE
|
||||||
&& selectedIndex >= SELECTED_INDEX_ALL
|
&& selectedIndex >= SELECTED_INDEX_ALL
|
||||||
&& selectedIndex < levels.size(),
|
&& selectedIndex < levels.size(),
|
||||||
String.format(Locale.getDefault(), "Invalid BatteryChartViewModel"
|
String.format(Locale.ENGLISH, "Invalid BatteryChartViewModel"
|
||||||
+ " levels.size: %d\ntexts.size: %d\nselectedIndex: %d.",
|
+ " levels.size: %d\ntexts.size: %d\nselectedIndex: %d.",
|
||||||
levels.size(), texts.size(), selectedIndex));
|
levels.size(), texts.size(), selectedIndex));
|
||||||
mLevels = levels;
|
mLevels = levels;
|
||||||
mTexts = texts;
|
mTexts = texts;
|
||||||
mSelectedIndex = selectedIndex;
|
mSelectedIndex = selectedIndex;
|
||||||
|
mAxisLabelPosition = axisLabelPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int size() {
|
public int size() {
|
||||||
@@ -72,9 +80,13 @@ class BatteryChartViewModel {
|
|||||||
mSelectedIndex = index;
|
mSelectedIndex = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AxisLabelPosition axisLabelPosition() {
|
||||||
|
return mAxisLabelPosition;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(mLevels, mTexts, mSelectedIndex);
|
return Objects.hash(mLevels, mTexts, mSelectedIndex, mAxisLabelPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -87,12 +99,15 @@ class BatteryChartViewModel {
|
|||||||
final BatteryChartViewModel batteryChartViewModel = (BatteryChartViewModel) other;
|
final BatteryChartViewModel batteryChartViewModel = (BatteryChartViewModel) other;
|
||||||
return Objects.equals(mLevels, batteryChartViewModel.mLevels)
|
return Objects.equals(mLevels, batteryChartViewModel.mLevels)
|
||||||
&& Objects.equals(mTexts, batteryChartViewModel.mTexts)
|
&& Objects.equals(mTexts, batteryChartViewModel.mTexts)
|
||||||
&& mSelectedIndex == batteryChartViewModel.mSelectedIndex;
|
&& mSelectedIndex == batteryChartViewModel.mSelectedIndex
|
||||||
|
&& mAxisLabelPosition == batteryChartViewModel.mAxisLabelPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return String.format(Locale.getDefault(), "levels: %s\ntexts: %s\nselectedIndex: %d",
|
return String.format(Locale.ENGLISH,
|
||||||
Objects.toString(mLevels), Objects.toString(mTexts), mSelectedIndex);
|
"levels: %s\ntexts: %s\nselectedIndex: %d, axisLabelPosition: %s",
|
||||||
|
Objects.toString(mLevels), Objects.toString(mTexts), mSelectedIndex,
|
||||||
|
mAxisLabelPosition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -441,11 +441,19 @@ public class BatteryChartViewV2 extends AppCompatImageView implements View.OnCli
|
|||||||
for (int index = 0; index < DEFAULT_AXIS_LABEL_COUNT; index++) {
|
for (int index = 0; index < DEFAULT_AXIS_LABEL_COUNT; index++) {
|
||||||
xOffsets[index] = baselineX + index * offsetX * slotBarOffset;
|
xOffsets[index] = baselineX + index * offsetX * slotBarOffset;
|
||||||
}
|
}
|
||||||
drawAxisLabel(canvas, xOffsets);
|
switch (mViewModel.axisLabelPosition()) {
|
||||||
|
case CENTER_OF_TRAPEZOIDS:
|
||||||
|
drawAxisLabelsCenterOfTrapezoids(canvas, xOffsets, unitWidth);
|
||||||
|
break;
|
||||||
|
case BETWEEN_TRAPEZOIDS:
|
||||||
|
default:
|
||||||
|
drawAxisLabelsBetweenTrapezoids(canvas, xOffsets);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void drawAxisLabel(Canvas canvas, float[] xOffsets) {
|
private void drawAxisLabelsBetweenTrapezoids(Canvas canvas, float[] xOffsets) {
|
||||||
// Draws the 1st axis label info.
|
// Draws the 1st axis label info.
|
||||||
canvas.drawText(
|
canvas.drawText(
|
||||||
mAxisLabels[0], xOffsets[0] - mAxisLabelsBounds[0].left, getAxisLabelY(0),
|
mAxisLabels[0], xOffsets[0] - mAxisLabelsBounds[0].left, getAxisLabelY(0),
|
||||||
@@ -471,6 +479,18 @@ public class BatteryChartViewV2 extends AppCompatImageView implements View.OnCli
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void drawAxisLabelsCenterOfTrapezoids(
|
||||||
|
Canvas canvas, float[] xOffsets, float unitWidth) {
|
||||||
|
for (int index = 0; index < DEFAULT_AXIS_LABEL_COUNT - 1; index++) {
|
||||||
|
canvas.drawText(
|
||||||
|
mAxisLabels[index],
|
||||||
|
xOffsets[index] + (unitWidth - (mAxisLabelsBounds[index].width()
|
||||||
|
- mAxisLabelsBounds[index].left)) * .5f,
|
||||||
|
getAxisLabelY(index),
|
||||||
|
mTextPaint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private int getAxisLabelY(int index) {
|
private int getAxisLabelY(int index) {
|
||||||
return getHeight()
|
return getHeight()
|
||||||
- mAxisLabelsBounds[index].height()
|
- mAxisLabelsBounds[index].height()
|
||||||
|
@@ -178,7 +178,8 @@ public final class BatteryChartPreferenceControllerV2Test {
|
|||||||
verify(mHourlyChartView).setViewModel(new BatteryChartViewModel(
|
verify(mHourlyChartView).setViewModel(new BatteryChartViewModel(
|
||||||
List.of(100, 97, 95),
|
List.of(100, 97, 95),
|
||||||
List.of("8 am", "10 am", "12 pm"),
|
List.of("8 am", "10 am", "12 pm"),
|
||||||
BatteryChartViewModel.SELECTED_INDEX_ALL));
|
BatteryChartViewModel.SELECTED_INDEX_ALL,
|
||||||
|
BatteryChartViewModel.AxisLabelPosition.BETWEEN_TRAPEZOIDS));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -193,7 +194,8 @@ public final class BatteryChartPreferenceControllerV2Test {
|
|||||||
verify(mDailyChartView).setViewModel(new BatteryChartViewModel(
|
verify(mDailyChartView).setViewModel(new BatteryChartViewModel(
|
||||||
List.of(100, 83, 59, 41),
|
List.of(100, 83, 59, 41),
|
||||||
List.of("SAT", "SUN", "MON", "MON"),
|
List.of("SAT", "SUN", "MON", "MON"),
|
||||||
BatteryChartViewModel.SELECTED_INDEX_ALL));
|
BatteryChartViewModel.SELECTED_INDEX_ALL,
|
||||||
|
BatteryChartViewModel.AxisLabelPosition.CENTER_OF_TRAPEZOIDS));
|
||||||
|
|
||||||
reset(mDailyChartView);
|
reset(mDailyChartView);
|
||||||
reset(mHourlyChartView);
|
reset(mHourlyChartView);
|
||||||
@@ -204,12 +206,14 @@ public final class BatteryChartPreferenceControllerV2Test {
|
|||||||
verify(mDailyChartView).setViewModel(new BatteryChartViewModel(
|
verify(mDailyChartView).setViewModel(new BatteryChartViewModel(
|
||||||
List.of(100, 83, 59, 41),
|
List.of(100, 83, 59, 41),
|
||||||
List.of("SAT", "SUN", "MON", "MON"),
|
List.of("SAT", "SUN", "MON", "MON"),
|
||||||
0));
|
0,
|
||||||
|
BatteryChartViewModel.AxisLabelPosition.CENTER_OF_TRAPEZOIDS));
|
||||||
verify(mHourlyChartView).setViewModel(new BatteryChartViewModel(
|
verify(mHourlyChartView).setViewModel(new BatteryChartViewModel(
|
||||||
List.of(100, 97, 95, 93, 91, 89, 87, 85, 83),
|
List.of(100, 97, 95, 93, 91, 89, 87, 85, 83),
|
||||||
List.of("8 am", "10 am", "12 pm", "2 pm", "4 pm", "6 pm", "8 pm", "10 pm",
|
List.of("8 am", "10 am", "12 pm", "2 pm", "4 pm", "6 pm", "8 pm", "10 pm",
|
||||||
"12 am"),
|
"12 am"),
|
||||||
BatteryChartViewModel.SELECTED_INDEX_ALL));
|
BatteryChartViewModel.SELECTED_INDEX_ALL,
|
||||||
|
BatteryChartViewModel.AxisLabelPosition.BETWEEN_TRAPEZOIDS));
|
||||||
|
|
||||||
reset(mDailyChartView);
|
reset(mDailyChartView);
|
||||||
reset(mHourlyChartView);
|
reset(mHourlyChartView);
|
||||||
@@ -221,12 +225,14 @@ public final class BatteryChartPreferenceControllerV2Test {
|
|||||||
verify(mDailyChartView).setViewModel(new BatteryChartViewModel(
|
verify(mDailyChartView).setViewModel(new BatteryChartViewModel(
|
||||||
List.of(100, 83, 59, 41),
|
List.of(100, 83, 59, 41),
|
||||||
List.of("SAT", "SUN", "MON", "MON"),
|
List.of("SAT", "SUN", "MON", "MON"),
|
||||||
1));
|
1,
|
||||||
|
BatteryChartViewModel.AxisLabelPosition.CENTER_OF_TRAPEZOIDS));
|
||||||
verify(mHourlyChartView).setViewModel(new BatteryChartViewModel(
|
verify(mHourlyChartView).setViewModel(new BatteryChartViewModel(
|
||||||
List.of(83, 81, 79, 77, 75, 73, 71, 69, 67, 65, 63, 61, 59),
|
List.of(83, 81, 79, 77, 75, 73, 71, 69, 67, 65, 63, 61, 59),
|
||||||
List.of("12 am", "2 am", "4 am", "6 am", "8 am", "10 am", "12 pm", "2 pm",
|
List.of("12 am", "2 am", "4 am", "6 am", "8 am", "10 am", "12 pm", "2 pm",
|
||||||
"4 pm", "6 pm", "8 pm", "10 pm", "12 am"),
|
"4 pm", "6 pm", "8 pm", "10 pm", "12 am"),
|
||||||
6));
|
6,
|
||||||
|
BatteryChartViewModel.AxisLabelPosition.BETWEEN_TRAPEZOIDS));
|
||||||
|
|
||||||
reset(mDailyChartView);
|
reset(mDailyChartView);
|
||||||
reset(mHourlyChartView);
|
reset(mHourlyChartView);
|
||||||
@@ -239,12 +245,14 @@ public final class BatteryChartPreferenceControllerV2Test {
|
|||||||
verify(mDailyChartView).setViewModel(new BatteryChartViewModel(
|
verify(mDailyChartView).setViewModel(new BatteryChartViewModel(
|
||||||
List.of(100, 83, 59, 41),
|
List.of(100, 83, 59, 41),
|
||||||
List.of("SAT", "SUN", "MON", "MON"),
|
List.of("SAT", "SUN", "MON", "MON"),
|
||||||
2));
|
2,
|
||||||
|
BatteryChartViewModel.AxisLabelPosition.CENTER_OF_TRAPEZOIDS));
|
||||||
verify(mHourlyChartView).setViewModel(new BatteryChartViewModel(
|
verify(mHourlyChartView).setViewModel(new BatteryChartViewModel(
|
||||||
List.of(59, 57, 55, 53, 51, 49, 47, 45, 43, 41),
|
List.of(59, 57, 55, 53, 51, 49, 47, 45, 43, 41),
|
||||||
List.of("12 am", "2 am", "4 am", "6 am", "8 am", "10 am", "12 pm", "2 pm",
|
List.of("12 am", "2 am", "4 am", "6 am", "8 am", "10 am", "12 pm", "2 pm",
|
||||||
"4 pm", "6 pm"),
|
"4 pm", "6 pm"),
|
||||||
BatteryChartViewModel.SELECTED_INDEX_ALL));
|
BatteryChartViewModel.SELECTED_INDEX_ALL,
|
||||||
|
BatteryChartViewModel.AxisLabelPosition.BETWEEN_TRAPEZOIDS));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@@ -104,7 +104,8 @@ public final class BatteryChartViewV2Test {
|
|||||||
final int originalSelectedIndex = 2;
|
final int originalSelectedIndex = 2;
|
||||||
mBatteryChartView.setViewModel(
|
mBatteryChartView.setViewModel(
|
||||||
new BatteryChartViewModel(List.of(90, 80, 70, 60), List.of("", "", "", ""),
|
new BatteryChartViewModel(List.of(90, 80, 70, 60), List.of("", "", "", ""),
|
||||||
originalSelectedIndex));
|
originalSelectedIndex,
|
||||||
|
BatteryChartViewModel.AxisLabelPosition.BETWEEN_TRAPEZOIDS));
|
||||||
for (int i = 0; i < mBatteryChartView.mTrapezoidSlots.length; i++) {
|
for (int i = 0; i < mBatteryChartView.mTrapezoidSlots.length; i++) {
|
||||||
mBatteryChartView.mTrapezoidSlots[i] = new BatteryChartViewV2.TrapezoidSlot();
|
mBatteryChartView.mTrapezoidSlots[i] = new BatteryChartViewV2.TrapezoidSlot();
|
||||||
mBatteryChartView.mTrapezoidSlots[i].mLeft = i;
|
mBatteryChartView.mTrapezoidSlots[i].mLeft = i;
|
||||||
@@ -136,6 +137,7 @@ public final class BatteryChartViewV2Test {
|
|||||||
.thenReturn(false);
|
.thenReturn(false);
|
||||||
|
|
||||||
mBatteryChartView.onAttachedToWindow();
|
mBatteryChartView.onAttachedToWindow();
|
||||||
|
|
||||||
assertThat(mBatteryChartView.isClickable()).isFalse();
|
assertThat(mBatteryChartView.isClickable()).isFalse();
|
||||||
assertThat(mBatteryChartView.mTrapezoidCurvePaint).isNotNull();
|
assertThat(mBatteryChartView.mTrapezoidCurvePaint).isNotNull();
|
||||||
}
|
}
|
||||||
@@ -148,6 +150,7 @@ public final class BatteryChartViewV2Test {
|
|||||||
doReturn(false).when(mMockAccessibilityManager).isEnabled();
|
doReturn(false).when(mMockAccessibilityManager).isEnabled();
|
||||||
|
|
||||||
mBatteryChartView.onAttachedToWindow();
|
mBatteryChartView.onAttachedToWindow();
|
||||||
|
|
||||||
assertThat(mBatteryChartView.isClickable()).isTrue();
|
assertThat(mBatteryChartView.isClickable()).isTrue();
|
||||||
assertThat(mBatteryChartView.mTrapezoidCurvePaint).isNull();
|
assertThat(mBatteryChartView.mTrapezoidCurvePaint).isNull();
|
||||||
}
|
}
|
||||||
@@ -163,6 +166,7 @@ public final class BatteryChartViewV2Test {
|
|||||||
.getEnabledAccessibilityServiceList(anyInt());
|
.getEnabledAccessibilityServiceList(anyInt());
|
||||||
|
|
||||||
mBatteryChartView.onAttachedToWindow();
|
mBatteryChartView.onAttachedToWindow();
|
||||||
|
|
||||||
assertThat(mBatteryChartView.isClickable()).isTrue();
|
assertThat(mBatteryChartView.isClickable()).isTrue();
|
||||||
assertThat(mBatteryChartView.mTrapezoidCurvePaint).isNull();
|
assertThat(mBatteryChartView.mTrapezoidCurvePaint).isNull();
|
||||||
}
|
}
|
||||||
@@ -175,6 +179,7 @@ public final class BatteryChartViewV2Test {
|
|||||||
doReturn(true).when(mMockAccessibilityManager).isEnabled();
|
doReturn(true).when(mMockAccessibilityManager).isEnabled();
|
||||||
|
|
||||||
mBatteryChartView.onAttachedToWindow();
|
mBatteryChartView.onAttachedToWindow();
|
||||||
|
|
||||||
assertThat(mBatteryChartView.isClickable()).isFalse();
|
assertThat(mBatteryChartView.isClickable()).isFalse();
|
||||||
assertThat(mBatteryChartView.mTrapezoidCurvePaint).isNotNull();
|
assertThat(mBatteryChartView.mTrapezoidCurvePaint).isNotNull();
|
||||||
}
|
}
|
||||||
@@ -188,7 +193,8 @@ public final class BatteryChartViewV2Test {
|
|||||||
texts.add("");
|
texts.add("");
|
||||||
}
|
}
|
||||||
mBatteryChartView.setViewModel(new BatteryChartViewModel(
|
mBatteryChartView.setViewModel(new BatteryChartViewModel(
|
||||||
levels, texts, BatteryChartViewModel.SELECTED_INDEX_ALL));
|
levels, texts, BatteryChartViewModel.SELECTED_INDEX_ALL,
|
||||||
|
BatteryChartViewModel.AxisLabelPosition.BETWEEN_TRAPEZOIDS));
|
||||||
mBatteryChartView.setClickableForce(true);
|
mBatteryChartView.setClickableForce(true);
|
||||||
when(mPowerUsageFeatureProvider.isChartGraphSlotsEnabled(mContext))
|
when(mPowerUsageFeatureProvider.isChartGraphSlotsEnabled(mContext))
|
||||||
.thenReturn(true);
|
.thenReturn(true);
|
||||||
|
Reference in New Issue
Block a user