的
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 AndroidPlot.com
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.androidplot.demos">
|
||||
|
||||
<!-- Used by Crittercism to report crashes -->
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
|
||||
<application android:name=".DemoApplication"
|
||||
android:label="Androidplot API DemoApp"
|
||||
android:theme="@android:style/Theme.Holo.NoActionBar.Fullscreen"
|
||||
android:icon="@drawable/ic_launcher">
|
||||
|
||||
<activity android:name=".MainActivity"
|
||||
android:label="@string/app_name"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".SimplePieChartActivity"
|
||||
android:label="@string/app_name"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".AnimatedXYPlotActivity"
|
||||
android:label="@string/app_name"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".SimpleXYPlotActivity"
|
||||
android:label="@string/app_name"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".ScatterPlotActivity"
|
||||
android:label="@string/app_name"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".BarPlotExampleActivity"
|
||||
android:label="@string/app_name"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".DynamicXYPlotActivity"
|
||||
android:label="@string/app_name"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".CandlestickChartActivity"
|
||||
android:label="@string/app_name"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".OrientationSensorExampleActivity"
|
||||
android:label="@string/app_name"
|
||||
android:screenOrientation="landscape"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".StepChartExampleActivity"
|
||||
android:label="@string/app_name"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".TouchZoomExampleActivity"
|
||||
android:label="@string/app_name"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".ListViewActivity" android:label="ListView Example"/>
|
||||
<activity android:name=".RecyclerViewActivity" android:label="RecyclerView Example"/>
|
||||
<activity android:name=".XYRegionExampleActivity" android:label="XYRegion Example"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".TimeSeriesActivity"/>
|
||||
<activity android:name=".XYPlotWithBgImgActivity"/>
|
||||
<activity android:name=".ECGExample"/>
|
||||
<activity android:name=".FXPlotExampleActivity"/>
|
||||
<activity android:name=".BubbleChartActivity"/>
|
||||
<activity android:name=".DualScaleActivity"/>
|
||||
|
||||
<!-- receiver for demo app widget -->
|
||||
<receiver
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="Example Widget"
|
||||
android:name="com.androidplot.demos.widget.DemoAppWidgetProvider"
|
||||
android:exported="false">
|
||||
<intent-filter >
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.appwidget.provider"
|
||||
android:resource="@xml/demo_app_widget_provider_info" />
|
||||
</receiver>
|
||||
</application>
|
||||
</manifest>
|
||||
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright 2015 AndroidPlot.com
|
||||
*
|
||||
* 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.androidplot.demos;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.app.Activity;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
import android.view.animation.AccelerateDecelerateInterpolator;
|
||||
|
||||
import com.androidplot.xy.BoundaryMode;
|
||||
import com.androidplot.xy.CatmullRomInterpolator;
|
||||
import com.androidplot.xy.LineAndPointFormatter;
|
||||
import com.androidplot.xy.ScalingXYSeries;
|
||||
import com.androidplot.xy.SimpleXYSeries;
|
||||
import com.androidplot.xy.XYGraphWidget;
|
||||
import com.androidplot.xy.XYPlot;
|
||||
import com.androidplot.xy.XYSeries;
|
||||
|
||||
import java.text.FieldPosition;
|
||||
import java.text.Format;
|
||||
import java.text.ParsePosition;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Demonstrates animating XYSeries data from a zero value up/down to the actual values set. Once
|
||||
* the animation completes, labels for each point are made visible.
|
||||
*
|
||||
* IMPORTANT: This example makes use of {@link ValueAnimator} which is only available in
|
||||
* SDK level 11 and later..
|
||||
*/
|
||||
public class AnimatedXYPlotActivity extends Activity {
|
||||
|
||||
private XYPlot plot;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.simple_xy_plot_example);
|
||||
|
||||
// initialize our XYPlot reference:
|
||||
plot = (XYPlot) findViewById(R.id.plot);
|
||||
|
||||
// create a couple arrays of y-values to plot:
|
||||
final Number[] domainLabels = {1, 2, 3, 6, 7, 8, 9, 10, 13, 14};
|
||||
Number[] series1Numbers = {1, 4, 2, 8, 4, 16, 8, 32, 16, 64};
|
||||
Number[] series2Numbers = {5, 2, 10, 5, 20, 10, 40, 20, 80, 40};
|
||||
|
||||
// turn the above arrays into XYSeries':
|
||||
// (Y_VALS_ONLY means use the element index as the x value)
|
||||
XYSeries series1 = new SimpleXYSeries(
|
||||
Arrays.asList(series1Numbers), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Series1");
|
||||
XYSeries series2 = new SimpleXYSeries(
|
||||
Arrays.asList(series2Numbers), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Series2");
|
||||
|
||||
// create formatters to use for drawing a series using LineAndPointRenderer
|
||||
// and configure them from xml:
|
||||
final LineAndPointFormatter series1Format =
|
||||
new LineAndPointFormatter(this, R.xml.line_point_formatter);
|
||||
|
||||
final LineAndPointFormatter series2Format =
|
||||
new LineAndPointFormatter(this, R.xml.line_point_formatter);
|
||||
series2Format.getLinePaint().setColor(Color.RED);
|
||||
|
||||
// just for fun, add some smoothing to the lines:
|
||||
// see: http://androidplot.com/smooth-curves-and-androidplot/
|
||||
series1Format.setInterpolationParams(
|
||||
new CatmullRomInterpolator.Params(10, CatmullRomInterpolator.Type.Centripetal));
|
||||
|
||||
series2Format.setInterpolationParams(
|
||||
new CatmullRomInterpolator.Params(10, CatmullRomInterpolator.Type.Centripetal));
|
||||
|
||||
// wrap each series in instances of ScalingXYSeries before adding to the plot
|
||||
// so that we can animate the series values below:
|
||||
final ScalingXYSeries scalingSeries1 = new ScalingXYSeries(series1, 0, ScalingXYSeries.Mode.Y_ONLY);
|
||||
plot.addSeries(scalingSeries1, series1Format);
|
||||
|
||||
final ScalingXYSeries scalingSeries2 = new ScalingXYSeries(series2, 0, ScalingXYSeries.Mode.Y_ONLY);
|
||||
plot.addSeries(scalingSeries2, series2Format);
|
||||
|
||||
plot.getGraph().getLineLabelStyle(XYGraphWidget.Edge.BOTTOM).setFormat(new Format() {
|
||||
@Override
|
||||
public StringBuffer format(Object obj,
|
||||
@NonNull StringBuffer toAppendTo,
|
||||
@NonNull FieldPosition pos) {
|
||||
int i = Math.round(((Number) obj).floatValue());
|
||||
return toAppendTo.append(domainLabels[i]);
|
||||
}
|
||||
@Override
|
||||
public Object parseObject(String source, @NonNull ParsePosition pos) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
plot.setRangeBoundaries(0, 100, BoundaryMode.FIXED);
|
||||
|
||||
// animate a scale value from a starting val of 0 to a final value of 1:
|
||||
ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
|
||||
|
||||
// use an animation pattern that begins and ends slowly:
|
||||
animator.setInterpolator(new AccelerateDecelerateInterpolator());
|
||||
|
||||
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator valueAnimator) {
|
||||
float scale = valueAnimator.getAnimatedFraction();
|
||||
scalingSeries1.setScale(scale);
|
||||
scalingSeries2.setScale(scale);
|
||||
plot.redraw();
|
||||
}
|
||||
});
|
||||
animator.addListener(new Animator.AnimatorListener() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animator) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animator) {
|
||||
// the animation is over, so show point labels:
|
||||
series1Format.getPointLabelFormatter().getTextPaint().setColor(Color.WHITE);
|
||||
series2Format.getPointLabelFormatter().getTextPaint().setColor(Color.WHITE);
|
||||
plot.redraw();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animator) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationRepeat(Animator animator) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
// the animation will run for 1.5 seconds:
|
||||
animator.setDuration(1500);
|
||||
animator.start();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,467 @@
|
||||
/*
|
||||
* Copyright 2015 AndroidPlot.com
|
||||
*
|
||||
* 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.androidplot.demos;
|
||||
|
||||
import java.text.DateFormatSymbols;
|
||||
import java.text.FieldPosition;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.ParsePosition;
|
||||
import java.util.Arrays;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PointF;
|
||||
import android.os.Bundle;
|
||||
import android.util.Pair;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemSelectedListener;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.Spinner;
|
||||
|
||||
import com.androidplot.Region;
|
||||
import com.androidplot.ui.*;
|
||||
import com.androidplot.ui.widget.TextLabelWidget;
|
||||
import com.androidplot.util.*;
|
||||
import com.androidplot.xy.*;
|
||||
|
||||
/**
|
||||
* An example of a Bar Plot.
|
||||
*/
|
||||
public class BarPlotExampleActivity extends Activity {
|
||||
|
||||
private static final String NO_SELECTION_TXT = "Touch bar to select.";
|
||||
private XYPlot plot;
|
||||
|
||||
private CheckBox series1CheckBox;
|
||||
private CheckBox series2CheckBox;
|
||||
private Spinner spRenderStyle, spWidthStyle, spSeriesSize;
|
||||
private SeekBar sbFixedWidth, sbVariableWidth;
|
||||
|
||||
private XYSeries series1;
|
||||
private XYSeries series2;
|
||||
|
||||
private enum SeriesSize {
|
||||
TEN,
|
||||
TWENTY,
|
||||
SIXTY
|
||||
}
|
||||
|
||||
// Create a couple arrays of y-values to plot:
|
||||
Number[] series1Numbers10 = {2, null, 5, 2, 7, 4, 3, 7, 4, 5};
|
||||
Number[] series2Numbers10 = {4, 6, 3, null, 2, 0, 7, 4, 5, 4};
|
||||
Number[] series1Numbers20 = {2, null, 5, 2, 7, 4, 3, 7, 4, 5, 7, 4, 5, 8, 5, 3, 6, 3, 9, 3};
|
||||
Number[] series2Numbers20 = {4, 6, 3, null, 2, 0, 7, 4, 5, 4, 9, 6, 2, 8, 4, 0, 7, 4, 7, 9};
|
||||
Number[] series1Numbers60 = {2, null, 5, 2, 7, 4, 3, 7, 4, 5, 7, 4, 5, 8, 5, 3, 6, 3, 9, 3, 2, null, 5, 2, 7, 4, 3, 7, 4, 5, 7, 4, 5, 8, 5, 3, 6, 3, 9, 3, 2, null, 5, 2, 7, 4, 3, 7, 4, 5, 7, 4, 5, 8, 5, 3, 6, 3, 9, 3};
|
||||
Number[] series2Numbers60 = {4, 6, 3, null, 2, 0, 7, 4, 5, 4, 9, 6, 2, 8, 4, 0, 7, 4, 7, 9, 4, 6, 3, null, 2, 0, 7, 4, 5, 4, 9, 6, 2, 8, 4, 0, 7, 4, 7, 9, 4, 6, 3, null, 2, 0, 7, 4, 5, 4, 9, 6, 2, 8, 4, 0, 7, 4, 7, 9};
|
||||
Number[] series1Numbers = series1Numbers10;
|
||||
Number[] series2Numbers = series2Numbers10;
|
||||
|
||||
private MyBarFormatter formatter1;
|
||||
|
||||
private MyBarFormatter formatter2;
|
||||
|
||||
private MyBarFormatter selectionFormatter;
|
||||
|
||||
private TextLabelWidget selectionWidget;
|
||||
|
||||
private Pair<Integer, XYSeries> selection;
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.bar_plot_example);
|
||||
|
||||
// initialize our XYPlot reference:
|
||||
plot = (XYPlot) findViewById(R.id.plot);
|
||||
|
||||
formatter1 = new MyBarFormatter(Color.rgb(100, 150, 100), Color.LTGRAY);
|
||||
formatter1.setMarginLeft(PixelUtils.dpToPix(1));
|
||||
formatter1.setMarginRight(PixelUtils.dpToPix(1));
|
||||
formatter2 = new MyBarFormatter(Color.rgb(100, 100, 150), Color.LTGRAY);
|
||||
formatter2.setMarginLeft(PixelUtils.dpToPix(1));
|
||||
formatter2.setMarginRight(PixelUtils.dpToPix(1));
|
||||
selectionFormatter = new MyBarFormatter(Color.YELLOW, Color.WHITE);
|
||||
|
||||
selectionWidget = new TextLabelWidget(plot.getLayoutManager(), NO_SELECTION_TXT,
|
||||
new Size(
|
||||
PixelUtils.dpToPix(100), SizeMode.ABSOLUTE,
|
||||
PixelUtils.dpToPix(100), SizeMode.ABSOLUTE),
|
||||
TextOrientation.HORIZONTAL);
|
||||
|
||||
selectionWidget.getLabelPaint().setTextSize(PixelUtils.dpToPix(16));
|
||||
|
||||
// add a dark, semi-transparent background to the selection label widget:
|
||||
Paint p = new Paint();
|
||||
p.setARGB(100, 0, 0, 0);
|
||||
selectionWidget.setBackgroundPaint(p);
|
||||
|
||||
selectionWidget.position(
|
||||
0, HorizontalPositioning.RELATIVE_TO_CENTER,
|
||||
PixelUtils.dpToPix(45), VerticalPositioning.ABSOLUTE_FROM_TOP,
|
||||
Anchor.TOP_MIDDLE);
|
||||
selectionWidget.pack();
|
||||
|
||||
// reduce the number of range labels
|
||||
plot.setLinesPerRangeLabel(3);
|
||||
plot.setRangeLowerBoundary(0, BoundaryMode.FIXED);
|
||||
|
||||
plot.setLinesPerDomainLabel(2);
|
||||
|
||||
// setup checkbox listers:
|
||||
series1CheckBox = (CheckBox) findViewById(R.id.s1CheckBox);
|
||||
series1CheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
|
||||
onS1CheckBoxClicked(b);
|
||||
}
|
||||
});
|
||||
|
||||
series2CheckBox = (CheckBox) findViewById(R.id.s2CheckBox);
|
||||
series2CheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
|
||||
onS2CheckBoxClicked(b);
|
||||
}
|
||||
});
|
||||
|
||||
plot.setOnTouchListener(new View.OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(View view, MotionEvent motionEvent) {
|
||||
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
onPlotClicked(new PointF(motionEvent.getX(), motionEvent.getY()));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
spRenderStyle = (Spinner) findViewById(R.id.spRenderStyle);
|
||||
ArrayAdapter<BarRenderer.BarOrientation> adapter = new ArrayAdapter<BarRenderer.BarOrientation>(this,
|
||||
android.R.layout.simple_spinner_item, BarRenderer.BarOrientation
|
||||
.values());
|
||||
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
spRenderStyle.setAdapter(adapter);
|
||||
spRenderStyle.setSelection(BarRenderer.BarOrientation.OVERLAID.ordinal());
|
||||
spRenderStyle.setOnItemSelectedListener(new OnItemSelectedListener() {
|
||||
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
|
||||
updatePlot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> arg0) {
|
||||
}
|
||||
});
|
||||
|
||||
spWidthStyle = (Spinner) findViewById(R.id.spWidthStyle);
|
||||
ArrayAdapter<BarRenderer.BarGroupWidthMode> adapter1 = new ArrayAdapter<BarRenderer.BarGroupWidthMode>(
|
||||
this, android.R.layout.simple_spinner_item, BarRenderer.BarGroupWidthMode
|
||||
.values());
|
||||
adapter1.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
spWidthStyle.setAdapter(adapter1);
|
||||
spWidthStyle.setSelection(BarRenderer.BarGroupWidthMode.FIXED_WIDTH.ordinal());
|
||||
spWidthStyle.setOnItemSelectedListener(new OnItemSelectedListener() {
|
||||
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
|
||||
if (BarRenderer.BarGroupWidthMode.FIXED_WIDTH.equals(spWidthStyle.getSelectedItem())) {
|
||||
sbFixedWidth.setVisibility(View.VISIBLE);
|
||||
sbVariableWidth.setVisibility(View.INVISIBLE);
|
||||
} else {
|
||||
sbFixedWidth.setVisibility(View.INVISIBLE);
|
||||
sbVariableWidth.setVisibility(View.VISIBLE);
|
||||
}
|
||||
updatePlot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> arg0) {
|
||||
}
|
||||
});
|
||||
|
||||
spSeriesSize = (Spinner) findViewById(R.id.spSeriesSize);
|
||||
ArrayAdapter<SeriesSize> adapter11 = new ArrayAdapter<SeriesSize>(this,
|
||||
android.R.layout.simple_spinner_item, SeriesSize.values());
|
||||
adapter11.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
spSeriesSize.setAdapter(adapter11);
|
||||
spSeriesSize.setSelection(SeriesSize.TEN.ordinal());
|
||||
spSeriesSize.setOnItemSelectedListener(new OnItemSelectedListener() {
|
||||
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
|
||||
final SeriesSize selectedSize = (SeriesSize) arg0.getSelectedItem();
|
||||
switch (selectedSize) {
|
||||
case TEN:
|
||||
series1Numbers = series1Numbers10;
|
||||
series2Numbers = series2Numbers10;
|
||||
break;
|
||||
case TWENTY:
|
||||
series1Numbers = series1Numbers20;
|
||||
series2Numbers = series2Numbers20;
|
||||
break;
|
||||
case SIXTY:
|
||||
series1Numbers = series1Numbers60;
|
||||
series2Numbers = series2Numbers60;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
updatePlot(selectedSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> arg0) {
|
||||
}
|
||||
});
|
||||
|
||||
sbFixedWidth = (SeekBar) findViewById(R.id.sbFixed);
|
||||
sbFixedWidth.setProgress(50);
|
||||
sbFixedWidth.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
|
||||
updatePlot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
}
|
||||
});
|
||||
|
||||
sbVariableWidth = (SeekBar) findViewById(R.id.sbVariable);
|
||||
sbVariableWidth.setProgress(1);
|
||||
sbVariableWidth.setVisibility(View.INVISIBLE);
|
||||
sbVariableWidth.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
|
||||
updatePlot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
}
|
||||
});
|
||||
|
||||
plot.getGraph().getLineLabelStyle(XYGraphWidget.Edge.BOTTOM).
|
||||
setFormat(new NumberFormat() {
|
||||
@Override
|
||||
public StringBuffer format(double value, StringBuffer buffer,
|
||||
FieldPosition field) {
|
||||
int year = (int) (value + 0.5d) / 12;
|
||||
int month = (int) ((value + 0.5d) % 12);
|
||||
return new StringBuffer(DateFormatSymbols.getInstance()
|
||||
.getShortMonths()[month] + " '0" + year);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringBuffer format(long value, StringBuffer buffer,
|
||||
FieldPosition field) {
|
||||
throw new UnsupportedOperationException("Not yet implemented.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Number parse(String string, ParsePosition position) {
|
||||
throw new UnsupportedOperationException("Not yet implemented.");
|
||||
}
|
||||
});
|
||||
updatePlot();
|
||||
}
|
||||
|
||||
private void updatePlot() {
|
||||
updatePlot(null);
|
||||
}
|
||||
|
||||
private void updatePlot(SeriesSize seriesSize) {
|
||||
|
||||
// Remove all current series from each plot
|
||||
plot.clear();
|
||||
|
||||
// Setup our Series with the selected number of elements
|
||||
series1 = new SimpleXYSeries(Arrays.asList(series1Numbers),
|
||||
SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Us");
|
||||
series2 = new SimpleXYSeries(Arrays.asList(series2Numbers),
|
||||
SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Them");
|
||||
|
||||
plot.setDomainBoundaries(-1, series1.size(), BoundaryMode.FIXED);
|
||||
plot.setRangeUpperBoundary(
|
||||
SeriesUtils.minMax(series1, series2).
|
||||
getMaxY().doubleValue() + 1, BoundaryMode.FIXED);
|
||||
|
||||
if(seriesSize != null) {
|
||||
switch(seriesSize) {
|
||||
case TEN:
|
||||
plot.setDomainStep(StepMode.INCREMENT_BY_VAL, 2);
|
||||
break;
|
||||
case TWENTY:
|
||||
plot.setDomainStep(StepMode.INCREMENT_BY_VAL, 4);
|
||||
break;
|
||||
case SIXTY:
|
||||
plot.setDomainStep(StepMode.INCREMENT_BY_VAL, 6);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// add a new series' to the xyplot:
|
||||
if (series1CheckBox.isChecked()) plot.addSeries(series1, formatter1);
|
||||
if (series2CheckBox.isChecked()) plot.addSeries(series2, formatter2);
|
||||
|
||||
// Setup the BarRenderer with our selected options
|
||||
MyBarRenderer renderer = plot.getRenderer(MyBarRenderer.class);
|
||||
renderer.setBarOrientation((BarRenderer.BarOrientation) spRenderStyle.getSelectedItem());
|
||||
final BarRenderer.BarGroupWidthMode barGroupWidthMode
|
||||
= (BarRenderer.BarGroupWidthMode) spWidthStyle.getSelectedItem();
|
||||
renderer.setBarGroupWidth(barGroupWidthMode,
|
||||
barGroupWidthMode == BarRenderer.BarGroupWidthMode.FIXED_WIDTH
|
||||
? sbFixedWidth.getProgress() : sbVariableWidth.getProgress());
|
||||
|
||||
if (BarRenderer.BarOrientation.STACKED.equals(spRenderStyle.getSelectedItem())) {
|
||||
plot.getInnerLimits().setMaxY(15);
|
||||
} else {
|
||||
plot.getInnerLimits().setMaxY(0);
|
||||
}
|
||||
|
||||
plot.redraw();
|
||||
|
||||
}
|
||||
|
||||
private void onPlotClicked(PointF point) {
|
||||
|
||||
// make sure the point lies within the graph area. we use gridrect
|
||||
// because it accounts for margins and padding as well.
|
||||
if (plot.containsPoint(point.x, point.y)) {
|
||||
Number x = plot.getXVal(point);
|
||||
Number y = plot.getYVal(point);
|
||||
|
||||
selection = null;
|
||||
double xDistance = 0;
|
||||
double yDistance = 0;
|
||||
|
||||
// find the closest value to the selection:
|
||||
for (SeriesBundle<XYSeries, ? extends XYSeriesFormatter> sfPair : plot
|
||||
.getRegistry().getSeriesAndFormatterList()) {
|
||||
XYSeries series = sfPair.getSeries();
|
||||
for (int i = 0; i < series.size(); i++) {
|
||||
Number thisX = series.getX(i);
|
||||
Number thisY = series.getY(i);
|
||||
if (thisX != null && thisY != null) {
|
||||
double thisXDistance =
|
||||
Region.measure(x, thisX).doubleValue();
|
||||
double thisYDistance =
|
||||
Region.measure(y, thisY).doubleValue();
|
||||
if (selection == null) {
|
||||
selection = new Pair<>(i, series);
|
||||
xDistance = thisXDistance;
|
||||
yDistance = thisYDistance;
|
||||
} else if (thisXDistance < xDistance) {
|
||||
selection = new Pair<>(i, series);
|
||||
xDistance = thisXDistance;
|
||||
yDistance = thisYDistance;
|
||||
} else if (thisXDistance == xDistance &&
|
||||
thisYDistance < yDistance &&
|
||||
thisY.doubleValue() >= y.doubleValue()) {
|
||||
selection = new Pair<>(i, series);
|
||||
xDistance = thisXDistance;
|
||||
yDistance = thisYDistance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// if the press was outside the graph area, deselect:
|
||||
selection = null;
|
||||
}
|
||||
|
||||
if (selection == null) {
|
||||
selectionWidget.setText(NO_SELECTION_TXT);
|
||||
} else {
|
||||
selectionWidget.setText("Selected: " + selection.second.getTitle() +
|
||||
" Value: " + selection.second.getY(selection.first));
|
||||
}
|
||||
plot.redraw();
|
||||
}
|
||||
|
||||
private void onS1CheckBoxClicked(boolean checked) {
|
||||
if (checked) {
|
||||
plot.addSeries(series1, formatter1);
|
||||
} else {
|
||||
plot.removeSeries(series1);
|
||||
}
|
||||
plot.redraw();
|
||||
}
|
||||
|
||||
private void onS2CheckBoxClicked(boolean checked) {
|
||||
if (checked) {
|
||||
plot.addSeries(series2, formatter2);
|
||||
} else {
|
||||
plot.removeSeries(series2);
|
||||
}
|
||||
plot.redraw();
|
||||
}
|
||||
|
||||
class MyBarFormatter extends BarFormatter {
|
||||
|
||||
public MyBarFormatter(int fillColor, int borderColor) {
|
||||
super(fillColor, borderColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends SeriesRenderer> getRendererClass() {
|
||||
return MyBarRenderer.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SeriesRenderer doGetRendererInstance(XYPlot plot) {
|
||||
return new MyBarRenderer(plot);
|
||||
}
|
||||
}
|
||||
|
||||
class MyBarRenderer extends BarRenderer<MyBarFormatter> {
|
||||
|
||||
public MyBarRenderer(XYPlot plot) {
|
||||
super(plot);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementing this method to allow us to inject our
|
||||
* special selection getFormatter.
|
||||
* @param index index of the point being rendered.
|
||||
* @param series XYSeries to which the point being rendered belongs.
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public MyBarFormatter getFormatter(int index, XYSeries series) {
|
||||
if (selection != null &&
|
||||
selection.second == series &&
|
||||
selection.first == index) {
|
||||
return selectionFormatter;
|
||||
} else {
|
||||
return getFormatter(series);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2015 AndroidPlot.com
|
||||
*
|
||||
* 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.androidplot.demos;
|
||||
|
||||
import android.app.*;
|
||||
import android.graphics.*;
|
||||
import android.os.*;
|
||||
|
||||
import com.androidplot.xy.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* An example of a bubble chart.
|
||||
*/
|
||||
public class BubbleChartActivity extends Activity {
|
||||
|
||||
private XYPlot plot;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.bubble_chart_example);
|
||||
|
||||
// initialize our XYPlot reference:
|
||||
plot = (XYPlot) findViewById(R.id.plot);
|
||||
|
||||
// turn the above arrays into XYSeries':
|
||||
// (Y_VALS_ONLY means use the element index as the x value)
|
||||
BubbleSeries series1 = new BubbleSeries(
|
||||
Arrays.asList(new Number[]{3, 5, 2, 3, 6}),
|
||||
Arrays.asList(new Number[]{1, 5, 2, 2, 3}), "s1");
|
||||
|
||||
BubbleSeries series2 = new BubbleSeries(
|
||||
Arrays.asList(new Number[]{2, 7, 3, 1, 3}),
|
||||
Arrays.asList(new Number[]{2, 1, 2, 6, 7}), "s2");
|
||||
|
||||
BubbleSeries series3 = new BubbleSeries(
|
||||
Arrays.asList(new Number[]{7, 2, 5, 6, 5}),
|
||||
Arrays.asList(new Number[]{3, 2, 4, 6, 7}), "s3");
|
||||
|
||||
plot.setDomainBoundaries(-1, 5, BoundaryMode.FIXED);
|
||||
plot.setRangeBoundaries(0, 8, BoundaryMode.FIXED);
|
||||
|
||||
BubbleFormatter bf1 = new BubbleFormatter(this, R.xml.bubble_formatter1);
|
||||
bf1.setPointLabelFormatter(new PointLabelFormatter(Color.BLACK));
|
||||
bf1.getPointLabelFormatter().getTextPaint().setTextAlign(Paint.Align.CENTER);
|
||||
bf1.getPointLabelFormatter().getTextPaint().setFakeBoldText(true);
|
||||
|
||||
// add series to the xyplot:
|
||||
plot.addSeries(series1, bf1);
|
||||
plot.addSeries(series2, new BubbleFormatter(this, R.xml.bubble_formatter2));
|
||||
plot.addSeries(series3, new BubbleFormatter(this, R.xml.bubble_formatter3));
|
||||
PanZoom.attach(plot);
|
||||
}
|
||||
}
|
||||
+167
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright 2016 AndroidPlot.com
|
||||
*
|
||||
* 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.androidplot.demos;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.DashPathEffect;
|
||||
import android.graphics.Paint;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.androidplot.Region;
|
||||
import com.androidplot.util.PixelUtils;
|
||||
import com.androidplot.util.SeriesUtils;
|
||||
import com.androidplot.xy.BoundaryMode;
|
||||
import com.androidplot.xy.CandlestickFormatter;
|
||||
import com.androidplot.xy.CandlestickMaker;
|
||||
import com.androidplot.xy.CandlestickSeries;
|
||||
import com.androidplot.xy.CatmullRomInterpolator;
|
||||
import com.androidplot.xy.LineAndPointFormatter;
|
||||
import com.androidplot.xy.PointLabelFormatter;
|
||||
import com.androidplot.xy.PointLabeler;
|
||||
import com.androidplot.xy.StepMode;
|
||||
import com.androidplot.xy.XYGraphWidget;
|
||||
import com.androidplot.xy.XYPlot;
|
||||
import com.androidplot.xy.XYSeries;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.FieldPosition;
|
||||
import java.text.Format;
|
||||
import java.text.ParsePosition;
|
||||
|
||||
/**
|
||||
* A simple example of a candlestick chart rendered on an {@link XYPlot}.
|
||||
*/
|
||||
public class CandlestickChartActivity extends Activity {
|
||||
|
||||
private XYPlot plot;
|
||||
|
||||
private DecimalFormat currencyFormat = new DecimalFormat("$0.00");
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.candlestick_example);
|
||||
|
||||
// initialize our XYPlot reference:
|
||||
plot = (XYPlot) findViewById(R.id.plot);
|
||||
|
||||
final CandlestickSeries candlestickSeries = new CandlestickSeries(
|
||||
new CandlestickSeries.Item(1, 10, 2, 9.04),
|
||||
new CandlestickSeries.Item(4, 18, 6, 5.50),
|
||||
new CandlestickSeries.Item(3, 11, 5, 9.21),
|
||||
new CandlestickSeries.Item(2, 17, 2, 15.25),
|
||||
new CandlestickSeries.Item(6, 11, 11, 7.12),
|
||||
new CandlestickSeries.Item(8, 16, 10, 15.02));
|
||||
|
||||
// draw a simple line plot of the close vals:
|
||||
LineAndPointFormatter lpf = new LineAndPointFormatter(Color.BLACK, Color.BLACK, null, null);
|
||||
lpf.getLinePaint().setPathEffect(
|
||||
new DashPathEffect(
|
||||
new float[] {PixelUtils.dpToPix(5), PixelUtils.dpToPix(5)}, 0));
|
||||
lpf.setInterpolationParams(
|
||||
new CatmullRomInterpolator.Params(20, CatmullRomInterpolator.Type.Centripetal));
|
||||
|
||||
plot.addSeries(candlestickSeries.getCloseSeries(), lpf);
|
||||
|
||||
CandlestickFormatter formatter = new CandlestickFormatter(this, R.xml.candlestick_formatter);
|
||||
|
||||
// draw candlestick bodies as triangles instead of squares:
|
||||
// triangles will point up for items that closed higher than they opened
|
||||
// and down for those that closed lower:
|
||||
formatter.setBodyStyle(CandlestickFormatter.BodyStyle.SQUARE);
|
||||
|
||||
// add the candlestick series data to the plot:
|
||||
CandlestickMaker.make(plot, formatter, candlestickSeries);
|
||||
|
||||
// setup the range tick label formatting, etc:
|
||||
plot.setLinesPerRangeLabel(3);
|
||||
|
||||
plot.getGraph().getLineLabelStyle(XYGraphWidget.Edge.LEFT).
|
||||
setFormat(currencyFormat);
|
||||
|
||||
// add some padding to range boundaries:
|
||||
final Region minMax = SeriesUtils.minMax(
|
||||
candlestickSeries.getHighSeries().getyVals(),
|
||||
candlestickSeries.getLowSeries().getyVals());
|
||||
|
||||
plot.setRangeBoundaries(
|
||||
minMax.getMin().doubleValue() - 1,
|
||||
minMax.getMax().doubleValue() + 1,
|
||||
BoundaryMode.FIXED);
|
||||
|
||||
|
||||
// setup the domain tick label formatting, etc:
|
||||
plot.setDomainBoundaries(-1, 6, BoundaryMode.FIXED);
|
||||
plot.setDomainStep(StepMode.INCREMENT_BY_VAL, 1);
|
||||
plot.getGraph().getLineLabelStyle(XYGraphWidget.Edge.BOTTOM).setFormat(new Format() {
|
||||
@Override
|
||||
public StringBuffer format(Object object, @NonNull StringBuffer buffer,
|
||||
@NonNull FieldPosition field) {
|
||||
int day = ((Number) object).intValue() % 7;
|
||||
switch (day) {
|
||||
case 0:
|
||||
buffer.append("Sun");
|
||||
break;
|
||||
case 1:
|
||||
buffer.append("Mon");
|
||||
break;
|
||||
case 2:
|
||||
buffer.append("Tues");
|
||||
break;
|
||||
case 3:
|
||||
buffer.append("Wed");
|
||||
break;
|
||||
case 4:
|
||||
buffer.append("Thurs");
|
||||
break;
|
||||
case 5:
|
||||
buffer.append("Fri");
|
||||
break;
|
||||
case 6:
|
||||
buffer.append("Sat");
|
||||
default:
|
||||
// show nothing
|
||||
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object parseObject(String string, @NonNull ParsePosition position) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
formatter.setPointLabelFormatter(
|
||||
new PointLabelFormatter(Color.BLACK, PixelUtils.dpToPix(8), 0));
|
||||
formatter.getPointLabelFormatter().getTextPaint().setFakeBoldText(true);
|
||||
formatter.getPointLabelFormatter().getTextPaint().setTextAlign(Paint.Align.LEFT);
|
||||
|
||||
// add labels for close vals:
|
||||
formatter.setPointLabeler(new PointLabeler() {
|
||||
@Override
|
||||
public String getLabel(XYSeries series, int index) {
|
||||
if(series == candlestickSeries.getCloseSeries()) {
|
||||
return currencyFormat.format(series.getY(index).doubleValue());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.androidplot.demos;
|
||||
|
||||
import android.app.*;
|
||||
|
||||
public class DemoApplication extends Application {
|
||||
|
||||
@Override public void onCreate() {
|
||||
super.onCreate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright 2015 AndroidPlot.com
|
||||
*
|
||||
* 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.androidplot.demos;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.DashPathEffect;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.androidplot.util.PixelUtils;
|
||||
import com.androidplot.xy.BoundaryMode;
|
||||
import com.androidplot.xy.CatmullRomInterpolator;
|
||||
import com.androidplot.xy.LineAndPointFormatter;
|
||||
import com.androidplot.xy.NormedXYSeries;
|
||||
import com.androidplot.xy.SimpleXYSeries;
|
||||
import com.androidplot.xy.StepMode;
|
||||
import com.androidplot.xy.XYGraphWidget;
|
||||
import com.androidplot.xy.XYPlot;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.FieldPosition;
|
||||
import java.text.Format;
|
||||
import java.text.ParsePosition;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Demonstrates normalizing series data using {@link com.androidplot.xy.NormedXYSeries}
|
||||
* and displaying a dual scale on an XYPlot.
|
||||
*
|
||||
* This particular example displays the yearly cost of raising of a child along the federal
|
||||
* minimum wage from 2012 to 2016.
|
||||
*
|
||||
*/
|
||||
public class DualScaleActivity extends Activity {
|
||||
|
||||
private XYPlot plot;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.dual_scale_example);
|
||||
plot = (XYPlot) findViewById(R.id.plot);
|
||||
|
||||
Number[] childCosts = {5500, 5550,5496, 5800, 5815};
|
||||
Number[] minWages = {9, 9, 9, 9, 10};
|
||||
|
||||
// create and normalize series data:
|
||||
final NormedXYSeries costsSeries = new NormedXYSeries(new SimpleXYSeries(
|
||||
Arrays.asList(childCosts), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Yearly Cost"));
|
||||
final NormedXYSeries minWageSeries = new NormedXYSeries(new SimpleXYSeries(
|
||||
Arrays.asList(minWages), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Min Wage"));
|
||||
|
||||
// create formatters to use for drawing a series using LineAndPointRenderer
|
||||
// and configure them from xml:
|
||||
LineAndPointFormatter childCostsFormat =
|
||||
new LineAndPointFormatter(this, R.xml.line_point_formatter_with_labels);
|
||||
childCostsFormat.setVertexPaint(null);
|
||||
childCostsFormat.setPointLabelFormatter(null);
|
||||
|
||||
LineAndPointFormatter minWageFormat =
|
||||
new LineAndPointFormatter(this, R.xml.line_point_formatter_with_labels_2);
|
||||
minWageFormat.setVertexPaint(null);
|
||||
minWageFormat.setPointLabelFormatter(null);
|
||||
|
||||
// add an "dash" effect to the series2 line:
|
||||
minWageFormat.getLinePaint().setPathEffect(new DashPathEffect(new float[] {
|
||||
|
||||
// always use DP when specifying pixel sizes, to keep things consistent across devices:
|
||||
PixelUtils.dpToPix(20),
|
||||
PixelUtils.dpToPix(15)}, 0));
|
||||
|
||||
// add some smoothing to the lines:
|
||||
// see: http://androidplot.com/smooth-curves-and-androidplot/
|
||||
childCostsFormat.setInterpolationParams(
|
||||
new CatmullRomInterpolator.Params(10, CatmullRomInterpolator.Type.Centripetal));
|
||||
|
||||
minWageFormat.setInterpolationParams(
|
||||
new CatmullRomInterpolator.Params(10, CatmullRomInterpolator.Type.Centripetal));
|
||||
|
||||
// add a new series' to the xyplot:
|
||||
plot.addSeries(costsSeries, childCostsFormat);
|
||||
plot.addSeries(minWageSeries, minWageFormat);
|
||||
|
||||
plot.setRangeBoundaries(-1, 2, BoundaryMode.FIXED);
|
||||
|
||||
plot.getGraph().getLineLabelStyle(XYGraphWidget.Edge.LEFT).getPaint().setColor(Color.GREEN);
|
||||
plot.getGraph().getLineLabelStyle(XYGraphWidget.Edge.LEFT).setFormat(new Format() {
|
||||
|
||||
final DecimalFormat df = new DecimalFormat("$#,###");
|
||||
|
||||
@Override
|
||||
public StringBuffer format(Object o, @NonNull StringBuffer stringBuffer,
|
||||
@NonNull FieldPosition fieldPosition) {
|
||||
final Number cost = costsSeries.denormalizeYVal((Number) o);
|
||||
stringBuffer.append(df.format(cost.doubleValue()));
|
||||
return stringBuffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object parseObject(String s, @NonNull ParsePosition parsePosition) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
plot.getGraph().getLineLabelStyle(XYGraphWidget.Edge.RIGHT).getPaint().setColor(Color.BLUE);
|
||||
plot.getGraph().getLineLabelStyle(XYGraphWidget.Edge.RIGHT).setFormat(new Format() {
|
||||
|
||||
final DecimalFormat df = new DecimalFormat("$#.##");
|
||||
|
||||
@Override
|
||||
public StringBuffer format(Object o, @NonNull StringBuffer stringBuffer,
|
||||
@NonNull FieldPosition fieldPosition) {
|
||||
Number minWage = minWageSeries.denormalizeYVal((Number) o);
|
||||
stringBuffer.append(df.format(minWage.doubleValue()));
|
||||
return stringBuffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object parseObject(String s, @NonNull ParsePosition parsePosition) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
plot.setDomainStep(StepMode.INCREMENT_BY_VAL, 1);
|
||||
plot.getGraph().getLineLabelStyle(XYGraphWidget.Edge.BOTTOM).setFormat(new Format() {
|
||||
|
||||
@Override
|
||||
public StringBuffer format(Object o, @NonNull StringBuffer stringBuffer,
|
||||
@NonNull FieldPosition fieldPosition) {
|
||||
|
||||
Number year = ((Number) o).intValue() + 2012;
|
||||
stringBuffer.append(year);
|
||||
return stringBuffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object parseObject(String s, @NonNull ParsePosition parsePosition) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,252 @@
|
||||
/*
|
||||
* Copyright 2015 AndroidPlot.com
|
||||
*
|
||||
* 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.androidplot.demos;
|
||||
import android.app.Activity;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.DashPathEffect;
|
||||
import android.graphics.Paint;
|
||||
import android.os.Bundle;
|
||||
import com.androidplot.Plot;
|
||||
import com.androidplot.util.PixelUtils;
|
||||
import com.androidplot.xy.XYSeries;
|
||||
import com.androidplot.xy.*;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
|
||||
public class DynamicXYPlotActivity extends Activity {
|
||||
|
||||
// redraws a plot whenever an update is received:
|
||||
private class MyPlotUpdater implements Observer {
|
||||
Plot plot;
|
||||
|
||||
public MyPlotUpdater(Plot plot) {
|
||||
this.plot = plot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Observable o, Object arg) {
|
||||
plot.redraw();
|
||||
}
|
||||
}
|
||||
|
||||
private XYPlot dynamicPlot;
|
||||
private MyPlotUpdater plotUpdater;
|
||||
SampleDynamicXYDatasource data;
|
||||
private Thread myThread;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
// android boilerplate stuff
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.dynamic_xyplot_example);
|
||||
|
||||
// get handles to our View defined in layout.xml:
|
||||
dynamicPlot = (XYPlot) findViewById(R.id.dynamicXYPlot);
|
||||
|
||||
plotUpdater = new MyPlotUpdater(dynamicPlot);
|
||||
|
||||
// only display whole numbers in domain labels
|
||||
dynamicPlot.getGraph().getLineLabelStyle(XYGraphWidget.Edge.BOTTOM).
|
||||
setFormat(new DecimalFormat("0"));
|
||||
|
||||
// getInstance and position datasets:
|
||||
data = new SampleDynamicXYDatasource();
|
||||
SampleDynamicSeries sine1Series = new SampleDynamicSeries(data, 0, "Sine 1");
|
||||
SampleDynamicSeries sine2Series = new SampleDynamicSeries(data, 1, "Sine 2");
|
||||
|
||||
LineAndPointFormatter formatter1 = new LineAndPointFormatter(
|
||||
Color.rgb(0, 200, 0), null, null, null);
|
||||
formatter1.getLinePaint().setStrokeJoin(Paint.Join.ROUND);
|
||||
formatter1.getLinePaint().setStrokeWidth(10);
|
||||
dynamicPlot.addSeries(sine1Series,
|
||||
formatter1);
|
||||
|
||||
LineAndPointFormatter formatter2 =
|
||||
new LineAndPointFormatter(Color.rgb(0, 0, 200), null, null, null);
|
||||
formatter2.getLinePaint().setStrokeWidth(10);
|
||||
formatter2.getLinePaint().setStrokeJoin(Paint.Join.ROUND);
|
||||
|
||||
//formatter2.getFillPaint().setAlpha(220);
|
||||
dynamicPlot.addSeries(sine2Series, formatter2);
|
||||
|
||||
// hook up the plotUpdater to the data model:
|
||||
data.addObserver(plotUpdater);
|
||||
|
||||
// thin out domain tick labels so they dont overlap each other:
|
||||
dynamicPlot.setDomainStepMode(StepMode.INCREMENT_BY_VAL);
|
||||
dynamicPlot.setDomainStepValue(5);
|
||||
|
||||
dynamicPlot.setRangeStepMode(StepMode.INCREMENT_BY_VAL);
|
||||
dynamicPlot.setRangeStepValue(10);
|
||||
|
||||
dynamicPlot.getGraph().getLineLabelStyle(
|
||||
XYGraphWidget.Edge.LEFT).setFormat(new DecimalFormat("###.#"));
|
||||
|
||||
// uncomment this line to freeze the range boundaries:
|
||||
dynamicPlot.setRangeBoundaries(-100, 100, BoundaryMode.FIXED);
|
||||
|
||||
// create a dash effect for domain and range grid lines:
|
||||
DashPathEffect dashFx = new DashPathEffect(
|
||||
new float[] {PixelUtils.dpToPix(3), PixelUtils.dpToPix(3)}, 0);
|
||||
dynamicPlot.getGraph().getDomainGridLinePaint().setPathEffect(dashFx);
|
||||
dynamicPlot.getGraph().getRangeGridLinePaint().setPathEffect(dashFx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
// kick off the data generating thread:
|
||||
myThread = new Thread(data);
|
||||
myThread.start();
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
data.stopThread();
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
class SampleDynamicXYDatasource implements Runnable {
|
||||
|
||||
// encapsulates management of the observers watching this datasource for update events:
|
||||
class MyObservable extends Observable {
|
||||
@Override
|
||||
public void notifyObservers() {
|
||||
setChanged();
|
||||
super.notifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
private static final double FREQUENCY = 5; // larger is lower frequency
|
||||
private static final int MAX_AMP_SEED = 100;
|
||||
private static final int MIN_AMP_SEED = 10;
|
||||
private static final int AMP_STEP = 1;
|
||||
static final int SINE1 = 0;
|
||||
static final int SINE2 = 1;
|
||||
private static final int SAMPLE_SIZE = 31;
|
||||
private int phase = 0;
|
||||
private int sinAmp = 1;
|
||||
private MyObservable notifier;
|
||||
private boolean keepRunning = false;
|
||||
|
||||
{
|
||||
notifier = new MyObservable();
|
||||
}
|
||||
|
||||
void stopThread() {
|
||||
keepRunning = false;
|
||||
}
|
||||
|
||||
//@Override
|
||||
public void run() {
|
||||
try {
|
||||
keepRunning = true;
|
||||
boolean isRising = true;
|
||||
while (keepRunning) {
|
||||
|
||||
Thread.sleep(10); // decrease or remove to speed up the refresh rate.
|
||||
phase++;
|
||||
if (sinAmp >= MAX_AMP_SEED) {
|
||||
isRising = false;
|
||||
} else if (sinAmp <= MIN_AMP_SEED) {
|
||||
isRising = true;
|
||||
}
|
||||
|
||||
if (isRising) {
|
||||
sinAmp += AMP_STEP;
|
||||
} else {
|
||||
sinAmp -= AMP_STEP;
|
||||
}
|
||||
notifier.notifyObservers();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
int getItemCount(int series) {
|
||||
return SAMPLE_SIZE;
|
||||
}
|
||||
|
||||
Number getX(int series, int index) {
|
||||
if (index >= SAMPLE_SIZE) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
Number getY(int series, int index) {
|
||||
if (index >= SAMPLE_SIZE) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
double angle = (index + (phase))/FREQUENCY;
|
||||
double amp = sinAmp * Math.sin(angle);
|
||||
switch (series) {
|
||||
case SINE1:
|
||||
return amp;
|
||||
case SINE2:
|
||||
return -amp;
|
||||
default:
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
void addObserver(Observer observer) {
|
||||
notifier.addObserver(observer);
|
||||
}
|
||||
|
||||
public void removeObserver(Observer observer) {
|
||||
notifier.deleteObserver(observer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class SampleDynamicSeries implements XYSeries {
|
||||
private SampleDynamicXYDatasource datasource;
|
||||
private int seriesIndex;
|
||||
private String title;
|
||||
|
||||
SampleDynamicSeries(SampleDynamicXYDatasource datasource, int seriesIndex, String title) {
|
||||
this.datasource = datasource;
|
||||
this.seriesIndex = seriesIndex;
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return datasource.getItemCount(seriesIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Number getX(int index) {
|
||||
return datasource.getX(seriesIndex, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Number getY(int index) {
|
||||
return datasource.getY(seriesIndex, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* Copyright 2016 AndroidPlot.com
|
||||
*
|
||||
* 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.androidplot.demos;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.graphics.Paint;
|
||||
import android.os.Bundle;
|
||||
import com.androidplot.Plot;
|
||||
import com.androidplot.util.Redrawer;
|
||||
import com.androidplot.xy.*;
|
||||
|
||||
import java.lang.ref.*;
|
||||
|
||||
/**
|
||||
* An example of a real-time plot displaying an asynchronously updated model of ECG data. There are three
|
||||
* key items to pay attention to here:
|
||||
* 1 - The model data is updated independently of all other data via a background thread. This is typical
|
||||
* of most signal inputs.
|
||||
*
|
||||
* 2 - The main render loop is controlled by a separate thread governed by an instance of {@link Redrawer}.
|
||||
* The alternative is to try synchronously invoking {@link Plot#redraw()} within whatever system is updating
|
||||
* the model, which would severely degrade performance.
|
||||
*
|
||||
* 3 - The plot is set to render using a background thread via config attr in R.layout.ecg_example.xml.
|
||||
* This ensures that the rest of the app will remain responsive during rendering.
|
||||
*/
|
||||
public class ECGExample extends Activity {
|
||||
private XYPlot plot;
|
||||
|
||||
/**
|
||||
* Uses a separate thread to modulate redraw frequency.
|
||||
*/
|
||||
private Redrawer redrawer;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.ecg_example);
|
||||
|
||||
// initialize our XYPlot reference:
|
||||
plot = (XYPlot) findViewById(R.id.plot);
|
||||
|
||||
ECGModel ecgSeries = new ECGModel(2000, 200);
|
||||
|
||||
// add a new series' to the xyplot:
|
||||
MyFadeFormatter formatter =new MyFadeFormatter(2000);
|
||||
formatter.setLegendIconEnabled(false);
|
||||
plot.addSeries(ecgSeries, formatter);
|
||||
plot.setRangeBoundaries(0, 10, BoundaryMode.FIXED);
|
||||
plot.setDomainBoundaries(0, 2000, BoundaryMode.FIXED);
|
||||
|
||||
// reduce the number of range labels
|
||||
plot.setLinesPerRangeLabel(3);
|
||||
|
||||
// start generating ecg data in the background:
|
||||
ecgSeries.start(new WeakReference<>(plot.getRenderer(AdvancedLineAndPointRenderer.class)));
|
||||
|
||||
// set a redraw rate of 30hz and start immediately:
|
||||
redrawer = new Redrawer(plot, 30, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Special {@link AdvancedLineAndPointRenderer.Formatter} that draws a line
|
||||
* that fades over time. Designed to be used in conjunction with a circular buffer model.
|
||||
*/
|
||||
public static class MyFadeFormatter extends AdvancedLineAndPointRenderer.Formatter {
|
||||
|
||||
private int trailSize;
|
||||
|
||||
MyFadeFormatter(int trailSize) {
|
||||
this.trailSize = trailSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Paint getLinePaint(int thisIndex, int latestIndex, int seriesSize) {
|
||||
// offset from the latest index:
|
||||
int offset;
|
||||
if(thisIndex > latestIndex) {
|
||||
offset = latestIndex + (seriesSize - thisIndex);
|
||||
} else {
|
||||
offset = latestIndex - thisIndex;
|
||||
}
|
||||
|
||||
float scale = 255f / trailSize;
|
||||
int alpha = (int) (255 - (offset * scale));
|
||||
getLinePaint().setAlpha(alpha > 0 ? alpha : 0);
|
||||
return getLinePaint();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Primitive simulation of some kind of signal. For this example,
|
||||
* we'll pretend its an ecg. This class represents the data as a circular buffer;
|
||||
* data is added sequentially from left to right. When the end of the buffer is reached,
|
||||
* i is reset back to 0 and simulated sampling continues.
|
||||
*/
|
||||
public static class ECGModel implements XYSeries {
|
||||
|
||||
private final Number[] data;
|
||||
private final long delayMs;
|
||||
private final int blipInteral;
|
||||
private final Thread thread;
|
||||
private boolean keepRunning;
|
||||
private int latestIndex;
|
||||
|
||||
private WeakReference<AdvancedLineAndPointRenderer> rendererRef;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param size Sample size contained within this model
|
||||
* @param updateFreqHz Frequency at which new samples are added to the model
|
||||
*/
|
||||
ECGModel(int size, int updateFreqHz) {
|
||||
data = new Number[size];
|
||||
for(int i = 0; i < data.length; i++) {
|
||||
data[i] = 0;
|
||||
}
|
||||
|
||||
// translate hz into delay (ms):
|
||||
delayMs = 1000 / updateFreqHz;
|
||||
|
||||
// add 7 "blips" into the signal:
|
||||
blipInteral = size / 7;
|
||||
|
||||
thread = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
while (keepRunning) {
|
||||
if (latestIndex >= data.length) {
|
||||
latestIndex = 0;
|
||||
}
|
||||
|
||||
// generate some random data:
|
||||
if (latestIndex % blipInteral == 0) {
|
||||
// insert a "blip" to simulate a heartbeat:
|
||||
data[latestIndex] = (Math.random() * 10) + 3;
|
||||
} else {
|
||||
// insert a random sample:
|
||||
data[latestIndex] = Math.random() * 2;
|
||||
}
|
||||
|
||||
if(latestIndex < data.length - 1) {
|
||||
// null out the point immediately following i, to disable
|
||||
// connecting i and i+1 with a line:
|
||||
data[latestIndex +1] = null;
|
||||
}
|
||||
|
||||
if(rendererRef.get() != null) {
|
||||
rendererRef.get().setLatestIndex(latestIndex);
|
||||
Thread.sleep(delayMs);
|
||||
} else {
|
||||
keepRunning = false;
|
||||
}
|
||||
latestIndex++;
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
keepRunning = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void start(final WeakReference<AdvancedLineAndPointRenderer> rendererRef) {
|
||||
this.rendererRef = rendererRef;
|
||||
keepRunning = true;
|
||||
thread.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return data.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Number getX(int index) {
|
||||
return index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Number getY(int index) {
|
||||
return data[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return "Signal";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
redrawer.finish();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright 2016 AndroidPlot.com
|
||||
*
|
||||
* 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.androidplot.demos;
|
||||
|
||||
import android.app.*;
|
||||
import android.graphics.*;
|
||||
import android.os.*;
|
||||
|
||||
import com.androidplot.util.*;
|
||||
import com.androidplot.xy.*;
|
||||
|
||||
import java.text.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* A simple XYPlot
|
||||
*/
|
||||
public class FXPlotExampleActivity extends Activity {
|
||||
|
||||
private XYPlot plot;
|
||||
|
||||
/**
|
||||
* Custom line label renderer that highlights origin labels
|
||||
*/
|
||||
class MyLineLabelRenderer extends XYGraphWidget.LineLabelRenderer {
|
||||
|
||||
@Override
|
||||
protected void drawLabel(Canvas canvas, String text, Paint paint,
|
||||
float x, float y, boolean isOrigin) {
|
||||
if(isOrigin) {
|
||||
// make the origin labels red:
|
||||
final Paint originPaint = new Paint(paint);
|
||||
originPaint.setColor(Color.RED);
|
||||
super.drawLabel(canvas, text, originPaint, x, y , isOrigin);
|
||||
} else {
|
||||
super.drawLabel(canvas, text, paint, x, y , isOrigin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws every other tick label and renders text in gray instead of white.
|
||||
*/
|
||||
class MySecondaryLabelRenderer extends MyLineLabelRenderer {
|
||||
|
||||
|
||||
@Override
|
||||
public void drawLabel(Canvas canvas, XYGraphWidget.LineLabelStyle style,
|
||||
Number val, float x, float y, boolean isOrigin) {
|
||||
if(val.doubleValue() % 2 == 0) {
|
||||
final Paint paint = style.getPaint();
|
||||
if(!isOrigin) {
|
||||
paint.setColor(Color.GRAY);
|
||||
}
|
||||
super.drawLabel(canvas, style, val, x, y, isOrigin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.fx_plot_example);
|
||||
|
||||
// initialize our XYPlot reference:
|
||||
plot = (XYPlot) findViewById(R.id.plot);
|
||||
|
||||
plot.setDomainStep(StepMode.INCREMENT_BY_VAL, 1);
|
||||
plot.setRangeStep(StepMode.INCREMENT_BY_VAL, 1);
|
||||
|
||||
plot.centerOnDomainOrigin(0);
|
||||
plot.centerOnRangeOrigin(0);
|
||||
|
||||
// create formatters to use for drawing a series using LineAndPointRenderer
|
||||
// and configure them from xml:
|
||||
LineAndPointFormatter series1Format =
|
||||
new LineAndPointFormatter(this, R.xml.line_point_formatter);
|
||||
|
||||
// use our custom renderer to make origin labels red
|
||||
plot.getGraph().setLineLabelRenderer(XYGraphWidget.Edge.BOTTOM, new MyLineLabelRenderer());
|
||||
plot.getGraph().setLineLabelRenderer(XYGraphWidget.Edge.LEFT, new MyLineLabelRenderer());
|
||||
|
||||
// skip every other line for top and right edge labels
|
||||
plot.getGraph().setLineLabelRenderer(XYGraphWidget.Edge.RIGHT, new MySecondaryLabelRenderer());
|
||||
plot.getGraph().setLineLabelRenderer(XYGraphWidget.Edge.TOP, new MySecondaryLabelRenderer());
|
||||
|
||||
// don't show decimal places for top and right edge labels
|
||||
plot.getGraph().getLineLabelStyle(XYGraphWidget.Edge.TOP).setFormat(new DecimalFormat("0"));
|
||||
plot.getGraph().getLineLabelStyle(XYGraphWidget.Edge.RIGHT).setFormat(new DecimalFormat("0"));
|
||||
|
||||
// create a dash effect for domain and range grid lines:
|
||||
DashPathEffect dashFx = new DashPathEffect(
|
||||
new float[] {PixelUtils.dpToPix(3), PixelUtils.dpToPix(3)}, 0);
|
||||
plot.getGraph().getDomainGridLinePaint().setPathEffect(dashFx);
|
||||
plot.getGraph().getRangeGridLinePaint().setPathEffect(dashFx);
|
||||
|
||||
// add a new series' to the xyplot:
|
||||
plot.addSeries(generateSeries(-5, 5, 100), series1Format);
|
||||
}
|
||||
|
||||
protected XYSeries generateSeries(double minX, double maxX, double resolution) {
|
||||
final double range = maxX - minX;
|
||||
final double step = range / resolution;
|
||||
List<Number> xVals = new ArrayList<>();
|
||||
List<Number> yVals = new ArrayList<>();
|
||||
|
||||
double x = minX;
|
||||
while (x <= maxX) {
|
||||
xVals.add(x);
|
||||
yVals.add(fx(x));
|
||||
x +=step;
|
||||
}
|
||||
|
||||
return new SimpleXYSeries(xVals, yVals, "f(x) = (x^2) - 13");
|
||||
}
|
||||
|
||||
protected double fx(double x) {
|
||||
return Math.abs(x*x) - 13;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright 2015 AndroidPlot.com
|
||||
*
|
||||
* 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.androidplot.demos;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ListView;
|
||||
|
||||
import com.androidplot.Plot;
|
||||
import com.androidplot.ui.SeriesBundle;
|
||||
import com.androidplot.util.PixelUtils;
|
||||
import com.androidplot.xy.CatmullRomInterpolator;
|
||||
import com.androidplot.xy.LineAndPointFormatter;
|
||||
import com.androidplot.xy.SimpleXYSeries;
|
||||
import com.androidplot.xy.XYPlot;
|
||||
import com.androidplot.xy.XYSeries;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
public class ListViewActivity extends Activity {
|
||||
private static final int NUM_PLOTS = 10;
|
||||
private static final int NUM_POINTS_PER_SERIES = 10;
|
||||
private static final int NUM_SERIES_PER_PLOT = 5;
|
||||
private ListView lv;
|
||||
|
||||
private List<List<SeriesBundle<XYSeries, LineAndPointFormatter>>> seriesData = new ArrayList<>(NUM_PLOTS);
|
||||
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.listview_example);
|
||||
PixelUtils.init(this);
|
||||
generateData();
|
||||
lv = (ListView) findViewById(R.id.listView1);
|
||||
lv.setAdapter(new MyViewAdapter(getApplicationContext(), R.layout.listview_example_item, null));
|
||||
}
|
||||
|
||||
protected void generateData() {
|
||||
Random generator = new Random();
|
||||
for(int i = 0; i < NUM_PLOTS; i++) {
|
||||
List<SeriesBundle<XYSeries, LineAndPointFormatter>> seriesList
|
||||
= new ArrayList<>(NUM_SERIES_PER_PLOT);
|
||||
|
||||
for (int k = 0; k < NUM_SERIES_PER_PLOT; k++) {
|
||||
ArrayList<Number> nums = new ArrayList<>();
|
||||
for (int j = 0; j < NUM_POINTS_PER_SERIES; j++) {
|
||||
nums.add(generator.nextFloat());
|
||||
}
|
||||
|
||||
double rl = Math.random();
|
||||
double gl = Math.random();
|
||||
double bl = Math.random();
|
||||
|
||||
double rp = Math.random();
|
||||
double gp = Math.random();
|
||||
double bp = Math.random();
|
||||
|
||||
LineAndPointFormatter lpf = new LineAndPointFormatter(
|
||||
Color.rgb(Double.valueOf(rl * 255).intValue(),
|
||||
Double.valueOf(gl * 255).intValue(), Double.valueOf(bl * 255).intValue()),
|
||||
Color.rgb(Double.valueOf(rp * 255).intValue(),
|
||||
Double.valueOf(gp * 255).intValue(), Double.valueOf(bp * 255).intValue()),
|
||||
null, null);
|
||||
|
||||
// for fun, configure interpolation on the formatter:
|
||||
lpf.setInterpolationParams(
|
||||
new CatmullRomInterpolator.Params(20, CatmullRomInterpolator.Type.Centripetal));
|
||||
|
||||
seriesList.add(new SeriesBundle<XYSeries, LineAndPointFormatter>(
|
||||
new SimpleXYSeries(nums, SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "S" + k),
|
||||
lpf));
|
||||
}
|
||||
seriesData.add(seriesList);
|
||||
}
|
||||
}
|
||||
|
||||
class MyViewAdapter extends ArrayAdapter<View> {
|
||||
public MyViewAdapter(Context context, int resId, List<View> views) {
|
||||
super(context, resId, views);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return NUM_PLOTS;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public View getView(int pos, View convertView, @NonNull ViewGroup parent) {
|
||||
LayoutInflater inf = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
|
||||
View v = convertView;
|
||||
if (v == null) {
|
||||
v = inf.inflate(R.layout.listview_example_item, parent, false);
|
||||
}
|
||||
|
||||
Plot p = (XYPlot) v.findViewById(R.id.xyplot);
|
||||
p.clear();
|
||||
p.getTitle().setText("plot" + pos);
|
||||
|
||||
List<SeriesBundle<XYSeries, LineAndPointFormatter>> thisSeriesList = seriesData.get(pos);
|
||||
for(SeriesBundle<XYSeries, LineAndPointFormatter> sf : thisSeriesList) {
|
||||
p.addSeries(sf.getSeries(), sf.getFormatter());
|
||||
}
|
||||
p.redraw();
|
||||
return v;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright 2021 AndroidPlot.com
|
||||
*
|
||||
* 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.androidplot.demos
|
||||
|
||||
import android.app.Activity
|
||||
import android.os.Bundle
|
||||
import android.content.Intent
|
||||
import com.androidplot.demos.databinding.MainBinding
|
||||
|
||||
class MainActivity : Activity() {
|
||||
|
||||
private lateinit var binding: MainBinding
|
||||
|
||||
public override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = MainBinding.inflate(layoutInflater)
|
||||
|
||||
binding.animatedXYPlotExButton.setOnClickListener {
|
||||
startActivity(Intent(this, AnimatedXYPlotActivity::class.java))
|
||||
}
|
||||
|
||||
binding.startScatterExButton.setOnClickListener {
|
||||
startActivity(Intent(this, ScatterPlotActivity::class.java))
|
||||
}
|
||||
|
||||
binding.startSimplePieExButton.setOnClickListener {
|
||||
startActivity(Intent(this, SimplePieChartActivity::class.java))
|
||||
}
|
||||
|
||||
binding.startDynamicXYExButton.setOnClickListener {
|
||||
startActivity(Intent(this@MainActivity, DynamicXYPlotActivity::class.java))
|
||||
}
|
||||
|
||||
binding.startCandlestickExButton.setOnClickListener {
|
||||
startActivity(Intent(this@MainActivity, CandlestickChartActivity::class.java))
|
||||
}
|
||||
|
||||
binding.startSimpleXYExButton.setOnClickListener {
|
||||
startActivity(Intent(this@MainActivity, SimpleXYPlotActivity::class.java))
|
||||
}
|
||||
|
||||
binding.startBarPlotExButton.setOnClickListener {
|
||||
startActivity(Intent(this@MainActivity, BarPlotExampleActivity::class.java))
|
||||
}
|
||||
|
||||
binding.startOrSensorExButton.setOnClickListener {
|
||||
startActivity(Intent(this@MainActivity, OrientationSensorExampleActivity::class.java))
|
||||
}
|
||||
|
||||
binding.startDualScaleExButton.setOnClickListener {
|
||||
startActivity(Intent(this@MainActivity, DualScaleActivity::class.java))
|
||||
}
|
||||
|
||||
binding.startTimeSeriesExButton.setOnClickListener {
|
||||
startActivity(Intent(this@MainActivity, TimeSeriesActivity::class.java))
|
||||
}
|
||||
|
||||
binding.startStepChartExButton.setOnClickListener {
|
||||
startActivity(Intent(this@MainActivity, StepChartExampleActivity::class.java))
|
||||
}
|
||||
|
||||
binding.startScrollZoomButton.setOnClickListener {
|
||||
startActivity(Intent(this@MainActivity, TouchZoomExampleActivity::class.java))
|
||||
}
|
||||
|
||||
binding.startXyRegionExampleButton.setOnClickListener {
|
||||
startActivity(Intent(this@MainActivity, XYRegionExampleActivity::class.java))
|
||||
}
|
||||
|
||||
binding.startXyListViewExButton.setOnClickListener {
|
||||
startActivity(Intent(this@MainActivity, ListViewActivity::class.java))
|
||||
}
|
||||
|
||||
binding.startXyRecyclerViewExButton.setOnClickListener {
|
||||
startActivity(Intent(this@MainActivity, RecyclerViewActivity::class.java))
|
||||
}
|
||||
|
||||
binding.startXYPlotWithBgImgExample.setOnClickListener {
|
||||
startActivity(Intent(this@MainActivity, XYPlotWithBgImgActivity::class.java))
|
||||
}
|
||||
|
||||
binding.startECGExample.setOnClickListener {
|
||||
startActivity(Intent(this@MainActivity, ECGExample::class.java))
|
||||
}
|
||||
|
||||
binding.fxPlotExample.setOnClickListener {
|
||||
startActivity(Intent(this@MainActivity, FXPlotExampleActivity::class.java))
|
||||
}
|
||||
|
||||
binding.bubbleChartExample.setOnClickListener {
|
||||
startActivity(Intent(this@MainActivity, BubbleChartActivity::class.java))
|
||||
}
|
||||
|
||||
setContentView(binding.root)
|
||||
}
|
||||
}
|
||||
+251
@@ -0,0 +1,251 @@
|
||||
/*
|
||||
* Copyright 2015 AndroidPlot.com
|
||||
*
|
||||
* 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.androidplot.demos;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.*;
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorEvent;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorManager;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import com.androidplot.Plot;
|
||||
import com.androidplot.util.PixelUtils;
|
||||
import com.androidplot.util.PlotStatistics;
|
||||
import com.androidplot.util.Redrawer;
|
||||
import com.androidplot.xy.*;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.Arrays;
|
||||
|
||||
// Monitor the phone's orientation sensor and plot the resulting azimuth pitch and roll values.
|
||||
// See: http://developer.android.com/reference/android/hardware/SensorEvent.html
|
||||
public class OrientationSensorExampleActivity extends Activity implements SensorEventListener
|
||||
{
|
||||
private static final int HISTORY_SIZE = 1000;
|
||||
private SensorManager sensorMgr = null;
|
||||
private Sensor orSensor = null;
|
||||
|
||||
private XYPlot aprLevelsPlot = null;
|
||||
private XYPlot aprHistoryPlot = null;
|
||||
|
||||
private CheckBox hwAcceleratedCb;
|
||||
private CheckBox showFpsCb;
|
||||
|
||||
private SimpleXYSeries aLvlSeries;
|
||||
private SimpleXYSeries pLvlSeries;
|
||||
private SimpleXYSeries rLvlSeries;
|
||||
private SimpleXYSeries azimuthHistorySeries = null;
|
||||
private SimpleXYSeries pitchHistorySeries = null;
|
||||
private SimpleXYSeries rollHistorySeries = null;
|
||||
|
||||
private Redrawer redrawer;
|
||||
|
||||
/** Called when the activity is first created. */
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.orientation_sensor_example);
|
||||
|
||||
// setup the APR Levels plot:
|
||||
aprLevelsPlot = (XYPlot) findViewById(R.id.aprLevelsPlot);
|
||||
aprLevelsPlot.setDomainBoundaries(-1, 1, BoundaryMode.FIXED);
|
||||
|
||||
aLvlSeries = new SimpleXYSeries("A");
|
||||
pLvlSeries = new SimpleXYSeries("P");
|
||||
rLvlSeries = new SimpleXYSeries("R");
|
||||
|
||||
aprLevelsPlot.addSeries(aLvlSeries,
|
||||
new BarFormatter(Color.rgb(0, 200, 0), Color.rgb(0, 80, 0)));
|
||||
aprLevelsPlot.addSeries(pLvlSeries,
|
||||
new BarFormatter(Color.rgb(200, 0, 0), Color.rgb(0, 80, 0)));
|
||||
aprLevelsPlot.addSeries(rLvlSeries,
|
||||
new BarFormatter(Color.rgb(0, 0, 200), Color.rgb(0, 80, 0)));
|
||||
|
||||
aprLevelsPlot.setDomainStepValue(3);
|
||||
aprLevelsPlot.setLinesPerRangeLabel(3);
|
||||
|
||||
// per the android documentation, the minimum and maximum readings we can get from
|
||||
// any of the orientation sensors is -180 and 359 respectively so we will fix our plot's
|
||||
// boundaries to those values. If we did not do this, the plot would auto-range which
|
||||
// can be visually confusing in the case of dynamic plots.
|
||||
aprLevelsPlot.setRangeBoundaries(-180, 359, BoundaryMode.FIXED);
|
||||
|
||||
// update our domain and range axis labels:
|
||||
aprLevelsPlot.setDomainLabel("");
|
||||
aprLevelsPlot.getDomainTitle().pack();
|
||||
aprLevelsPlot.setRangeLabel("Angle (Degs)");
|
||||
aprLevelsPlot.getRangeTitle().pack();
|
||||
aprLevelsPlot.getGraph().getLineLabelStyle(XYGraphWidget.Edge.LEFT).
|
||||
setFormat(new DecimalFormat("#"));
|
||||
|
||||
// setup the APR History plot:
|
||||
aprHistoryPlot = (XYPlot) findViewById(R.id.aprHistoryPlot);
|
||||
|
||||
azimuthHistorySeries = new SimpleXYSeries("Az.");
|
||||
azimuthHistorySeries.useImplicitXVals();
|
||||
pitchHistorySeries = new SimpleXYSeries("Pitch");
|
||||
pitchHistorySeries.useImplicitXVals();
|
||||
rollHistorySeries = new SimpleXYSeries("Roll");
|
||||
rollHistorySeries.useImplicitXVals();
|
||||
|
||||
aprHistoryPlot.setRangeBoundaries(-180, 359, BoundaryMode.FIXED);
|
||||
aprHistoryPlot.setDomainBoundaries(0, HISTORY_SIZE, BoundaryMode.FIXED);
|
||||
aprHistoryPlot.addSeries(azimuthHistorySeries,
|
||||
new LineAndPointFormatter(
|
||||
Color.rgb(100, 100, 200), null, null, null));
|
||||
aprHistoryPlot.addSeries(pitchHistorySeries,
|
||||
new LineAndPointFormatter(
|
||||
Color.rgb(100, 200, 100), null, null, null));
|
||||
aprHistoryPlot.addSeries(rollHistorySeries,
|
||||
new LineAndPointFormatter(
|
||||
Color.rgb(200, 100, 100), null, null, null));
|
||||
aprHistoryPlot.setDomainStepMode(StepMode.INCREMENT_BY_VAL);
|
||||
aprHistoryPlot.setDomainStepValue(HISTORY_SIZE/10);
|
||||
aprHistoryPlot.setLinesPerRangeLabel(3);
|
||||
aprHistoryPlot.setDomainLabel("Sample Index");
|
||||
aprHistoryPlot.getDomainTitle().pack();
|
||||
aprHistoryPlot.setRangeLabel("Angle (Degs)");
|
||||
aprHistoryPlot.getRangeTitle().pack();
|
||||
|
||||
aprHistoryPlot.getGraph().getLineLabelStyle(XYGraphWidget.Edge.LEFT).
|
||||
setFormat(new DecimalFormat("#"));
|
||||
|
||||
aprHistoryPlot.getGraph().getLineLabelStyle(XYGraphWidget.Edge.BOTTOM).
|
||||
setFormat(new DecimalFormat("#"));
|
||||
|
||||
// setup checkboxes:
|
||||
hwAcceleratedCb = (CheckBox) findViewById(R.id.hwAccelerationCb);
|
||||
final PlotStatistics levelStats = new PlotStatistics(1000, false);
|
||||
final PlotStatistics histStats = new PlotStatistics(1000, false);
|
||||
|
||||
aprLevelsPlot.addListener(levelStats);
|
||||
aprHistoryPlot.addListener(histStats);
|
||||
hwAcceleratedCb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
|
||||
if(b) {
|
||||
aprLevelsPlot.setLayerType(View.LAYER_TYPE_NONE, null);
|
||||
aprHistoryPlot.setLayerType(View.LAYER_TYPE_NONE, null);
|
||||
} else {
|
||||
aprLevelsPlot.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
|
||||
aprHistoryPlot.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
showFpsCb = (CheckBox) findViewById(R.id.showFpsCb);
|
||||
showFpsCb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
|
||||
levelStats.setAnnotatePlotEnabled(b);
|
||||
histStats.setAnnotatePlotEnabled(b);
|
||||
}
|
||||
});
|
||||
|
||||
// get a ref to the BarRenderer so we can make some changes to it:
|
||||
BarRenderer barRenderer = aprLevelsPlot.getRenderer(BarRenderer.class);
|
||||
if(barRenderer != null) {
|
||||
// make our bars a little thicker than the default so they can be seen better:
|
||||
barRenderer.setBarGroupWidth(
|
||||
BarRenderer.BarGroupWidthMode.FIXED_WIDTH, PixelUtils.dpToPix(18));
|
||||
}
|
||||
|
||||
// register for orientation sensor events:
|
||||
sensorMgr = (SensorManager) getApplicationContext().getSystemService(Context.SENSOR_SERVICE);
|
||||
for (Sensor sensor : sensorMgr.getSensorList(Sensor.TYPE_ORIENTATION)) {
|
||||
if (sensor.getType() == Sensor.TYPE_ORIENTATION) {
|
||||
orSensor = sensor;
|
||||
}
|
||||
}
|
||||
|
||||
// if we can't access the orientation sensor then exit:
|
||||
if (orSensor == null) {
|
||||
System.out.println("Failed to attach to orSensor.");
|
||||
cleanup();
|
||||
}
|
||||
|
||||
sensorMgr.registerListener(this, orSensor, SensorManager.SENSOR_DELAY_UI);
|
||||
|
||||
redrawer = new Redrawer(
|
||||
Arrays.asList(new Plot[]{aprHistoryPlot, aprLevelsPlot}),
|
||||
100, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
redrawer.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
redrawer.pause();
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
redrawer.finish();
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
private void cleanup() {
|
||||
// aunregister with the orientation sensor before exiting:
|
||||
sensorMgr.unregisterListener(this);
|
||||
finish();
|
||||
}
|
||||
|
||||
|
||||
// Called whenever a new orSensor reading is taken.
|
||||
@Override
|
||||
public synchronized void onSensorChanged(SensorEvent sensorEvent) {
|
||||
|
||||
// update level data:
|
||||
aLvlSeries.setModel(Arrays.asList(
|
||||
new Number[]{sensorEvent.values[0]}),
|
||||
SimpleXYSeries.ArrayFormat.Y_VALS_ONLY);
|
||||
|
||||
pLvlSeries.setModel(Arrays.asList(
|
||||
new Number[]{sensorEvent.values[1]}),
|
||||
SimpleXYSeries.ArrayFormat.Y_VALS_ONLY);
|
||||
|
||||
rLvlSeries.setModel(Arrays.asList(
|
||||
new Number[]{sensorEvent.values[2]}),
|
||||
SimpleXYSeries.ArrayFormat.Y_VALS_ONLY);
|
||||
|
||||
// get rid the oldest sample in history:
|
||||
if (rollHistorySeries.size() > HISTORY_SIZE) {
|
||||
rollHistorySeries.removeFirst();
|
||||
pitchHistorySeries.removeFirst();
|
||||
azimuthHistorySeries.removeFirst();
|
||||
}
|
||||
|
||||
// add the latest history sample:
|
||||
azimuthHistorySeries.addLast(null, sensorEvent.values[0]);
|
||||
pitchHistorySeries.addLast(null, sensorEvent.values[1]);
|
||||
rollHistorySeries.addLast(null, sensorEvent.values[2]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccuracyChanged(Sensor sensor, int i) {
|
||||
// Not interested in this event
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright 2021 AndroidPlot.com
|
||||
*
|
||||
* 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.androidplot.demos
|
||||
|
||||
import android.app.Activity
|
||||
import android.graphics.Color
|
||||
import com.androidplot.ui.SeriesBundle
|
||||
import android.os.Bundle
|
||||
import android.view.ViewGroup
|
||||
import android.view.LayoutInflater
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.androidplot.demos.databinding.RecyclerviewExampleBinding
|
||||
import com.androidplot.demos.databinding.RecyclerviewExampleItemBinding
|
||||
import com.androidplot.util.PixelUtils
|
||||
import com.androidplot.xy.*
|
||||
import java.util.*
|
||||
|
||||
class RecyclerViewActivity : Activity() {
|
||||
private lateinit var binding: RecyclerviewExampleBinding
|
||||
|
||||
companion object {
|
||||
private const val NUM_PLOTS = 10
|
||||
private const val NUM_POINTS_PER_SERIES = 10
|
||||
private const val NUM_SERIES_PER_PLOT = 5
|
||||
}
|
||||
|
||||
public override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
PixelUtils.init(this)
|
||||
|
||||
binding = RecyclerviewExampleBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
||||
binding.recyclerView.setHasFixedSize(true)
|
||||
binding.recyclerView.layoutManager = LinearLayoutManager(this)
|
||||
binding.recyclerView.adapter = MyRecyclerViewAdapter()
|
||||
}
|
||||
|
||||
class MyRecyclerViewHolder(
|
||||
private val binding: RecyclerviewExampleItemBinding
|
||||
) : RecyclerView.ViewHolder(binding.root) {
|
||||
fun bind(data: List<SeriesBundle<XYSeries, LineAndPointFormatter>>, title: String) {
|
||||
val plot = binding.plot
|
||||
plot.clear()
|
||||
plot.title.text = title
|
||||
data.map { plot.addSeries(it.series, it.formatter) }
|
||||
plot.redraw()
|
||||
}
|
||||
}
|
||||
|
||||
class MyRecyclerViewAdapter : RecyclerView.Adapter<MyRecyclerViewHolder>() {
|
||||
private val seriesData = generateData()
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyRecyclerViewHolder {
|
||||
val itemBinding = RecyclerviewExampleItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
return MyRecyclerViewHolder(itemBinding)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: MyRecyclerViewHolder, position: Int) {
|
||||
holder.bind(seriesData[position], "Series $position")
|
||||
}
|
||||
|
||||
override fun getItemCount() = seriesData.size
|
||||
|
||||
private fun generateData(): List<List<SeriesBundle<XYSeries, LineAndPointFormatter>>> {
|
||||
val theData = mutableListOf<List<SeriesBundle<XYSeries, LineAndPointFormatter>>>()
|
||||
fun generateBundle(seriesLabel: String): SeriesBundle<XYSeries, LineAndPointFormatter> {
|
||||
val generator = Random()
|
||||
val nums = ArrayList<Number>()
|
||||
for (j in 0 until NUM_POINTS_PER_SERIES) {
|
||||
nums.add(generator.nextFloat())
|
||||
}
|
||||
|
||||
val formatter = LineAndPointFormatter(
|
||||
Color.rgb(
|
||||
java.lang.Double.valueOf(Math.random() * 255).toInt(),
|
||||
java.lang.Double.valueOf(Math.random() * 255).toInt(),
|
||||
java.lang.Double.valueOf(Math.random() * 255).toInt()
|
||||
),
|
||||
Color.rgb(
|
||||
java.lang.Double.valueOf(Math.random() * 255).toInt(),
|
||||
java.lang.Double.valueOf(Math.random() * 255).toInt(),
|
||||
java.lang.Double.valueOf(Math.random() * 255).toInt()
|
||||
),
|
||||
null, null
|
||||
)
|
||||
|
||||
// for fun, configure interpolation on the formatter:
|
||||
formatter.interpolationParams = CatmullRomInterpolator.Params(
|
||||
20,
|
||||
CatmullRomInterpolator.Type.Centripetal
|
||||
)
|
||||
|
||||
return SeriesBundle(
|
||||
SimpleXYSeries(
|
||||
nums,
|
||||
SimpleXYSeries.ArrayFormat.Y_VALS_ONLY,
|
||||
seriesLabel
|
||||
),
|
||||
formatter
|
||||
)
|
||||
}
|
||||
|
||||
for (i in 0 until NUM_PLOTS) {
|
||||
val seriesList: MutableList<SeriesBundle<XYSeries, LineAndPointFormatter>> =
|
||||
ArrayList(NUM_SERIES_PER_PLOT)
|
||||
|
||||
for (k in 0 until NUM_SERIES_PER_PLOT) {
|
||||
seriesList.add(generateBundle("S$k"))
|
||||
}
|
||||
theData.add(seriesList)
|
||||
}
|
||||
return theData
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2015 AndroidPlot.com
|
||||
*
|
||||
* 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.androidplot.demos;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import com.androidplot.xy.*;
|
||||
|
||||
/**
|
||||
* A scatter plot
|
||||
*/
|
||||
public class ScatterPlotActivity extends Activity
|
||||
{
|
||||
|
||||
private XYPlot plot;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.scatter_plot_example);
|
||||
|
||||
// initialize our XYPlot reference:
|
||||
plot = (XYPlot) findViewById(R.id.plot);
|
||||
|
||||
XYSeries series1 = generateScatter("series1", 80, new RectRegion(10, 50, 10, 50));
|
||||
XYSeries series2 = generateScatter("series2", 80, new RectRegion(30, 70, 30, 70));
|
||||
|
||||
plot.setDomainBoundaries(0, 80, BoundaryMode.FIXED);
|
||||
plot.setRangeBoundaries(0, 80, BoundaryMode.FIXED);
|
||||
|
||||
// create formatters to use for drawing a series using LineAndPointRenderer
|
||||
// and configure them from xml:
|
||||
LineAndPointFormatter series1Format =
|
||||
new LineAndPointFormatter(this, R.xml.point_formatter);
|
||||
|
||||
LineAndPointFormatter series2Format =
|
||||
new LineAndPointFormatter(this, R.xml.point_formatter_2);
|
||||
|
||||
// add each series to the xyplot:
|
||||
plot.addSeries(series1, series1Format);
|
||||
plot.addSeries(series2, series2Format);
|
||||
|
||||
// reduce the number of range labels
|
||||
plot.setLinesPerRangeLabel(3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a XYSeries of random points within a specified region
|
||||
* @param title
|
||||
* @param numPoints
|
||||
* @param region
|
||||
* @return
|
||||
*/
|
||||
private XYSeries generateScatter(String title, int numPoints, RectRegion region) {
|
||||
SimpleXYSeries series = new SimpleXYSeries(title);
|
||||
for(int i = 0; i < numPoints; i++) {
|
||||
series.addLast(
|
||||
region.getMinX().doubleValue() + (Math.random() * region.getWidth().doubleValue()),
|
||||
region.getMinY().doubleValue() + (Math.random() * region.getHeight().doubleValue())
|
||||
);
|
||||
}
|
||||
return series;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* Copyright 2015 AndroidPlot.com
|
||||
*
|
||||
* 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.androidplot.demos;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.graphics.*;
|
||||
import android.os.Bundle;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.animation.AccelerateDecelerateInterpolator;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
import com.androidplot.pie.PieChart;
|
||||
import com.androidplot.pie.PieRenderer;
|
||||
import com.androidplot.pie.Segment;
|
||||
import com.androidplot.pie.SegmentFormatter;
|
||||
import com.androidplot.util.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* The simplest possible example of using AndroidPlot to plot some data.
|
||||
*/
|
||||
public class SimplePieChartActivity extends Activity
|
||||
{
|
||||
|
||||
public static final int SELECTED_SEGMENT_OFFSET = 50;
|
||||
|
||||
private TextView donutSizeTextView;
|
||||
private SeekBar donutSizeSeekBar;
|
||||
|
||||
public PieChart pie;
|
||||
|
||||
private Segment s1;
|
||||
private Segment s2;
|
||||
private Segment s3;
|
||||
private Segment s4;
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.pie_chart);
|
||||
|
||||
// initialize our XYPlot reference:
|
||||
pie = (PieChart) findViewById(R.id.mySimplePieChart);
|
||||
|
||||
// enable the legend:
|
||||
pie.getLegend().setVisible(true);
|
||||
|
||||
final float padding = PixelUtils.dpToPix(30);
|
||||
pie.getPie().setPadding(padding, padding, padding, padding);
|
||||
|
||||
// detect segment clicks:
|
||||
pie.setOnTouchListener(new View.OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(View view, MotionEvent motionEvent) {
|
||||
PointF click = new PointF(motionEvent.getX(), motionEvent.getY());
|
||||
if(pie.getPie().containsPoint(click)) {
|
||||
Segment segment = pie.getRenderer(PieRenderer.class).getContainingSegment(click);
|
||||
|
||||
if(segment != null) {
|
||||
final boolean isSelected = getFormatter(segment).getOffset() != 0;
|
||||
deselectAll();
|
||||
setSelected(segment, !isSelected);
|
||||
pie.redraw();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private SegmentFormatter getFormatter(Segment segment) {
|
||||
return pie.getFormatter(segment, PieRenderer.class);
|
||||
}
|
||||
|
||||
private void deselectAll() {
|
||||
List<Segment> segments = pie.getRegistry().getSeriesList();
|
||||
for(Segment segment : segments) {
|
||||
setSelected(segment, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void setSelected(Segment segment, boolean isSelected) {
|
||||
SegmentFormatter f = getFormatter(segment);
|
||||
if(isSelected) {
|
||||
f.setOffset(SELECTED_SEGMENT_OFFSET);
|
||||
} else {
|
||||
f.setOffset(0);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
donutSizeSeekBar = (SeekBar) findViewById(R.id.donutSizeSeekBar);
|
||||
donutSizeSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
pie.getRenderer(PieRenderer.class).setDonutSize(seekBar.getProgress()/100f,
|
||||
PieRenderer.DonutMode.PERCENT);
|
||||
pie.redraw();
|
||||
updateDonutText();
|
||||
}
|
||||
});
|
||||
|
||||
donutSizeTextView = (TextView) findViewById(R.id.donutSizeTextView);
|
||||
updateDonutText();
|
||||
|
||||
s1 = new Segment("s1", 3);
|
||||
s2 = new Segment("s2", 1);
|
||||
s3 = new Segment("s3", 7);
|
||||
s4 = new Segment("s4", 9);
|
||||
|
||||
EmbossMaskFilter emf = new EmbossMaskFilter(
|
||||
new float[]{1, 1, 1}, 0.4f, 10, 8.2f);
|
||||
|
||||
SegmentFormatter sf1 = new SegmentFormatter(this, R.xml.pie_segment_formatter1);
|
||||
sf1.getLabelPaint().setShadowLayer(3, 0, 0, Color.BLACK);
|
||||
sf1.getFillPaint().setMaskFilter(emf);
|
||||
|
||||
SegmentFormatter sf2 = new SegmentFormatter(this, R.xml.pie_segment_formatter2);
|
||||
sf2.getLabelPaint().setShadowLayer(3, 0, 0, Color.BLACK);
|
||||
sf2.getFillPaint().setMaskFilter(emf);
|
||||
|
||||
SegmentFormatter sf3 = new SegmentFormatter(this, R.xml.pie_segment_formatter3);
|
||||
sf3.getLabelPaint().setShadowLayer(3, 0, 0, Color.BLACK);
|
||||
sf3.getFillPaint().setMaskFilter(emf);
|
||||
|
||||
SegmentFormatter sf4 = new SegmentFormatter(this, R.xml.pie_segment_formatter4);
|
||||
sf4.getLabelPaint().setShadowLayer(3, 0, 0, Color.BLACK);
|
||||
sf4.getFillPaint().setMaskFilter(emf);
|
||||
|
||||
pie.addSegment(s1, sf1);
|
||||
pie.addSegment(s2, sf2);
|
||||
pie.addSegment(s3, sf3);
|
||||
pie.addSegment(s4, sf4);
|
||||
|
||||
pie.getBorderPaint().setColor(Color.TRANSPARENT);
|
||||
pie.getBackgroundPaint().setColor(Color.TRANSPARENT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
setupIntroAnimation();
|
||||
}
|
||||
|
||||
protected void updateDonutText() {
|
||||
donutSizeTextView.setText(donutSizeSeekBar.getProgress() + "%");
|
||||
}
|
||||
|
||||
protected void setupIntroAnimation() {
|
||||
|
||||
final PieRenderer renderer = pie.getRenderer(PieRenderer.class);
|
||||
// start with a zero degrees pie:
|
||||
|
||||
renderer.setExtentDegs(0);
|
||||
// animate a scale value from a starting val of 0 to a final value of 1:
|
||||
ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
|
||||
|
||||
// use an animation pattern that begins and ends slowly:
|
||||
animator.setInterpolator(new AccelerateDecelerateInterpolator());
|
||||
|
||||
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator valueAnimator) {
|
||||
float scale = valueAnimator.getAnimatedFraction();
|
||||
renderer.setExtentDegs(360 * scale);
|
||||
pie.redraw();
|
||||
}
|
||||
});
|
||||
|
||||
// the animation will run for 1.5 seconds:
|
||||
animator.setDuration(1500);
|
||||
animator.start();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright 2018 AndroidPlot.com
|
||||
*
|
||||
* 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.androidplot.demos;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.graphics.DashPathEffect;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.androidplot.util.PixelUtils;
|
||||
import com.androidplot.xy.CatmullRomInterpolator;
|
||||
import com.androidplot.xy.LineAndPointFormatter;
|
||||
import com.androidplot.xy.SimpleXYSeries;
|
||||
import com.androidplot.xy.XYGraphWidget;
|
||||
import com.androidplot.xy.XYPlot;
|
||||
import com.androidplot.xy.XYSeries;
|
||||
|
||||
import java.text.FieldPosition;
|
||||
import java.text.Format;
|
||||
import java.text.ParsePosition;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* A simple XYPlot
|
||||
*/
|
||||
public class SimpleXYPlotActivity extends Activity {
|
||||
|
||||
private XYPlot plot;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.simple_xy_plot_example);
|
||||
|
||||
// initialize our XYPlot reference:
|
||||
plot = findViewById(R.id.plot);
|
||||
|
||||
// create a couple arrays of y-values to plot:
|
||||
final Number[] domainLabels = {1, 2, 3, 6, 7, 8, 9, 10, 13, 14};
|
||||
Number[] series1Numbers = {1, 4, 2, 8, 4, 16, 8, 32, 16, 64};
|
||||
Number[] series2Numbers = {5, 2, 10, 5, 20, 10, 40, 20, 80, 40};
|
||||
|
||||
// turn the above arrays into XYSeries':
|
||||
// (Y_VALS_ONLY means use the element index as the x value)
|
||||
XYSeries series1 = new SimpleXYSeries(
|
||||
Arrays.asList(series1Numbers), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Series1");
|
||||
XYSeries series2 = new SimpleXYSeries(
|
||||
Arrays.asList(series2Numbers), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Series2");
|
||||
|
||||
// create formatters to use for drawing a series using LineAndPointRenderer
|
||||
// and configure them from xml:
|
||||
LineAndPointFormatter series1Format =
|
||||
new LineAndPointFormatter(this, R.xml.line_point_formatter_with_labels);
|
||||
|
||||
LineAndPointFormatter series2Format =
|
||||
new LineAndPointFormatter(this, R.xml.line_point_formatter_with_labels_2);
|
||||
|
||||
// add an "dash" effect to the series2 line:
|
||||
series2Format.getLinePaint().setPathEffect(new DashPathEffect(new float[] {
|
||||
|
||||
// always use DP when specifying pixel sizes, to keep things consistent across devices:
|
||||
PixelUtils.dpToPix(20),
|
||||
PixelUtils.dpToPix(15)}, 0));
|
||||
|
||||
// (optional) add some smoothing to the lines:
|
||||
// see: http://androidplot.com/smooth-curves-and-androidplot/
|
||||
series1Format.setInterpolationParams(
|
||||
new CatmullRomInterpolator.Params(10, CatmullRomInterpolator.Type.Centripetal));
|
||||
|
||||
series2Format.setInterpolationParams(
|
||||
new CatmullRomInterpolator.Params(10, CatmullRomInterpolator.Type.Centripetal));
|
||||
|
||||
// add a new series' to the xyplot:
|
||||
plot.addSeries(series1, series1Format);
|
||||
plot.addSeries(series2, series2Format);
|
||||
|
||||
plot.getGraph().getLineLabelStyle(XYGraphWidget.Edge.BOTTOM).setFormat(new Format() {
|
||||
@Override
|
||||
public StringBuffer format(Object obj, @NonNull StringBuffer toAppendTo, @NonNull FieldPosition pos) {
|
||||
int i = Math.round(((Number) obj).floatValue());
|
||||
return toAppendTo.append(domainLabels[i]);
|
||||
}
|
||||
@Override
|
||||
public Object parseObject(String source, @NonNull ParsePosition pos) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright 2015 AndroidPlot.com
|
||||
*
|
||||
* 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.androidplot.demos;
|
||||
|
||||
|
||||
import android.app.Activity;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.LinearGradient;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Shader;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.androidplot.util.PixelUtils;
|
||||
import com.androidplot.xy.SimpleXYSeries;
|
||||
import com.androidplot.xy.StepFormatter;
|
||||
import com.androidplot.xy.StepMode;
|
||||
import com.androidplot.xy.XYGraphWidget;
|
||||
import com.androidplot.xy.XYPlot;
|
||||
import com.androidplot.xy.XYSeries;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.FieldPosition;
|
||||
import java.text.Format;
|
||||
import java.text.ParsePosition;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class StepChartExampleActivity extends Activity
|
||||
{
|
||||
|
||||
private XYPlot mySimpleXYPlot;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.step_chart_example);
|
||||
|
||||
// initialize our XYPlot reference:
|
||||
mySimpleXYPlot = (XYPlot) findViewById(R.id.stepChartExamplePlot);
|
||||
|
||||
// y-vals to plot:
|
||||
Number[] series1Numbers = {1, 2, 3, 4, 2, 3, 4, 2, 2, 2, 3, 4, 2, 3, 2, 2};
|
||||
// create our series from our array of nums:
|
||||
XYSeries series2 = new SimpleXYSeries(
|
||||
Arrays.asList(series1Numbers),
|
||||
SimpleXYSeries.ArrayFormat.Y_VALS_ONLY,
|
||||
"Thread #1");
|
||||
|
||||
|
||||
final int screenHeightPx = getWindowManager().getDefaultDisplay().getHeight();
|
||||
// setup our line fill paint to be a slightly transparent gradient:
|
||||
Paint lineFill = new Paint();
|
||||
lineFill.setAlpha(200);
|
||||
lineFill.setShader(new LinearGradient(0, 0, 0, screenHeightPx, Color.WHITE, Color.BLUE, Shader.TileMode.MIRROR));
|
||||
|
||||
StepFormatter stepFormatter = new StepFormatter(Color.WHITE, Color.BLUE);
|
||||
stepFormatter.setVertexPaint(null); // don't draw individual points
|
||||
stepFormatter.getLinePaint().setStrokeWidth(PixelUtils.dpToPix(3));
|
||||
|
||||
stepFormatter.getLinePaint().setAntiAlias(false);
|
||||
stepFormatter.setFillPaint(lineFill);
|
||||
mySimpleXYPlot.addSeries(series2, stepFormatter);
|
||||
|
||||
// adjust the domain/range ticks to make more sense; label per line for range and label per 5 ticks domain:
|
||||
mySimpleXYPlot.setRangeStep(StepMode.INCREMENT_BY_VAL, 1);
|
||||
mySimpleXYPlot.setDomainStep(StepMode.INCREMENT_BY_VAL, 1);
|
||||
mySimpleXYPlot.setLinesPerRangeLabel(1);
|
||||
mySimpleXYPlot.setLinesPerDomainLabel(5);
|
||||
|
||||
// get rid of decimal points in our domain labels:
|
||||
mySimpleXYPlot.getGraph().getLineLabelStyle(XYGraphWidget.Edge.BOTTOM).
|
||||
setFormat(new DecimalFormat("0"));
|
||||
|
||||
// create a custom getFormatter to draw our state names as range tick labels:
|
||||
mySimpleXYPlot.getGraph().getLineLabelStyle(XYGraphWidget.Edge.LEFT).setFormat(new Format() {
|
||||
@Override
|
||||
public StringBuffer format(Object obj, @NonNull StringBuffer toAppendTo,
|
||||
@NonNull FieldPosition pos) {
|
||||
Number num = (Number) obj;
|
||||
switch (num.intValue()) {
|
||||
case 1:
|
||||
toAppendTo.append("Init");
|
||||
break;
|
||||
case 2:
|
||||
toAppendTo.append("Idle");
|
||||
break;
|
||||
case 3:
|
||||
toAppendTo.append("Recv");
|
||||
break;
|
||||
case 4:
|
||||
toAppendTo.append("Send");
|
||||
break;
|
||||
default:
|
||||
toAppendTo.append("Unknown");
|
||||
break;
|
||||
}
|
||||
return toAppendTo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object parseObject(String source, @NonNull ParsePosition pos) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright 2015 AndroidPlot.com
|
||||
*
|
||||
* 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.androidplot.demos;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.DashPathEffect;
|
||||
import android.graphics.Paint;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.androidplot.util.PixelUtils;
|
||||
import com.androidplot.xy.BoundaryMode;
|
||||
import com.androidplot.xy.LineAndPointFormatter;
|
||||
import com.androidplot.xy.SimpleXYSeries;
|
||||
import com.androidplot.xy.StepMode;
|
||||
import com.androidplot.xy.XYGraphWidget;
|
||||
import com.androidplot.xy.XYPlot;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.FieldPosition;
|
||||
import java.text.Format;
|
||||
import java.text.ParsePosition;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
public class TimeSeriesActivity extends Activity {
|
||||
|
||||
private static final String SERIES_TITLE = "Signthings in USA";
|
||||
|
||||
private XYPlot plot1;
|
||||
private SimpleXYSeries series;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.time_series_example);
|
||||
|
||||
plot1 = (XYPlot) findViewById(R.id.plot1);
|
||||
|
||||
// these will be our domain index labels:
|
||||
final Date[] years = {
|
||||
new GregorianCalendar(2001, Calendar.JANUARY, 1).getTime(),
|
||||
new GregorianCalendar(2001, Calendar.JULY, 1).getTime(),
|
||||
new GregorianCalendar(2002, Calendar.JANUARY, 1).getTime(),
|
||||
new GregorianCalendar(2002, Calendar.JULY, 1).getTime(),
|
||||
new GregorianCalendar(2003, Calendar.JANUARY, 1).getTime(),
|
||||
new GregorianCalendar(2003, Calendar.JULY, 1).getTime(),
|
||||
new GregorianCalendar(2004, Calendar.JANUARY, 1).getTime(),
|
||||
new GregorianCalendar(2004, Calendar.JULY, 1).getTime(),
|
||||
new GregorianCalendar(2005, Calendar.JANUARY, 1).getTime(),
|
||||
new GregorianCalendar(2005, Calendar.JULY, 1).getTime()
|
||||
};
|
||||
|
||||
addSeries(savedInstanceState);
|
||||
|
||||
plot1.setRangeBoundaries(0, 10, BoundaryMode.FIXED);
|
||||
|
||||
plot1.getGraph().getGridBackgroundPaint().setColor(Color.WHITE);
|
||||
plot1.getGraph().getDomainGridLinePaint().setColor(Color.BLACK);
|
||||
plot1.getGraph().getDomainGridLinePaint().
|
||||
setPathEffect(new DashPathEffect(new float[]{1, 1}, 1));
|
||||
plot1.getGraph().getRangeGridLinePaint().setColor(Color.BLACK);
|
||||
plot1.getGraph().getRangeGridLinePaint().
|
||||
setPathEffect(new DashPathEffect(new float[]{1, 1}, 1));
|
||||
plot1.getGraph().getDomainOriginLinePaint().setColor(Color.BLACK);
|
||||
plot1.getGraph().getRangeOriginLinePaint().setColor(Color.BLACK);
|
||||
|
||||
plot1.getGraph().setPaddingRight(2);
|
||||
|
||||
// draw a domain tick for each year:
|
||||
plot1.setDomainStep(StepMode.SUBDIVIDE, years.length);
|
||||
|
||||
// customize our domain/range labels
|
||||
plot1.setDomainLabel("Year");
|
||||
plot1.setRangeLabel("# of Sightings");
|
||||
|
||||
// get rid of decimal points in our range labels:
|
||||
plot1.getGraph().getLineLabelStyle(XYGraphWidget.Edge.LEFT).
|
||||
setFormat(new DecimalFormat("0.0"));
|
||||
|
||||
plot1.getGraph().getLineLabelStyle(XYGraphWidget.Edge.BOTTOM).
|
||||
setFormat(new Format() {
|
||||
|
||||
// create a simple date format that draws on the year portion of our timestamp.
|
||||
// see http://download.oracle.com/javase/1.4.2/docs/api/java/text/SimpleDateFormat.html
|
||||
// for a full description of SimpleDateFormat.
|
||||
@SuppressLint("SimpleDateFormat")
|
||||
private final SimpleDateFormat dateFormat = new SimpleDateFormat("MMM yyyy");
|
||||
|
||||
@Override
|
||||
public StringBuffer format(Object obj,
|
||||
@NonNull StringBuffer toAppendTo,
|
||||
@NonNull FieldPosition pos) {
|
||||
|
||||
// this rounding is necessary to avoid precision loss when converting from
|
||||
// double back to int:
|
||||
int yearIndex = (int) Math.round(((Number) obj).doubleValue());
|
||||
return dateFormat.format(years[yearIndex], toAppendTo, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object parseObject(String source, @NonNull ParsePosition pos) {
|
||||
return null;
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates our XYSeries, checking the current savedInstanceState for existing series data
|
||||
* to avoid having to regenerate on each resume. If your series data is small and easy to
|
||||
* regenerate (as it is here) then you can skip saving/restoring your series data to
|
||||
* savedInstanceState.
|
||||
* @param savedInstanceState Current saved instance state, if any; may be null.
|
||||
*/
|
||||
private void addSeries(Bundle savedInstanceState) {
|
||||
Number[] yVals;
|
||||
|
||||
if(savedInstanceState != null) {
|
||||
yVals = (Number[]) savedInstanceState.getSerializable(SERIES_TITLE);
|
||||
} else {
|
||||
yVals = new Number[]{5, 8, 6, 9, 3, 8, 5, 4, 7, 4};
|
||||
}
|
||||
|
||||
// create our series from our array of nums:
|
||||
series = new SimpleXYSeries(Arrays.asList(yVals),
|
||||
SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, SERIES_TITLE);
|
||||
|
||||
LineAndPointFormatter formatter =
|
||||
new LineAndPointFormatter(Color.rgb(0, 0, 0), Color.RED, Color.RED, null);
|
||||
formatter.getVertexPaint().setStrokeWidth(PixelUtils.dpToPix(10));
|
||||
formatter.getLinePaint().setStrokeWidth(PixelUtils.dpToPix(5));
|
||||
|
||||
// setup our line fill paint to be a slightly transparent gradient:
|
||||
Paint lineFill = new Paint();
|
||||
lineFill.setAlpha(200);
|
||||
|
||||
formatter.setFillPaint(lineFill);
|
||||
|
||||
plot1.addSeries(series, formatter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle bundle) {
|
||||
// persist our series data so we don't have to regenerate each time:
|
||||
bundle.putSerializable(SERIES_TITLE, series.getyVals().toArray(new Number[]{}));
|
||||
}
|
||||
}
|
||||
+186
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright 2015 AndroidPlot.com
|
||||
*
|
||||
* 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.androidplot.demos;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.Random;
|
||||
|
||||
import android.app.*;
|
||||
import android.graphics.Color;
|
||||
import android.os.*;
|
||||
import android.view.*;
|
||||
import android.widget.*;
|
||||
|
||||
import com.androidplot.Plot;
|
||||
import com.androidplot.xy.*;
|
||||
|
||||
public class TouchZoomExampleActivity extends Activity {
|
||||
private static final int SERIES_SIZE = 3000;
|
||||
private static final int SERIES_ALPHA = 255;
|
||||
private static final int NUM_GRIDLINES = 5;
|
||||
private XYPlot plot;
|
||||
private PanZoom panZoom;
|
||||
private Button resetButton;
|
||||
private Spinner panSpinner;
|
||||
private Spinner zoomSpinner;
|
||||
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.touch_zoom_example);
|
||||
resetButton = findViewById(R.id.resetButton);
|
||||
resetButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
reset();
|
||||
}
|
||||
});
|
||||
plot = findViewById(R.id.plot);
|
||||
|
||||
// set a fixed origin and a "by-value" step mode so that grid lines will
|
||||
// move dynamically with the data when the users pans or zooms:
|
||||
plot.setUserDomainOrigin(0);
|
||||
plot.setUserRangeOrigin(0);
|
||||
|
||||
// predefine the stepping of both axis
|
||||
// increment will be chosen from list to best fit NUM_GRIDLINES grid lines
|
||||
double[] inc_domain = new double[]{10,50,100,500};
|
||||
double[] inc_range = new double[]{1,5,10,20,50,100};
|
||||
plot.setDomainStepModel(new StepModelFit(plot.getBounds().getxRegion(),inc_domain,NUM_GRIDLINES));
|
||||
plot.setRangeStepModel( new StepModelFit(plot.getBounds().getyRegion(),inc_range,NUM_GRIDLINES));
|
||||
|
||||
|
||||
panSpinner = findViewById(R.id.pan_spinner);
|
||||
zoomSpinner = findViewById(R.id.zoom_spinner);
|
||||
plot.getGraph().setLinesPerRangeLabel(2);
|
||||
plot.getGraph().setLinesPerDomainLabel(2);
|
||||
plot.getGraph().getBackgroundPaint().setColor(Color.TRANSPARENT);
|
||||
plot.getGraph().getLineLabelStyle(XYGraphWidget.Edge.LEFT).
|
||||
setFormat(new DecimalFormat("#####"));
|
||||
plot.getGraph().getLineLabelStyle(XYGraphWidget.Edge.BOTTOM).
|
||||
setFormat(new DecimalFormat("#####.#"));
|
||||
|
||||
plot.setRangeLabel("");
|
||||
plot.setDomainLabel("");
|
||||
|
||||
plot.setBorderStyle(Plot.BorderStyle.NONE, null, null);
|
||||
|
||||
panZoom = PanZoom.attach(plot, PanZoom.Pan.BOTH, PanZoom.Zoom.STRETCH_BOTH, PanZoom.ZoomLimit.MIN_TICKS);
|
||||
plot.getOuterLimits().set(0, 3000, 0, 1000);
|
||||
initSpinners();
|
||||
|
||||
// enable autoselect of sampling level based on visible boundaries:
|
||||
plot.getRegistry().setEstimator(new ZoomEstimator());
|
||||
|
||||
generateSeriesData();
|
||||
reset();
|
||||
}
|
||||
|
||||
private void reset() {
|
||||
plot.setDomainBoundaries(0, 10000, BoundaryMode.FIXED);
|
||||
plot.setRangeBoundaries(0, 1000, BoundaryMode.FIXED);
|
||||
plot.redraw();
|
||||
}
|
||||
|
||||
private ProgressDialog progress;
|
||||
|
||||
private void generateSeriesData() {
|
||||
progress = ProgressDialog.show(this, "Loading", "Please wait...", true);
|
||||
new AsyncTask() {
|
||||
|
||||
@Override
|
||||
protected Object doInBackground(Object[] objects) {
|
||||
generateAndAddSeries(625, new LineAndPointFormatter(Color.rgb(50, 0, 0), null,
|
||||
Color.argb(SERIES_ALPHA, 100, 0, 0), null));
|
||||
generateAndAddSeries(125, new LineAndPointFormatter(Color.rgb(50, 50, 0), null,
|
||||
Color.argb(SERIES_ALPHA, 100, 100, 0), null));
|
||||
generateAndAddSeries(25, new LineAndPointFormatter(Color.rgb(0, 50, 0), null,
|
||||
Color.argb(SERIES_ALPHA, 0, 100, 0), null));
|
||||
generateAndAddSeries(5, new LineAndPointFormatter(Color.rgb(0, 0, 0), null,
|
||||
Color.argb(SERIES_ALPHA, 0, 0, 150), null));
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Object result) {
|
||||
progress.dismiss();
|
||||
plot.redraw();
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
|
||||
private void generateAndAddSeries(int max, LineAndPointFormatter formatter) {
|
||||
final FixedSizeEditableXYSeries series = new FixedSizeEditableXYSeries("s" + max, SERIES_SIZE);
|
||||
Random r = new Random();
|
||||
for(int i = 0; i < SERIES_SIZE; i++) {
|
||||
series.setX(i, i);
|
||||
series.setY(r.nextInt(max), i);
|
||||
}
|
||||
|
||||
// wrap our series in a SampledXYSeries with a threshold of 1000.
|
||||
final SampledXYSeries sampledSeries =
|
||||
new SampledXYSeries(series, OrderedXYSeries.XOrder.ASCENDING, 2,100);
|
||||
plot.addSeries(sampledSeries, formatter);
|
||||
}
|
||||
|
||||
private void initSpinners() {
|
||||
panSpinner.setAdapter(
|
||||
new ArrayAdapter<>(this, R.layout.spinner_item, PanZoom.Pan.values()));
|
||||
panSpinner.setSelection(panZoom.getPan().ordinal());
|
||||
panSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
panZoom.setPan(PanZoom.Pan.values()[position]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
// nothing to do
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
zoomSpinner.setAdapter(
|
||||
new ArrayAdapter<>(this, R.layout.spinner_item, PanZoom.Zoom.values()));
|
||||
zoomSpinner.setSelection(panZoom.getZoom().ordinal());
|
||||
zoomSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
panZoom.setZoom(PanZoom.Zoom.values()[position]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
// nothing to do
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// (optional) save the current pan/zoom state
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle bundle) {
|
||||
bundle.putSerializable("pan-zoom-state", panZoom.getState());
|
||||
}
|
||||
|
||||
// (optional) restore the previously saved pan/zoom state
|
||||
@Override
|
||||
public void onRestoreInstanceState(Bundle bundle) {
|
||||
PanZoom.State state = (PanZoom.State) bundle.getSerializable("pan-zoom-state");
|
||||
panZoom.setState(state);
|
||||
plot.redraw();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.androidplot.demos;
|
||||
|
||||
import android.app.*;
|
||||
import android.content.*;
|
||||
|
||||
/**
|
||||
* Created by halfhp on 10/29/16.
|
||||
*/
|
||||
public class Util {
|
||||
|
||||
|
||||
|
||||
public ProgressDialog showLoadingDialog(Context context) {
|
||||
return ProgressDialog.show(context, "Loading", "Please wait...", true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright 2015 AndroidPlot.com
|
||||
*
|
||||
* 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.androidplot.demos;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.graphics.*;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.ToggleButton;
|
||||
import com.androidplot.util.PixelUtils;
|
||||
import com.androidplot.xy.*;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class XYPlotWithBgImgActivity extends Activity {
|
||||
private static final String TAG = XYPlotWithBgImgActivity.class.getName();
|
||||
|
||||
private int SERIES_LEN = 50;
|
||||
private Shader WHITE_SHADER = new LinearGradient(1, 1, 1, 1, Color.WHITE, Color.WHITE, Shader.TileMode.REPEAT);
|
||||
|
||||
private XYPlot plot;
|
||||
private SimpleXYSeries series;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.xy_plot_with_bq_img_example);
|
||||
|
||||
plot = (XYPlot) findViewById(R.id.graph_metrics);
|
||||
|
||||
// Format Graph
|
||||
plot.getGraph().getBackgroundPaint().setColor(Color.TRANSPARENT);
|
||||
plot.getGraph().getGridBackgroundPaint().setShader(WHITE_SHADER);
|
||||
plot.getGraph().getDomainGridLinePaint().setColor(Color.BLACK);
|
||||
plot.getGraph().getDomainGridLinePaint().setPathEffect(new DashPathEffect(new float[]{3, 3}, 1));
|
||||
plot.getGraph().getRangeGridLinePaint().setColor(Color.BLACK);
|
||||
plot.getGraph().getRangeGridLinePaint().setPathEffect(new DashPathEffect(new float[]{3, 3}, 1));
|
||||
plot.getGraph().getDomainOriginLinePaint().setColor(Color.BLACK);
|
||||
plot.getGraph().getRangeOriginLinePaint().setColor(Color.BLACK);
|
||||
|
||||
// Customize domain and range labels.
|
||||
plot.setDomainLabel("x-vals");
|
||||
plot.setRangeLabel("y-vals");
|
||||
plot.getGraph().getLineLabelStyle(XYGraphWidget.Edge.LEFT).
|
||||
setFormat(new DecimalFormat("0"));
|
||||
|
||||
// Make the domain and range step correctly
|
||||
plot.setRangeBoundaries(40, 160, BoundaryMode.FIXED);
|
||||
plot.setRangeStep(StepMode.INCREMENT_BY_VAL, 20);
|
||||
plot.setDomainStep(StepMode.INCREMENT_BY_VAL, 60);
|
||||
plot.setLinesPerDomainLabel(2);
|
||||
|
||||
series = getSeries();
|
||||
LineAndPointFormatter lpFormat = new LineAndPointFormatter(
|
||||
Color.BLACK,
|
||||
Color.GRAY,
|
||||
null, // No fill
|
||||
new PointLabelFormatter(Color.TRANSPARENT) // Don't show text at points
|
||||
);
|
||||
lpFormat.getLinePaint().setStrokeWidth(PixelUtils.dpToPix(3));
|
||||
lpFormat.getVertexPaint().setStrokeWidth(PixelUtils.dpToPix(6));
|
||||
plot.addSeries(series, lpFormat);
|
||||
plot.redraw();
|
||||
}
|
||||
|
||||
private SimpleXYSeries getSeries() {
|
||||
Integer[] xVals = new Integer[SERIES_LEN];
|
||||
Integer[] yVals = new Integer[SERIES_LEN];
|
||||
|
||||
xVals[0] = 0;
|
||||
yVals[0] = 0;
|
||||
|
||||
for (int i = 1; i < SERIES_LEN; i += 1){
|
||||
xVals[i] = xVals[i-1] + (int)(Math.random() * i);
|
||||
yVals[i] = (int)(Math.random() * 140);
|
||||
}
|
||||
|
||||
return new SimpleXYSeries(
|
||||
Arrays.asList(xVals),
|
||||
Arrays.asList(yVals),
|
||||
"Sample Series");
|
||||
}
|
||||
|
||||
public void onGraphStyleToggle(View v) {
|
||||
boolean styleOn = ((ToggleButton) v).isChecked();
|
||||
RectF rect = plot.getGraph().getGridRect();
|
||||
BitmapShader myShader = new BitmapShader(
|
||||
Bitmap.createScaledBitmap(
|
||||
BitmapFactory.decodeResource(
|
||||
getResources(),
|
||||
R.drawable.graph_background),
|
||||
1,
|
||||
(int) rect.height(),
|
||||
false),
|
||||
Shader.TileMode.REPEAT,
|
||||
Shader.TileMode.REPEAT);
|
||||
Matrix m = new Matrix();
|
||||
m.setTranslate(rect.left, rect.top);
|
||||
myShader.setLocalMatrix(m);
|
||||
if (styleOn)
|
||||
plot.getGraph().getGridBackgroundPaint().setShader(
|
||||
myShader);
|
||||
else
|
||||
plot.getGraph().getGridBackgroundPaint().setShader(WHITE_SHADER);
|
||||
|
||||
plot.redraw();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,328 @@
|
||||
/*
|
||||
* Copyright 2015 AndroidPlot.com
|
||||
*
|
||||
* 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.androidplot.demos;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.DashPathEffect;
|
||||
import android.os.Bundle;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
|
||||
import com.androidplot.util.PixelUtils;
|
||||
import com.androidplot.xy.XYSeries;
|
||||
import com.androidplot.ui.*;
|
||||
import com.androidplot.xy.*;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.FieldPosition;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.ParsePosition;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Demonstration of the usage of Marker and RectRegion.
|
||||
*/
|
||||
public class XYRegionExampleActivity extends Activity {
|
||||
|
||||
private static final float HOME_RUN_DIST = 325;
|
||||
private static final int LINE_THICKNESS_DP = 4;
|
||||
private static final int POINT_SIZE_DP = 7;
|
||||
private XYPlot plot;
|
||||
private final Number[] timHits = {105, 252, 216, 10, 301, 320, 220, 350, 12, 250, 353};
|
||||
private final Number[] nickHits = {110, 191, 61, 300, 205, 40, 224, 371, 289, 101, 10};
|
||||
private LineAndPointFormatter timFormatter;
|
||||
private LineAndPointFormatter nickFormatter;
|
||||
|
||||
private XYSeries timSeries;
|
||||
private XYSeries nickSeries;
|
||||
|
||||
private RectRegion shortRegion;
|
||||
private RectRegion warmupRegion;
|
||||
private RectRegion homeRunRegion;
|
||||
|
||||
private XYRegionFormatter shortRegionFormatter;
|
||||
private XYRegionFormatter warmupRegionFormatter;
|
||||
private XYRegionFormatter homeRunRegionFormatter;
|
||||
|
||||
private CheckBox timCB;
|
||||
private CheckBox nickCB;
|
||||
|
||||
private CheckBox r2CheckBox;
|
||||
private CheckBox r3CheckBox;
|
||||
private CheckBox r4CheckBox;
|
||||
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.xyregion_example);
|
||||
plot = findViewById(R.id.xyRegionExamplePlot);
|
||||
timCB = findViewById(R.id.s1CheckBox);
|
||||
timCB.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
|
||||
onS1CheckBoxClicked();
|
||||
}
|
||||
});
|
||||
|
||||
nickCB = findViewById(R.id.s2CheckBox);
|
||||
nickCB.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
|
||||
onS2CheckBoxClicked();
|
||||
}
|
||||
});
|
||||
|
||||
r2CheckBox = findViewById(R.id.r2CheckBox);
|
||||
r2CheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
|
||||
onCheckBoxClicked(r2CheckBox, timFormatter, shortRegionFormatter, shortRegion);
|
||||
}
|
||||
});
|
||||
|
||||
r3CheckBox = findViewById(R.id.r3CheckBox);
|
||||
r3CheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
|
||||
onCheckBoxClicked(r3CheckBox, nickFormatter, warmupRegionFormatter, warmupRegion);
|
||||
}
|
||||
});
|
||||
|
||||
r4CheckBox = findViewById(R.id.r4CheckBox);
|
||||
r4CheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
|
||||
onCheckBoxClicked(r4CheckBox, nickFormatter, homeRunRegionFormatter, homeRunRegion);
|
||||
}
|
||||
});
|
||||
|
||||
seriesSetup();
|
||||
markerSetup();
|
||||
axisLabelSetup();
|
||||
regionSetup();
|
||||
makePlotPretty();
|
||||
}
|
||||
|
||||
private void onS1CheckBoxClicked() {
|
||||
if (timCB.isChecked()) {
|
||||
plot.addSeries(timSeries, timFormatter);
|
||||
r2CheckBox.setEnabled(true);
|
||||
} else {
|
||||
plot.removeSeries(timSeries);
|
||||
r2CheckBox.setEnabled(false);
|
||||
}
|
||||
plot.redraw();
|
||||
}
|
||||
|
||||
private void onS2CheckBoxClicked() {
|
||||
if (nickCB.isChecked()) {
|
||||
plot.addSeries(nickSeries, nickFormatter);
|
||||
r3CheckBox.setEnabled(true);
|
||||
r4CheckBox.setEnabled(true);
|
||||
} else {
|
||||
plot.removeSeries(nickSeries);
|
||||
r3CheckBox.setEnabled(false);
|
||||
r4CheckBox.setEnabled(false);
|
||||
}
|
||||
plot.redraw();
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a run box event
|
||||
* @param cb The checkbox event origin
|
||||
* @param lpf LineAndPointFormatter with which rr and rf are to be added/removed
|
||||
* @param rf The XYRegionFormatter with which rr should be rendered
|
||||
* @param rr The RectRegion to add/remove
|
||||
*/
|
||||
private void onCheckBoxClicked(CheckBox cb, LineAndPointFormatter lpf,
|
||||
XYRegionFormatter rf, RectRegion rr) {
|
||||
if (cb.isChecked()) {
|
||||
lpf.removeRegion(rr);
|
||||
} else {
|
||||
lpf.addRegion(rr, rf);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up the plot's general layout and color scheme
|
||||
*/
|
||||
private void makePlotPretty() {
|
||||
// use a 2x5 grid with room for 10 items:
|
||||
plot.getLegend().setTableModel(new DynamicTableModel(4, 2));
|
||||
plot.getGraph().getLineLabelStyle(XYGraphWidget.Edge.LEFT)
|
||||
.setFormat(new NumberFormat() {
|
||||
@Override
|
||||
public StringBuffer format(double value, StringBuffer buffer,
|
||||
FieldPosition field) {
|
||||
return new StringBuffer(value + "'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringBuffer format(long value, StringBuffer buffer,
|
||||
FieldPosition field) {
|
||||
throw new UnsupportedOperationException("Not yet implemented.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Number parse(String string, ParsePosition position) {
|
||||
throw new UnsupportedOperationException("Not yet implemented.");
|
||||
}
|
||||
});
|
||||
|
||||
plot.getGraph().getLineLabelStyle(XYGraphWidget.Edge.BOTTOM)
|
||||
.setFormat(new DecimalFormat("#"));
|
||||
|
||||
plot.getGraph().setDomainGridLinePaint(null);
|
||||
|
||||
plot.getLegend().setWidth(PixelUtils.dpToPix(100), SizeMode.FILL);
|
||||
|
||||
// reposition the grid so that it rests above the bottom-left
|
||||
// edge of the graph widget:
|
||||
plot.getLegend().position(
|
||||
50,
|
||||
HorizontalPositioning.ABSOLUTE_FROM_CENTER,
|
||||
200,
|
||||
VerticalPositioning.ABSOLUTE_FROM_TOP,
|
||||
Anchor.TOP_MIDDLE);
|
||||
|
||||
plot.setRangeBoundaries(0, BoundaryMode.FIXED, 500, BoundaryMode.FIXED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create 4 XYSeries from the values defined above add add them to the plot.
|
||||
* Also add some arbitrary regions.
|
||||
*/
|
||||
private void seriesSetup() {
|
||||
|
||||
// TIM
|
||||
timFormatter = new LineAndPointFormatter(Color.YELLOW, Color.YELLOW, null, null);
|
||||
timFormatter.getLinePaint().setStrokeWidth(PixelUtils.dpToPix(LINE_THICKNESS_DP));
|
||||
timFormatter.getVertexPaint().setStrokeWidth(PixelUtils.dpToPix(POINT_SIZE_DP));
|
||||
timFormatter.setInterpolationParams(new CatmullRomInterpolator.Params(8,
|
||||
CatmullRomInterpolator.Type.Centripetal));
|
||||
|
||||
timSeries = new SimpleXYSeries(Arrays.asList(timHits),
|
||||
SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Tim");
|
||||
|
||||
plot.addSeries(timSeries, timFormatter);
|
||||
|
||||
// SERIES #2:
|
||||
nickFormatter = new LineAndPointFormatter(Color.BLUE, Color.BLUE, null, null);
|
||||
nickFormatter.getLinePaint().setStrokeWidth(PixelUtils.dpToPix(LINE_THICKNESS_DP));
|
||||
nickFormatter.getVertexPaint().setStrokeWidth(PixelUtils.dpToPix(POINT_SIZE_DP));
|
||||
nickFormatter.setInterpolationParams(new CatmullRomInterpolator.Params(8,
|
||||
CatmullRomInterpolator.Type.Centripetal));
|
||||
|
||||
nickSeries = new SimpleXYSeries(Arrays.asList(nickHits),
|
||||
SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Nick");
|
||||
|
||||
plot.addSeries(nickSeries, nickFormatter);
|
||||
|
||||
plot.setRangeStep(StepMode.INCREMENT_BY_VAL, 100);
|
||||
plot.setDomainStep(StepMode.INCREMENT_BY_VAL, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add some color coded regions to our axis labels.
|
||||
*/
|
||||
private void axisLabelSetup() {
|
||||
// DOMAIN
|
||||
// TODO
|
||||
// plot.getGraphWidget().addDomainLineLabelFormatter(
|
||||
// Double.NEGATIVE_INFINITY, 2, new SimpleLineLabelFormatter(Color.GRAY));
|
||||
// plot.getGraphWidget().addDomainLineLabelFormatter(
|
||||
// 2, Double.POSITIVE_INFINITY, new SimpleLineLabelFormatter(Color.WHITE));
|
||||
// // RANGE
|
||||
// plot.getGraphWidget().addRangeLineLabelFormatter(
|
||||
// Double.NEGATIVE_INFINITY, HOME_RUN_DIST, new SimpleLineLabelFormatter(Color.RED));
|
||||
// plot.getGraphWidget().addRangeLineLabelFormatter(
|
||||
// HOME_RUN_DIST, Double.POSITIVE_INFINITY, new SimpleLineLabelFormatter(Color.GREEN));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add some markers to our plot.
|
||||
*/
|
||||
private void markerSetup() {
|
||||
|
||||
YValueMarker fenwayLfMarker = new YValueMarker(
|
||||
380, // y-val to mark
|
||||
"Fenway Park LF Wall", // marker label
|
||||
new HorizontalPosition(
|
||||
// object instance to set text positioning on the marker
|
||||
PixelUtils.dpToPix(5), // 5dp offset
|
||||
HorizontalPositioning.ABSOLUTE_FROM_RIGHT), // offset origin
|
||||
Color.BLUE, // line paint color
|
||||
Color.BLUE); // text paint color
|
||||
|
||||
YValueMarker attRfMarker = new YValueMarker(
|
||||
309, // y-val to mark
|
||||
"ATT Park RF Wall", // marker label
|
||||
new HorizontalPosition(
|
||||
// object instance to set text positioning on the marker
|
||||
PixelUtils.dpToPix(5), // 5dp offset
|
||||
HorizontalPositioning.ABSOLUTE_FROM_RIGHT), // offset origin
|
||||
Color.CYAN, // line paint color
|
||||
Color.CYAN); // text paint color
|
||||
|
||||
fenwayLfMarker.getTextPaint().setTextSize(PixelUtils.dpToPix(14));
|
||||
attRfMarker.getTextPaint().setTextSize(PixelUtils.dpToPix(14));
|
||||
|
||||
DashPathEffect dpe = new DashPathEffect(
|
||||
new float[] {PixelUtils.dpToPix(2), PixelUtils.dpToPix(2)}, 0);
|
||||
|
||||
fenwayLfMarker.getLinePaint().setPathEffect(dpe);
|
||||
attRfMarker.getLinePaint().setPathEffect(dpe);
|
||||
|
||||
plot.addMarker(fenwayLfMarker);
|
||||
plot.addMarker(attRfMarker);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add some fill regions to our series data
|
||||
*/
|
||||
private void regionSetup() {
|
||||
|
||||
// and another region:
|
||||
shortRegionFormatter = new XYRegionFormatter(Color.RED);
|
||||
shortRegionFormatter.getPaint().setAlpha(60);
|
||||
shortRegion = new RectRegion(
|
||||
2, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, HOME_RUN_DIST, "Short");
|
||||
|
||||
timFormatter.addRegion(shortRegion, shortRegionFormatter);
|
||||
nickFormatter.addRegion(shortRegion, shortRegionFormatter);
|
||||
|
||||
// the next three regions are horizontal regions with minY/maxY
|
||||
// set to negative and positive infinity respectively.
|
||||
warmupRegionFormatter = new XYRegionFormatter(Color.LTGRAY);
|
||||
warmupRegionFormatter.getPaint().setAlpha(60);
|
||||
|
||||
warmupRegion = new RectRegion(
|
||||
0, 2, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, "Warmup");
|
||||
|
||||
timFormatter.addRegion(warmupRegion, warmupRegionFormatter);
|
||||
nickFormatter.addRegion(warmupRegion, warmupRegionFormatter);
|
||||
|
||||
homeRunRegionFormatter = new XYRegionFormatter(Color.GREEN);
|
||||
homeRunRegionFormatter.getPaint().setAlpha(60);
|
||||
|
||||
homeRunRegion = new RectRegion(
|
||||
2, Double.POSITIVE_INFINITY, HOME_RUN_DIST, Double.POSITIVE_INFINITY, "H. Run");
|
||||
timFormatter.addRegion(homeRunRegion, homeRunRegionFormatter);
|
||||
nickFormatter.addRegion(homeRunRegion, homeRunRegionFormatter);
|
||||
nickFormatter.setFillDirection(FillDirection.RANGE_ORIGIN);
|
||||
}
|
||||
}
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 2015 AndroidPlot.com
|
||||
*
|
||||
* 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.androidplot.demos.widget;
|
||||
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.appwidget.AppWidgetProvider;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.widget.RemoteViews;
|
||||
import com.androidplot.demos.R;
|
||||
import com.androidplot.ui.*;
|
||||
import com.androidplot.util.PixelUtils;
|
||||
import com.androidplot.xy.XYGraphWidget;
|
||||
import com.androidplot.xy.XYSeries;
|
||||
import com.androidplot.xy.LineAndPointFormatter;
|
||||
import com.androidplot.xy.SimpleXYSeries;
|
||||
import com.androidplot.xy.XYPlot;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class DemoAppWidgetProvider extends AppWidgetProvider {
|
||||
|
||||
@Override
|
||||
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
|
||||
for (int widgetId : appWidgetIds) {
|
||||
XYPlot plot = new XYPlot(context, "Widget Example");
|
||||
final int h = (int) context.getResources().getDimension(R.dimen.sample_widget_height);
|
||||
final int w = (int) context.getResources().getDimension(R.dimen.sample_widget_width);
|
||||
|
||||
plot.getGraph().setMargins(0, 0, 0 , 0);
|
||||
plot.getGraph().setPadding(0, 0, 0, 0);
|
||||
|
||||
plot.getGraph().position(0, HorizontalPositioning.ABSOLUTE_FROM_LEFT, 0,
|
||||
VerticalPositioning.ABSOLUTE_FROM_TOP, Anchor.LEFT_TOP);
|
||||
|
||||
plot.getGraph().setSize(Size.FILL);
|
||||
|
||||
plot.getLayoutManager().moveToTop(plot.getTitle());
|
||||
|
||||
plot.getGraph().setLineLabelEdges(XYGraphWidget.Edge.LEFT, XYGraphWidget.Edge.BOTTOM);
|
||||
plot.getGraph().getLineLabelInsets().setLeft(PixelUtils.dpToPix(16));
|
||||
plot.getGraph().getLineLabelInsets().setBottom(PixelUtils.dpToPix(4));
|
||||
plot.getGraph().getLineLabelStyle(XYGraphWidget.Edge.LEFT).getPaint().setColor(Color.RED);
|
||||
plot.getGraph().getGridInsets().setTop(PixelUtils.dpToPix(12));
|
||||
plot.getGraph().getGridInsets().setRight(PixelUtils.dpToPix(12));
|
||||
plot.getGraph().getGridInsets().setLeft(PixelUtils.dpToPix(36));
|
||||
plot.getGraph().getGridInsets().setBottom(PixelUtils.dpToPix(16));
|
||||
|
||||
plot.measure(w, h);
|
||||
plot.layout(0, 0, w, h);
|
||||
|
||||
Number[] series1Numbers = {1, 4, 2, 8, 4, 16, 8, 32, 16, 64};
|
||||
Number[] series2Numbers = {5, 2, 10, 5, 20, 10, 40, 20, 80, 40};
|
||||
|
||||
// Turn the above arrays into XYSeries':
|
||||
XYSeries series1 = new SimpleXYSeries(
|
||||
Arrays.asList(series1Numbers), // SimpleXYSeries takes a List so turn our array into a List
|
||||
SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, // Y_VALS_ONLY means use the element index as the x value
|
||||
"Series1"); // Set the display title of the series
|
||||
|
||||
// same as above
|
||||
XYSeries series2 = new SimpleXYSeries(Arrays.asList(series2Numbers),
|
||||
SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Series2");
|
||||
|
||||
// Create a formatter to use for drawing a series using LineAndPointRenderer:
|
||||
LineAndPointFormatter series1Format = new LineAndPointFormatter(
|
||||
Color.rgb(0, 200, 0), // line color
|
||||
Color.rgb(0, 100, 0), // point color
|
||||
null, null); // fill color (none)
|
||||
|
||||
// add a new series' to the xyplot:
|
||||
plot.addSeries(series1, series1Format);
|
||||
|
||||
// same as above:
|
||||
plot.addSeries(series2,
|
||||
new LineAndPointFormatter(
|
||||
Color.rgb(0, 0, 200), Color.rgb(0, 0, 100), null, null));
|
||||
|
||||
|
||||
// reduce the number of range labels
|
||||
plot.setLinesPerRangeLabel(3);
|
||||
plot.setLinesPerDomainLabel(2);
|
||||
|
||||
// hide the legend:
|
||||
plot.getLegend().setVisible(false);
|
||||
|
||||
RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.demo_app_widget);
|
||||
|
||||
Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
|
||||
plot.draw(new Canvas(bitmap));
|
||||
rv.setImageViewBitmap(R.id.imgView, bitmap);
|
||||
appWidgetManager.updateAppWidget(widgetId, rv);
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.3 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 7.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 9.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 133 B |
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
@@ -0,0 +1,108 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright 2015 AndroidPlot.com
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:ap="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.androidplot.xy.XYPlot
|
||||
android:id="@+id/plot"
|
||||
style="@style/APDefacto.Light"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_weight="1"
|
||||
ap:gridClippingEnabled="false"
|
||||
ap:gridInsetLeft="35dp"
|
||||
ap:gridInsetRight="10dp"
|
||||
ap:title="Growth" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/spRenderStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/spSeriesSize"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/spWidthStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/sectionGraph"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<SeekBar
|
||||
android:id="@+id/sbFixed"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:max="300"
|
||||
android:paddingLeft="10dp"
|
||||
android:paddingRight="10dp"
|
||||
android:progress="10" />
|
||||
|
||||
<SeekBar
|
||||
android:id="@+id/sbVariable"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:max="50"
|
||||
android:paddingLeft="10dp"
|
||||
android:paddingRight="10dp"
|
||||
android:progress="1" />
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/s1CheckBox"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="true"
|
||||
android:text="Series 1" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/s2CheckBox"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="true"
|
||||
android:text="Series 2" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 AndroidPlot.com
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:ap="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="match_parent">
|
||||
|
||||
<com.androidplot.xy.XYPlot
|
||||
style="@style/APDefacto.Dark"
|
||||
android:id="@+id/plot"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
ap:title="A Bubble Chart"
|
||||
ap:rangeTitle="range"
|
||||
ap:domainTitle="domain"
|
||||
ap:lineLabels="left|bottom"
|
||||
ap:lineLabelRotationBottom="-45"/>
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2016 AndroidPlot.com
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:ap="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:background="@color/ap_black">
|
||||
|
||||
<com.androidplot.xy.XYPlot
|
||||
style="@style/APDefacto.Light"
|
||||
android:id="@+id/plot"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
ap:previewMode="candlestick"
|
||||
ap:title="Daily Price"
|
||||
ap:domainTitle="Day"
|
||||
ap:rangeTitle="Price"
|
||||
ap:gridClippingEnabled="false"
|
||||
ap:legendVisible="false"
|
||||
ap:lineLabelTextSizeLeft="12sp"
|
||||
ap:lineLabelTextSizeBottom="15sp"
|
||||
ap:lineLabelInsetLeft="32dp"
|
||||
ap:gridInsetLeft="35dp"/>
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
~ Copyright 2015 AndroidPlot.com
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/imgView"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:scaleType="centerInside"></ImageView>
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 AndroidPlot.com
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:ap="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="match_parent">
|
||||
|
||||
<com.androidplot.xy.XYPlot
|
||||
style="@style/APDefacto.Dark"
|
||||
android:id="@+id/plot"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
ap:title="Min Wage vs Cost by Year"
|
||||
ap:lineLabels="left|bottom|right"
|
||||
ap:gridInsetLeft="50dp"
|
||||
ap:lineLabelInsetLeft="45dp"
|
||||
ap:gridInsetRight="40dp"
|
||||
ap:lineLabelInsetRight="35dp"
|
||||
ap:lineLabelRotationBottom="-45"/>
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright 2015 AndroidPlot.com
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:ap="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.androidplot.xy.XYPlot
|
||||
android:id="@+id/dynamicXYPlot"
|
||||
style="@style/APDefacto.Dark"
|
||||
androidplot.renderMode="use_background_thread"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
ap:domainTitle="Domain"
|
||||
ap:legendAnchor="right_bottom"
|
||||
ap:legendHeight="25dp"
|
||||
ap:legendIconHeight="15dp"
|
||||
ap:legendIconWidth="15dp"
|
||||
ap:legendTextSize="15sp"
|
||||
ap:rangeTitle="Range"
|
||||
ap:title="A Dynamic XY Plot" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2016 AndroidPlot.com
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:ap="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="match_parent">
|
||||
|
||||
<com.androidplot.xy.XYPlot
|
||||
style="@style/APDefacto.Dark"
|
||||
android:id="@+id/plot"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
ap:renderMode="use_background_thread"
|
||||
ap:title="ECG Example"
|
||||
ap:rangeTitle="range"
|
||||
ap:domainTitle="domain"/>
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2016 AndroidPlot.com
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:ap="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="match_parent">
|
||||
|
||||
<com.androidplot.xy.XYPlot
|
||||
style="@style/APDefacto.Dark"
|
||||
android:id="@+id/plot"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
ap:title="A Simple XY Plot"
|
||||
ap:rangeTitle="range"
|
||||
ap:domainTitle="domain"
|
||||
ap:lineLabels="left|bottom|top|right"
|
||||
ap:gridInsetRight="30dp"
|
||||
ap:gridInsetTop="30dp"
|
||||
ap:gridInsetBottom="20dp"
|
||||
ap:lineLabelInsetRight="25dp"
|
||||
ap:lineLabelInsetTop="25dp"
|
||||
ap:lineLabelRotationBottom="-45"
|
||||
ap:lineLabelRotationTop="0"
|
||||
ap:lineLabelAlignTop="center"
|
||||
ap:domainOriginLineThickness="4dp"
|
||||
ap:rangeOriginLineThickness="4dp"/>
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 AndroidPlot.com
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<LinearLayout android:id="@+id/LinearLayout01"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:background="#000000"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<ListView android:id="@+id/listView1"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"/>
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
~ Copyright 2015 AndroidPlot.com
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:ap="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
|
||||
<com.androidplot.xy.XYPlot
|
||||
style="@style/APDefacto.Light"
|
||||
android:id="@+id/xyplot"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="250dp"
|
||||
ap:title="an xy plot"/>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,166 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 AndroidPlot.com
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1">
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<Button
|
||||
android:id="@+id/startSimplePieExButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Pie Chart"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/startSimpleXYExButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="A Simple XY Plot"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/animatedXYPlotExButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Animated XY Plot"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/startScatterExButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="XY Scatter Plot"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/startDynamicXYExButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="A Dynamic XY Plot"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/startCandlestickExButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Candlestick Chart"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/startOrSensorExButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Realtime Orientation Sensor Plot"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/startDualScaleExButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Dual Scale XY"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/startTimeSeriesExButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/ts_title"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/startStepChartExButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Step Chart"
|
||||
/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/startScrollZoomButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Scroll and Zoom"
|
||||
/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/startBarPlotExButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Bar Plot"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/startXyRegionExampleButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="XYRegion Example"
|
||||
android:enabled="true"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/startXyListViewExButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="ListView of XYPlots"
|
||||
android:enabled="true"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/startXyRecyclerViewExButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="RecyclerView of XYPlots"
|
||||
android:enabled="true"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/startXYPlotWithBgImgExample"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="XY Background Example"
|
||||
android:enabled="true"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/startECGExample"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="ECG Example"
|
||||
android:enabled="true"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/fxPlotExample"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="f(x) Example"
|
||||
android:enabled="true"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/bubbleChartExample"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Bubble Chart Example"
|
||||
android:enabled="true"/>
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:autoLink="web"
|
||||
android:gravity="center"
|
||||
android:text="http://androidplot.com"/>
|
||||
</LinearLayout>
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 AndroidPlot.com
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:ap="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.androidplot.xy.XYPlot
|
||||
style="@style/APDefacto.Dark"
|
||||
android:id="@+id/aprLevelsPlot"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_margin="0dp"
|
||||
android:layout_weight="3"
|
||||
android:layout_marginTop="10px"
|
||||
android:layout_marginLeft="10px"
|
||||
android:layout_marginRight="10px"
|
||||
ap:renderMode="use_background_thread"
|
||||
ap:title="Levels"/>
|
||||
|
||||
<com.androidplot.xy.XYPlot
|
||||
style="@style/APDefacto.Dark"
|
||||
android:id="@+id/aprHistoryPlot"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_margin="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginTop="10px"
|
||||
android:layout_marginLeft="10px"
|
||||
android:layout_marginRight="10px"
|
||||
androidPlot.backgroundPaint.color="#000000"
|
||||
androidPlot.borderPaint.color="#000000"
|
||||
androidplot.renderMode="use_background_thread"
|
||||
ap:title="History"
|
||||
ap:domainTitle="Domain"
|
||||
ap:rangeTitle="Range"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/hwAccelerationCb"
|
||||
android:visibility="gone"
|
||||
android:text="HW Acceleration"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/showFpsCb"
|
||||
android:text="Show FPS"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 AndroidPlot.com
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.androidplot.pie.PieChart
|
||||
android:id="@+id/mySimplePieChart"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_weight="1"
|
||||
androidPlot.title.text="A Simple Pie Chart"
|
||||
androidPlot.title.labelPaint.textSize="@dimen/title_font_size"/>
|
||||
<LinearLayout
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_gravity="center"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_gravity="center"
|
||||
android:text="Donut Size"
|
||||
android:id="@+id/donutSizeSeekLabel"/>
|
||||
<SeekBar
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:paddingLeft="10dp"
|
||||
android:paddingRight="10dp"
|
||||
android:max="90"
|
||||
android:progress="50"
|
||||
android:id="@+id/donutSizeSeekBar"/>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_gravity="center"
|
||||
android:text="unknown"
|
||||
android:id="@+id/donutSizeTextView"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 AndroidPlot.com
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<LinearLayout android:id="@+id/LinearLayout01"
|
||||
android:layout_width="fill_parent"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_height="fill_parent"
|
||||
android:background="@color/ap_white"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_view"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
~ Copyright 2015 AndroidPlot.com
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<com.androidplot.xy.XYPlot xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:ap="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/plot"
|
||||
style="@style/APDefacto.Light"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="250dp"
|
||||
ap:title="an xy plot" />
|
||||
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 AndroidPlot.com
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:ap="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="match_parent">
|
||||
|
||||
<com.androidplot.xy.XYPlot
|
||||
style="@style/APDefacto.Dark"
|
||||
android:id="@+id/plot"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
ap:title="A Scatter Plot"
|
||||
ap:rangeTitle="range"
|
||||
ap:domainTitle="domain"/>
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 AndroidPlot.com
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:ap="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.androidplot.xy.XYPlot
|
||||
style="@style/APDefacto.Dark"
|
||||
android:id="@+id/plot"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
ap:title="A Simple XY Plot"
|
||||
ap:rangeTitle="range"
|
||||
ap:domainTitle="domain"
|
||||
ap:lineLabels="left|bottom"
|
||||
ap:lineLabelRotationBottom="-45"
|
||||
android:layout_weight="1"/>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="15dp">
|
||||
|
||||
</TextView>
|
||||
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright 2015 AndroidPlot.com
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:ap="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.androidplot.xy.XYPlot
|
||||
android:id="@+id/stepChartExamplePlot"
|
||||
style="@style/APDefacto.Dark"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
ap:domainTitle="time (secs)"
|
||||
ap:rangeTitle="server state"
|
||||
ap:title="HTTP Server State (15 Sec)" />
|
||||
</LinearLayout>
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
~ Copyright 2015 AndroidPlot.com
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:ap="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.androidplot.xy.XYPlot
|
||||
android:id="@+id/plot1"
|
||||
style="@style/APDefacto.Light"
|
||||
renderMode="use_main_thread"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
ap:backgroundColor="@color/ap_white"
|
||||
ap:graphBackgroundColor="@color/ap_white"
|
||||
ap:gridInsetBottom="40dp"
|
||||
ap:gridInsetLeft="35dp"
|
||||
ap:lineLabelInsetBottom="25dp"
|
||||
ap:lineLabelInsetLeft="25dp"
|
||||
ap:lineLabelRotationBottom="-45"
|
||||
ap:paddingBottom="10dp"
|
||||
ap:paddingLeft="10dp"
|
||||
ap:paddingRight="10dp"
|
||||
ap:paddingTop="10dp"
|
||||
ap:title="@string/ts_plot1_title" />
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,92 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright 2015 AndroidPlot.com
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:ap="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/ap_black"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.androidplot.xy.XYPlot
|
||||
android:id="@+id/plot"
|
||||
style="@style/APDefacto.Dark"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_weight="1"
|
||||
ap:drawGridOnTop="true"
|
||||
ap:renderMode="use_background_thread"
|
||||
ap:title="A Simple XY Plot" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="3dp"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="5"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="15dp"
|
||||
android:text="Pan"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/pan_spinner"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="0dp">
|
||||
|
||||
</Spinner>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="3"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="15dp"
|
||||
android:text="Zoom"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/zoom_spinner"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="0dp">
|
||||
|
||||
</Spinner>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/resetButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
android:text="Reset" />
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,47 @@
|
||||
<!--
|
||||
~ Copyright 2015 AndroidPlot.com
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:ap="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||
android:paddingTop="@dimen/activity_vertical_margin">
|
||||
|
||||
<com.androidplot.xy.XYPlot
|
||||
style="@style/APDefacto.Light"
|
||||
android:id="@+id/graph_metrics"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_centerVertical="true"
|
||||
ap:gridClippingEnabled="true"/>
|
||||
|
||||
<ToggleButton
|
||||
android:id="@+id/style_toggle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignTop="@id/graph_metrics"
|
||||
android:layout_alignRight="@id/graph_metrics"
|
||||
android:layout_marginTop="15dp"
|
||||
android:layout_marginRight="15dp"
|
||||
android:textOn="bg on"
|
||||
android:textOff="bg off"
|
||||
android:onClick="onGraphStyleToggle" />
|
||||
|
||||
</RelativeLayout>
|
||||
@@ -0,0 +1,105 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 AndroidPlot.com
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:ap="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
>
|
||||
|
||||
<com.androidplot.xy.XYPlot
|
||||
style="@style/APDefacto.Dark"
|
||||
android:id="@+id/xyRegionExamplePlot"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
ap:graphMarginTop="10dp"
|
||||
ap:graphMarginLeft="25dp"
|
||||
ap:graphMarginRight="0dp"
|
||||
ap:graphMarginBottom="20dp"
|
||||
ap:title="Batting Practice Stats"
|
||||
ap:domainTitle="Pitch #"
|
||||
ap:rangeTitle="Distance"
|
||||
android:layout_weight="1"
|
||||
/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/s1CheckBox"
|
||||
android:text="Tim"
|
||||
android:checked="true"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="fill_parent"/>
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/s2CheckBox"
|
||||
android:text="Nick"
|
||||
android:checked="true"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="fill_parent"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/r1CheckBox"
|
||||
android:text="R1"
|
||||
android:checked="true"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="fill_parent"/>
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/r2CheckBox"
|
||||
android:text="R2"
|
||||
android:checked="true"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="fill_parent"/>
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/r3CheckBox"
|
||||
android:text="R3"
|
||||
android:checked="true"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="fill_parent"/>
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/r4CheckBox"
|
||||
android:text="R4"
|
||||
android:checked="true"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="fill_parent"/>
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/r5CheckBox"
|
||||
android:text="R5"
|
||||
android:checked="true"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="fill_parent"/>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
<resources>
|
||||
<dimen name="title_font_size">30dp</dimen>
|
||||
<dimen name="pie_segment_label_font_size">20dp</dimen>
|
||||
</resources>
|
||||
@@ -0,0 +1,17 @@
|
||||
<resources>
|
||||
|
||||
<!-- Default screen margins, per the Android Design guidelines. -->
|
||||
<dimen name="activity_horizontal_margin">16dp</dimen>
|
||||
<dimen name="activity_vertical_margin">16dp</dimen>
|
||||
|
||||
<dimen name="pie_segment_label_font_size">10sp</dimen>
|
||||
<dimen name="title_font_size">20sp</dimen>
|
||||
<dimen name="domain_label_font_size">13sp</dimen>
|
||||
<dimen name="range_label_font_size">13sp</dimen>
|
||||
<dimen name="range_tick_label_font_size">15sp</dimen>
|
||||
<dimen name="domain_tick_label_font_size">15sp</dimen>
|
||||
<dimen name="legend_text_font_size">20sp</dimen>
|
||||
|
||||
<dimen name="sample_widget_height">72dp</dimen>
|
||||
<dimen name="sample_widget_width">294dp</dimen>
|
||||
</resources>
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 AndroidPlot.com
|
||||
~
|
||||
~ 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>
|
||||
<string name="app_name">Androidplot Demos</string>
|
||||
<string name="sxy_title">A Simple XY Plot</string>
|
||||
<string name="ts_title">Time Series</string>
|
||||
<string name="ts_plot1_title">UFO Sightings</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 AndroidPlot.com
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<config
|
||||
strokePaint.color="#FFCC66"
|
||||
fillPaint.color="#FF0000"/>
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 AndroidPlot.com
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<config
|
||||
strokePaint.color="#2255AA"
|
||||
fillPaint.color="#AABBFF"/>
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 AndroidPlot.com
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<config
|
||||
strokePaint.color="#A18459"
|
||||
fillPaint.color="#604219"/>
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 AndroidPlot.com
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<config
|
||||
wickPaint.color="#000000"
|
||||
upperCapPaint.color="#000000"
|
||||
lowerCapPaint.color="#000000"
|
||||
risingBodyStrokePaint.color="#000000"
|
||||
fallingBodyStrokePaint.color="#000000"/>
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
~ Copyright 2015 AndroidPlot.com
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:minWidth="@dimen/sample_widget_width"
|
||||
android:minHeight="@dimen/sample_widget_height"
|
||||
android:updatePeriodMillis="86400000"
|
||||
android:initialLayout="@layout/demo_app_widget"
|
||||
android:resizeMode="horizontal|vertical">
|
||||
</appwidget-provider>
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2016 AndroidPlot.com
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<config
|
||||
linePaint.strokeWidth="5dp"
|
||||
linePaint.color="#00AA00"
|
||||
vertexPaint.color="#00000000"
|
||||
fillPaint.color="#00000000"/>
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 AndroidPlot.com
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<config
|
||||
linePaint.strokeWidth="5dp"
|
||||
linePaint.color="#00AA00"
|
||||
vertexPaint.color="#007700"
|
||||
vertexPaint.strokeWidth="20dp"
|
||||
fillPaint.color="#00000000"
|
||||
pointLabelFormatter.textPaint.color="#CCCCCC"/>
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 AndroidPlot.com
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<config
|
||||
linePaint.strokeWidth="5dp"
|
||||
linePaint.color="#0000AA"
|
||||
vertexPaint.strokeWidth="20dp"
|
||||
vertexPaint.color="#000099"
|
||||
fillPaint.color="#00000000"
|
||||
pointLabelFormatter.textPaint.color="#CCCCCC"/>
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 AndroidPlot.com
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<config
|
||||
fillPaint.color="#FF0000"
|
||||
labelPaint.textSize="@dimen/pie_segment_label_font_size"/>
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 AndroidPlot.com
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<config
|
||||
fillPaint.color="#00FF00"
|
||||
labelPaint.textSize="@dimen/pie_segment_label_font_size"/>
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 AndroidPlot.com
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<config
|
||||
fillPaint.color="#0000FF"
|
||||
labelPaint.textSize="@dimen/pie_segment_label_font_size"/>
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 AndroidPlot.com
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<config
|
||||
fillPaint.color="#FF00FF"
|
||||
labelPaint.textSize="@dimen/pie_segment_label_font_size"/>
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 AndroidPlot.com
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<config
|
||||
linePaint.color="#00000000"
|
||||
vertexPaint.color="#6666FF"
|
||||
vertexPaint.strokeWidth="10dp"
|
||||
fillPaint.color="#00000000"/>
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2015 AndroidPlot.com
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<config
|
||||
linePaint.color="#00000000"
|
||||
vertexPaint.strokeWidth="10dp"
|
||||
vertexPaint.color="#FFCC66"
|
||||
fillPaint.color="#00000000"/>
|
||||
Reference in New Issue
Block a user