的
This commit is contained in:
@@ -0,0 +1 @@
|
||||
/build
|
||||
@@ -0,0 +1,40 @@
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
apply plugin: 'kotlin-kapt'
|
||||
|
||||
android {
|
||||
compileSdkVersion 28
|
||||
defaultConfig {
|
||||
applicationId "com.android.stockapp"
|
||||
minSdkVersion 15
|
||||
targetSdkVersion 28
|
||||
versionCode 1
|
||||
versionName "3.2.0"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
implementation 'androidx.appcompat:appcompat:1.0.2'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
||||
testImplementation 'junit:junit:4.12'
|
||||
androidTestImplementation 'androidx.test:runner:1.1.1'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
|
||||
implementation 'com.jakewharton:butterknife:10.0.0'
|
||||
kapt 'com.jakewharton:butterknife-compiler:10.0.0'
|
||||
implementation project(':MPChartLib')
|
||||
implementation 'com.google.android.material:material:1.0.0'
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package com.android.stockapp
|
||||
|
||||
import android.support.test.InstrumentationRegistry
|
||||
import android.support.test.runner.AndroidJUnit4
|
||||
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ExampleInstrumentedTest {
|
||||
@Test
|
||||
fun useAppContext() {
|
||||
// Context of the app under test.
|
||||
val appContext = InstrumentationRegistry.getTargetContext()
|
||||
assertEquals("com.android.stockapp", appContext.packageName)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.android.stockapp">
|
||||
|
||||
<application
|
||||
android:name=".application.MyApplication"
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity android:name=".ui.main.MainActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".ui.market.activity.StockDetailActivity" />
|
||||
<activity android:name=".ui.market.activity.StockDetailLandActivity"
|
||||
android:screenOrientation="landscape"
|
||||
android:theme="@style/FullscreenTheme"></activity>
|
||||
|
||||
<activity android:name=".ui.mpchartexample.notimportant.MPMainActivity"
|
||||
android:theme="@style/MPAppTheme"/>
|
||||
<activity android:name=".ui.mpchartexample.LineChartActivity1"
|
||||
android:theme="@style/MPAppTheme"/>
|
||||
<activity android:name=".ui.mpchartexample.LineChartActivity2"
|
||||
android:theme="@style/MPAppTheme"/>
|
||||
<activity android:name=".ui.mpchartexample.LineChartTime"
|
||||
android:theme="@style/MPAppTheme"/>
|
||||
<activity android:name=".ui.mpchartexample.BarChartActivity"
|
||||
android:theme="@style/MPAppTheme"/>
|
||||
<activity android:name=".ui.mpchartexample.HorizontalBarChartActivity"
|
||||
android:theme="@style/MPAppTheme"/>
|
||||
<activity android:name=".ui.mpchartexample.PieChartActivity"
|
||||
android:theme="@style/MPAppTheme"/>
|
||||
<activity android:name=".ui.mpchartexample.PiePolylineChartActivity"
|
||||
android:theme="@style/MPAppTheme"/>
|
||||
<activity android:name=".ui.mpchartexample.MultiLineChartActivity"
|
||||
android:theme="@style/MPAppTheme"/>
|
||||
<activity android:name=".ui.mpchartexample.BarChartActivityMultiDataset"
|
||||
android:theme="@style/MPAppTheme"/>
|
||||
<activity android:name=".ui.mpchartexample.DrawChartActivity"
|
||||
android:theme="@style/MPAppTheme"/>
|
||||
<activity android:name=".ui.mpchartexample.ScatterChartActivity"
|
||||
android:theme="@style/MPAppTheme"/>
|
||||
<activity android:name=".ui.mpchartexample.BubbleChartActivity"
|
||||
android:theme="@style/MPAppTheme"/>
|
||||
<activity android:name=".ui.mpchartexample.fragments.SimpleChartDemo"
|
||||
android:theme="@style/MPAppTheme"/>
|
||||
<activity android:name=".ui.mpchartexample.ListViewBarChartActivity"
|
||||
android:theme="@style/MPAppTheme"/>
|
||||
<activity android:name=".ui.mpchartexample.ListViewMultiChartActivity"
|
||||
android:theme="@style/MPAppTheme"/>
|
||||
<activity android:name=".ui.mpchartexample.StackedBarActivity"
|
||||
android:theme="@style/MPAppTheme"/>
|
||||
<activity android:name=".ui.mpchartexample.AnotherBarActivity"
|
||||
android:theme="@style/MPAppTheme"/>
|
||||
<activity android:name=".ui.mpchartexample.InvertedLineChartActivity"
|
||||
android:theme="@style/MPAppTheme"/>
|
||||
<activity android:name=".ui.mpchartexample.CandleStickChartActivity"
|
||||
android:theme="@style/MPAppTheme"/>
|
||||
<activity android:name=".ui.mpchartexample.CubicLineChartActivity"
|
||||
android:theme="@style/MPAppTheme"/>
|
||||
<activity android:name=".ui.mpchartexample.RadarChartActivity"
|
||||
android:theme="@style/MPAppTheme"/>
|
||||
<activity android:name=".ui.mpchartexample.LineChartActivityColored"
|
||||
android:theme="@style/MPAppTheme"/>
|
||||
<activity android:name=".ui.mpchartexample.DynamicalAddingActivity"
|
||||
android:theme="@style/MPAppTheme"/>
|
||||
<activity android:name=".ui.mpchartexample.RealtimeLineChartActivity"
|
||||
android:theme="@style/MPAppTheme"/>
|
||||
<activity android:name=".ui.mpchartexample.CombinedChartActivity"
|
||||
android:theme="@style/MPAppTheme"/>
|
||||
<activity android:name=".ui.mpchartexample.PerformanceLineChart"
|
||||
android:theme="@style/MPAppTheme"/>
|
||||
<activity android:name=".ui.mpchartexample.BarChartActivitySinus"
|
||||
android:theme="@style/MPAppTheme"/>
|
||||
<activity android:name=".ui.mpchartexample.ScrollViewActivity"
|
||||
android:theme="@style/MPAppTheme"/>
|
||||
<activity android:name=".ui.mpchartexample.StackedBarActivityNegative"
|
||||
android:theme="@style/MPAppTheme"/>
|
||||
<activity android:name=".ui.mpchartexample.BarChartPositiveNegative"
|
||||
android:theme="@style/MPAppTheme"/>
|
||||
<activity android:name=".ui.mpchartexample.FilledLineActivity"
|
||||
android:theme="@style/MPAppTheme"/>
|
||||
<activity android:name=".ui.mpchartexample.HalfPieChartActivity"
|
||||
android:theme="@style/MPAppTheme"/>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,750 @@
|
||||
1.0#0
|
||||
0.9998000066755178#1
|
||||
0.9992001066967312#2
|
||||
0.9982005400156222#3
|
||||
0.996801706445518#4
|
||||
0.9950041651292624#5
|
||||
0.992808635283034#6
|
||||
0.990215996129463#7
|
||||
0.9872272839453933#8
|
||||
0.9838436941753507#9
|
||||
0.9800665802095645#10
|
||||
0.9758974528426302#11
|
||||
0.9713379796692108#12
|
||||
0.9663899805862244#13
|
||||
0.9610554379813293#14
|
||||
0.9553364856027305#15
|
||||
0.9492354109575819#16
|
||||
0.9427546543970131#17
|
||||
0.9358968081400203#18
|
||||
0.9286646152366127#19
|
||||
0.9210609684706269#20
|
||||
0.913088909202652#21
|
||||
0.904751626153523#22
|
||||
0.8960524541288755#23
|
||||
0.8869948726852646#24
|
||||
0.8775825047383886#25
|
||||
0.8678191299221538#26
|
||||
0.8577086396867667#27
|
||||
0.8472550780858032#28
|
||||
0.8364626263965502#29
|
||||
0.8253356014475525#30
|
||||
0.8138784538919424#31
|
||||
0.8020957664272419#32
|
||||
0.7899922519623475#33
|
||||
0.7775727517324336#34
|
||||
0.7648422333625261#35
|
||||
0.7518057888805234#36
|
||||
0.7384686326804557#37
|
||||
0.724836099436802#38
|
||||
0.7109136419706951#39
|
||||
0.6967068290688696#40
|
||||
0.6822213432562266#41
|
||||
0.667462978522903#42
|
||||
0.6524376380067577#43
|
||||
0.6371513316321991#44
|
||||
0.6216101737063007#45
|
||||
0.605820380473164#46
|
||||
0.5897882676275087#47
|
||||
0.5735202477884837#48
|
||||
0.5570228279347097#49
|
||||
0.54030260680158#50
|
||||
0.5233662722418589#51
|
||||
0.506220598550635#52
|
||||
0.48887244375569844#53
|
||||
0.47132874687442705#54
|
||||
0.45359652513827653#55
|
||||
0.4356828711859872#56
|
||||
0.4175949502266283#57
|
||||
0.3993399971736154#58
|
||||
0.3809253137508472#59
|
||||
0.36235826557211853#60
|
||||
0.34364627919497903#61
|
||||
0.3247968391502145#62
|
||||
0.3058174849481404#63
|
||||
0.2867158080629036#64
|
||||
0.2674994488960003#65
|
||||
0.2481760937202225#66
|
||||
0.22875347160525775#67
|
||||
0.2092393513261698#68
|
||||
0.18964153825599847#69
|
||||
0.16996787124372015#70
|
||||
0.1502262194788189#71
|
||||
0.1304244793437215#72
|
||||
0.11057057125535577#73
|
||||
0.09067243649709553#74
|
||||
0.07073803404235907#75
|
||||
0.050775337371132094#76
|
||||
0.03079233128068804#77
|
||||
0.01079700869178177#78
|
||||
-0.009202632548406111#79
|
||||
-0.02919859286529534#80
|
||||
-0.04918287415662309#81
|
||||
-0.06914748299157214#82
|
||||
-0.08908443380803052#83
|
||||
-0.10898575210670376#84
|
||||
-0.12884347764080226#85
|
||||
-0.1486496676000277#86
|
||||
-0.16839639978758542#87
|
||||
-0.18807577578895107#88
|
||||
-0.20767992413112554#89
|
||||
-0.22720100343111285#90
|
||||
-0.24663120553236303#91
|
||||
-0.2659627586279245#92
|
||||
-0.28518793036905754#93
|
||||
-0.3042990309580645#94
|
||||
-0.32328841622410065#95
|
||||
-0.3421484906807349#96
|
||||
-0.3608717105640369#97
|
||||
-0.37945058684997673#98
|
||||
-0.39787768824992864#99
|
||||
-0.4161456441830819#100
|
||||
-0.43424725510755136#101
|
||||
-0.4521750648543838#102
|
||||
-0.469922010949154#103
|
||||
-0.4874809948635857#104
|
||||
-0.5048449932516255#105
|
||||
-0.5220070607586818#106
|
||||
-0.5389603327996688#107
|
||||
-0.5556980283047446#108
|
||||
-0.5722134524316421#109
|
||||
-0.5884999992435129#110
|
||||
-0.6045511543512081#111
|
||||
-0.6203604975189423#112
|
||||
-0.6359217052322976#113
|
||||
-0.6512285532275404#114
|
||||
-0.6662749189812381#115
|
||||
-0.6810547841591839#116
|
||||
-0.6955622370236441#117
|
||||
-0.7097914747979706#118
|
||||
-0.7237368059876295#119
|
||||
-0.737392652656719#120
|
||||
-0.7507535526590651#121
|
||||
-0.7638141618230024#122
|
||||
-0.7765692560889685#123
|
||||
-0.7890137335990532#124
|
||||
-0.8011426167376704#125
|
||||
-0.8129510541225339#126
|
||||
-0.824434322545142#127
|
||||
-0.8355878288599945#128
|
||||
-0.8464071118217855#129
|
||||
-0.8568878438698396#130
|
||||
-0.8670258328590743#131
|
||||
-0.8768170237367994#132
|
||||
-0.886257500164681#133
|
||||
-0.8953434860852212#134
|
||||
-0.9040713472321283#135
|
||||
-0.912437592583972#136
|
||||
-0.9204388757605422#137
|
||||
-0.9280719963613548#138
|
||||
-0.9353339012457665#139
|
||||
-0.9422216857541875#140
|
||||
-0.948732594869905#141
|
||||
-0.9548640243210507#142
|
||||
-0.960613521622273#143
|
||||
-0.9659787870556967#144
|
||||
-0.9709576745907774#145
|
||||
-0.9755481927426838#146
|
||||
-0.979748505368863#147
|
||||
-0.9835569324034725#148
|
||||
-0.9869719505293822#149
|
||||
-0.98999219378748#150
|
||||
-0.9926164541230362#151
|
||||
-0.9948436818689081#152
|
||||
-0.9966729861653926#153
|
||||
-0.998103635316557#154
|
||||
-0.9991350570829072#155
|
||||
-0.9997668389102758#156
|
||||
-0.9999987280948375#157
|
||||
-0.9998306318841871#158
|
||||
-0.9992626175144392#159
|
||||
-0.9982949121833353#160
|
||||
-0.996927902959367#161
|
||||
-0.9951621366269541#162
|
||||
-0.9929983194677395#163
|
||||
-0.9904373169780857#164
|
||||
-0.9874801535228883#165
|
||||
-0.9841280119258453#166
|
||||
-0.9803822329963435#167
|
||||
-0.9762443149931541#168
|
||||
-0.97171591302515#169
|
||||
-0.9667988383892859#170
|
||||
-0.9614950578461049#171
|
||||
-0.9558066928330617#172
|
||||
-0.9497360186159785#173
|
||||
-0.9432854633789693#174
|
||||
-0.9364576072532017#175
|
||||
-0.9292551812848803#176
|
||||
-0.9216810663428666#177
|
||||
-0.9137382919663726#178
|
||||
-0.9054300351531868#179
|
||||
-0.8967596190889212#180
|
||||
-0.887730511817783#181
|
||||
-0.8783463248554058#182
|
||||
-0.8686108117442946#183
|
||||
-0.8585278665524617#184
|
||||
-0.8481015223158543#185
|
||||
-0.8373359494251967#186
|
||||
-0.8262354539578933#187
|
||||
-0.8148044759556579#188
|
||||
-0.8030475876485598#189
|
||||
-0.7909694916261961#190
|
||||
-0.7785750189567227#191
|
||||
-0.765869127254494#192
|
||||
-0.7528568986970883#193
|
||||
-0.7395435379925076#194
|
||||
-0.725934370297368#195
|
||||
-0.712034839086912#196
|
||||
-0.6978505039776957#197
|
||||
-0.6833870385038194#198
|
||||
-0.6686502278475953#199
|
||||
-0.653645966525555#200
|
||||
-0.6383800725148856#201
|
||||
-0.6228590159091549#202
|
||||
-0.6070888244769085#203
|
||||
-0.5910758060724219#204
|
||||
-0.5748263656773369#205
|
||||
-0.5583470028387585#206
|
||||
-0.5416443090695284#207
|
||||
-0.5247249652117124#208
|
||||
-0.5075957387643578#209
|
||||
-0.49026348117658924#210
|
||||
-0.47273512510712556#211
|
||||
-0.455017681651314#212
|
||||
-0.4371182375367911#213
|
||||
-0.4190439522888913#214
|
||||
-0.4008020553669378#215
|
||||
-0.3823998432725609#216
|
||||
-0.3638446766311999#217
|
||||
-0.34514397724795687#218
|
||||
-0.3263052251389793#219
|
||||
-0.3073359555395589#220
|
||||
-0.2882437558901438#221
|
||||
-0.26903626280146914#222
|
||||
-0.2497211590000209#223
|
||||
-0.230306170255053#224
|
||||
-0.210799062288389#225
|
||||
-0.19120763766824242#226
|
||||
-0.17153973268829978#227
|
||||
-0.1518032142333134#228
|
||||
-0.13200597663245844#229
|
||||
-0.11215593850171253#230
|
||||
-0.09226103957652096#231
|
||||
-0.07232923753601443#232
|
||||
-0.052368504820049594#233
|
||||
-0.032386825440345476#234
|
||||
-0.012392191786991334#235
|
||||
0.00760739856839673#236
|
||||
0.027603946071591657#237
|
||||
0.04758945238546438#238
|
||||
0.06755592358920592#239
|
||||
0.08749537337578304#240
|
||||
0.10739982624634846#241
|
||||
0.127261320700328#242
|
||||
0.14707191241990855#243
|
||||
0.16682367744765325#244
|
||||
0.18650871535597274#245
|
||||
0.2061191524071849#246
|
||||
0.22564714470289873#247
|
||||
0.24508488132146347#248
|
||||
0.26442458744222685#249
|
||||
0.28365852745535386#250
|
||||
0.30277900805596175#251
|
||||
0.32177838132133346#252
|
||||
0.3406490477699788#253
|
||||
0.35938345940131994#254
|
||||
0.3779741227147856#255
|
||||
0.39641360170710516#256
|
||||
0.4146945208466053#257
|
||||
0.43280956802331894#258
|
||||
0.4507514974737259#259
|
||||
0.4685131326789562#260
|
||||
0.48608736923529655#261
|
||||
0.5034671776958516#262
|
||||
0.5206456063822237#263
|
||||
0.5376157841650862#264
|
||||
0.5543709232125382#265
|
||||
0.5709043217051422#266
|
||||
0.5872093665165563#267
|
||||
0.6032795358586928#268
|
||||
0.6191084018903404#269
|
||||
0.6346896332882112#270
|
||||
0.6500169977793795#271
|
||||
0.6650843646341041#272
|
||||
0.6798857071180334#273
|
||||
0.6944151049028142#274
|
||||
0.7086667464341395#275
|
||||
0.7226349312562887#276
|
||||
0.7363140722922291#277
|
||||
0.749698698078368#278
|
||||
0.7627834549530611#279
|
||||
0.775563109198002#280
|
||||
0.7880325491316352#281
|
||||
0.8001867871537571#282
|
||||
0.8120209617404855#283
|
||||
0.8235303393888008#284
|
||||
0.8347103165098803#285
|
||||
0.8455564212704689#286
|
||||
0.8560643153815497#287
|
||||
0.866229795833598#288
|
||||
0.8760487965777259#289
|
||||
0.885517390152045#290
|
||||
0.8946317892525951#291
|
||||
0.9033883482482131#292
|
||||
0.9117835646387336#293
|
||||
0.9198140804559395#294
|
||||
0.9274766836067025#295
|
||||
0.934768309157775#296
|
||||
0.9416860405617193#297
|
||||
0.9482271108234865#298
|
||||
0.9543889036071753#299
|
||||
0.9601689542825289#300
|
||||
0.9655649509107532#301
|
||||
0.970574735169259#302
|
||||
0.9751963032149611#303
|
||||
0.9794278064857869#304
|
||||
0.9832675524400757#305
|
||||
0.9867140052335709#306
|
||||
0.9897657863337365#307
|
||||
0.9924216750711504#308
|
||||
0.9946806091277554#309
|
||||
0.9965416849617705#310
|
||||
0.9980041581690963#311
|
||||
0.9990674437810647#312
|
||||
0.9997311164984192#313
|
||||
0.9999949108614278#314
|
||||
0.9998587213560639#315
|
||||
0.9993226024562099#316
|
||||
0.9983867686018685#317
|
||||
0.9970515941133901#318
|
||||
0.9953176130417491#319
|
||||
0.9931855189549322#320
|
||||
0.9906561646605199#321
|
||||
0.987730561864576#322
|
||||
0.9844098807669794#323
|
||||
0.980695449593361#324
|
||||
0.9765887540638312#325
|
||||
0.9720914367987137#326
|
||||
0.9672052966615201#327
|
||||
0.9619322880394301#328
|
||||
0.956274520061564#329
|
||||
0.9502342557553608#330
|
||||
0.9438139111413991#331
|
||||
0.9370160542670232#332
|
||||
0.9298434041791597#333
|
||||
0.9222988298367378#334
|
||||
0.914385348963146#335
|
||||
0.9061061268391848#336
|
||||
0.8974644750369997#337
|
||||
0.8884638500954981#338
|
||||
0.8791078521377839#339
|
||||
0.8694002234311572#340
|
||||
0.8593448468902616#341
|
||||
0.8489457445239725#342
|
||||
0.8382070758266503#343
|
||||
0.8271331361144011#344
|
||||
0.8157283548070109#345
|
||||
0.8039972936562406#346
|
||||
0.7919446449211889#347
|
||||
0.779575229491455#348
|
||||
0.7668939949588511#349
|
||||
0.7539060136384351#350
|
||||
0.7406164805396558#351
|
||||
0.727030711288423#352
|
||||
0.7131541400009316#353
|
||||
0.6989923171100918#354
|
||||
0.6845509071454342#355
|
||||
0.6698356864673781#356
|
||||
0.6548525409567681#357
|
||||
0.6396074636606056#358
|
||||
0.6241065523949136#359
|
||||
0.6083560073056969#360
|
||||
0.5923621283889708#361
|
||||
0.5761313129708517#362
|
||||
0.5596700531487165#363
|
||||
0.5429849331944554#364
|
||||
0.5260826269208558#365
|
||||
0.5089698950121717#366
|
||||
0.4916535823199446#367
|
||||
0.4741406151251599#368
|
||||
0.4564379983678321#369
|
||||
0.43855281284512715#370
|
||||
0.42049221237914375#371
|
||||
0.4022634209554854#372
|
||||
0.3838737298337676#373
|
||||
0.36533049463121725#374
|
||||
0.346641132380529#375
|
||||
0.32781311856315715#376
|
||||
0.3088539841192281#377
|
||||
0.28977131243527066#378
|
||||
0.2705727363109682#379
|
||||
0.25126593490614646#380
|
||||
0.23185863066921794#381
|
||||
0.21235858624831114#382
|
||||
0.1927736013863209#383
|
||||
0.1731115098011213#384
|
||||
0.15338017605218865#385
|
||||
0.13358749239488882#386
|
||||
0.11374137562368615#387
|
||||
0.09384976390553743#388
|
||||
0.07392061360473688#389
|
||||
0.05396189610048263#390
|
||||
0.03398159459843745#391
|
||||
0.013987700937558934#392
|
||||
-0.0060117876065233595#393
|
||||
-0.026008871520305465#394
|
||||
-0.04599555225210164#395
|
||||
-0.0659638354113523#396
|
||||
-0.08590573396626752#397
|
||||
-0.10581327143852721#398
|
||||
-0.12567848509376003#399
|
||||
-0.14549342912652474#400
|
||||
-0.16525064811995077#401
|
||||
-0.18494176603177878#402
|
||||
-0.20455890631685353#403
|
||||
-0.22409422202143867#404
|
||||
-0.2435398989220372#405
|
||||
-0.26288815865111975#406
|
||||
-0.2821312618085105#407
|
||||
-0.3012615110571854#408
|
||||
-0.32027125420224567#409
|
||||
-0.3391528872518335#410
|
||||
-0.3578988574587669#411
|
||||
-0.37650166634167603#412
|
||||
-0.39495387268443305#413
|
||||
-0.4132480955126757#414
|
||||
-0.4313770170462337#415
|
||||
-0.44933338562627717#416
|
||||
-0.46711001861601636#417
|
||||
-0.48469980527379214#418
|
||||
-0.5020957095974079#419
|
||||
-0.5192907731385656#420
|
||||
-0.5362781177862795#421
|
||||
-0.5530509485181553#422
|
||||
-0.5696025561184319#423
|
||||
-0.5859263198617023#424
|
||||
-0.602015710161236#425
|
||||
-0.6178642911808461#426
|
||||
-0.6334657234092563#427
|
||||
-0.6488137661959366#428
|
||||
-0.6639022802473945#429
|
||||
-0.6787252300829233#430
|
||||
-0.6932766864488242#431
|
||||
-0.7075508286901373#432
|
||||
-0.7215419470789324#433
|
||||
-0.735244445098229#434
|
||||
-0.7486528416806302#435
|
||||
-0.7617617734007782#436
|
||||
-0.7745659966207497#437
|
||||
-0.787060389587538#438
|
||||
-0.7992399544817796#439
|
||||
-0.8110998194169068#440
|
||||
-0.822635240387926#441
|
||||
-0.8338416031690444#442
|
||||
-0.8447144251593824#443
|
||||
-0.8552493571760367#444
|
||||
-0.8654421851937745#445
|
||||
-0.8752888320306655#446
|
||||
-0.8847853589789743#447
|
||||
-0.8939279673806632#448
|
||||
-0.9027130001468745#449
|
||||
-0.9111369432207839#450
|
||||
-0.9191964269832412#451
|
||||
-0.9268882276006345#452
|
||||
-0.9342092683144392#453
|
||||
-0.9411566206719377#454
|
||||
-0.9477275056976144#455
|
||||
-0.9539192950047597#456
|
||||
-0.959729511846838#457
|
||||
-0.9651558321081987#458
|
||||
-0.9701960852337338#459
|
||||
-0.9748482550971108#460
|
||||
-0.9791104808072335#461
|
||||
-0.9829810574526074#462
|
||||
-0.9864584367833128#463
|
||||
-0.9895412278303127#464
|
||||
-0.9922281974618472#465
|
||||
-0.9945182708766922#466
|
||||
-0.9964105320340856#467
|
||||
-0.9979042240201477#468
|
||||
-0.998998749350651#469
|
||||
-0.9996936702100165#470
|
||||
-0.9999887086264423#471
|
||||
-0.9998837465830935#472
|
||||
-0.9993788260653099#473
|
||||
-0.9984741490438113#474
|
||||
-0.9971700773939082#475
|
||||
-0.99546713275075#476
|
||||
-0.9933659963006688#477
|
||||
-0.9908675085087004#478
|
||||
-0.9879726687823952#479
|
||||
-0.9846826350720495#480
|
||||
-0.9809987234075198#481
|
||||
-0.9769224073718046#482
|
||||
-0.9724553175116033#483
|
||||
-0.9675992406850901#484
|
||||
-0.9623561193471611#485
|
||||
-0.9567280507724435#486
|
||||
-0.9507172862163743#487
|
||||
-0.9443262300146881#488
|
||||
-0.9375574386216696#489
|
||||
-0.9304136195875602#490
|
||||
-0.922897630475524#491
|
||||
-0.915012477718608#492
|
||||
-0.9067613154171548#493
|
||||
-0.8981474440771456#494
|
||||
-0.8891743092899825#495
|
||||
-0.879845500354234#496
|
||||
-0.8701647488398982#497
|
||||
-0.8601359270957558#498
|
||||
-0.8497630467004118#499
|
||||
-0.8390502568576437#500
|
||||
-0.8280018427366993#501
|
||||
-0.8166222237582085#502
|
||||
-0.8049159518263918#503
|
||||
-0.7928877095082767#504
|
||||
-0.7805423081606475#505
|
||||
-0.767884686005479#506
|
||||
-0.7549199061546221#507
|
||||
-0.7416531545845351#508
|
||||
-0.728089738061866#509
|
||||
-0.7142350820207211#510
|
||||
-0.7000947283924623#511
|
||||
-0.6856743333889093#512
|
||||
-0.6709796652398244#513
|
||||
-0.6560166018855939#514
|
||||
-0.640791128626021#515
|
||||
-0.6253093357261775#516
|
||||
-0.6095774159802665#517
|
||||
-0.5936016622344745#518
|
||||
-0.5773884648698012#519
|
||||
-0.5609443092458755#520
|
||||
-0.5442757731067793#521
|
||||
-0.5273895239499172#522
|
||||
-0.5102923163589844#523
|
||||
-0.4929909893020995#524
|
||||
-0.4754924633961832#525
|
||||
-0.4578037381386771#526
|
||||
-0.4399318891077101#527
|
||||
-0.42188406513183174#528
|
||||
-0.4036674854304451#529
|
||||
-0.3852894367260835#530
|
||||
-0.36675727032968475#531
|
||||
-0.3480783992000305#532
|
||||
-0.3292602949785258#533
|
||||
-0.3103104850005053#534
|
||||
-0.2912365492842617#535
|
||||
-0.27204611749900054#536
|
||||
-0.25274686591293494#537
|
||||
-0.23334651432273967#538
|
||||
-0.21385282296559432#539
|
||||
-0.19427358941504982#540
|
||||
-0.17461664546196007#541
|
||||
-0.1548898539817267#542
|
||||
-0.13510110578910986#543
|
||||
-0.11525831648186291#544
|
||||
-0.09536942327445402#545
|
||||
-0.07544238182314085#546
|
||||
-0.05548516304366845#547
|
||||
-0.03550574992286332#548
|
||||
-0.015512134325398927#549
|
||||
0.004487686202989896#550
|
||||
0.02448571163456509#551
|
||||
0.04447394265963625#552
|
||||
0.06444438388632431#553
|
||||
0.08438904703875809#554
|
||||
0.10429995415242439#555
|
||||
0.1241691407653935#556
|
||||
0.1439886591041436#557
|
||||
0.16375058126270975#558
|
||||
0.18344700237388564#559
|
||||
0.20307004377121#560
|
||||
0.2226118561404721#561
|
||||
0.2420646226594768#562
|
||||
0.2614205621248122#563
|
||||
0.28067193206436947#564
|
||||
0.29981103183437086#565
|
||||
0.31883020569966475#566
|
||||
0.3377218458960585#567
|
||||
0.35647839567346157#568
|
||||
0.3750923523186232#569
|
||||
0.3935562701562553#570
|
||||
0.41186276352733925#571
|
||||
0.4300045097434266#572
|
||||
0.44797425201575064#573
|
||||
0.46576480235797824#574
|
||||
0.4833690444614399#575
|
||||
0.500779936541689#576
|
||||
0.5179905141552499#577
|
||||
0.5349938929854311#578
|
||||
0.5517832715960851#579
|
||||
0.5683519341522173#580
|
||||
0.5846932531063534#581
|
||||
0.6008006918495911#582
|
||||
0.6166678073262762#583
|
||||
0.6322882526112575#584
|
||||
0.6476557794486876#585
|
||||
0.6627642407513568#586
|
||||
0.6776075930595586#587
|
||||
0.6921798989585037#588
|
||||
0.706475329453315#589
|
||||
0.7204881663006553#590
|
||||
0.7342128042960522#591
|
||||
0.7476437535160088#592
|
||||
0.7607756415139992#593
|
||||
0.7736032154694754#594
|
||||
0.7861213442890201#595
|
||||
0.7983250206588106#596
|
||||
0.8102093630475687#597
|
||||
0.8217696176591981#598
|
||||
0.8330011603343257#599
|
||||
0.8438994983999891#600
|
||||
0.854460272466728#601
|
||||
0.8646792581723609#602
|
||||
0.8745523678717522#603
|
||||
0.8840756522718898#604
|
||||
0.893245302011622#605
|
||||
0.9020576491854215#606
|
||||
0.910509168810565#607
|
||||
0.9185964802371446#608
|
||||
0.926316348500344#609
|
||||
0.9336656856144409#610
|
||||
0.9406415518080167#611
|
||||
0.9472411566998794#612
|
||||
0.95346186041523#613
|
||||
0.9593011746416258#614
|
||||
0.9647567636243177#615
|
||||
0.9698264451005635#616
|
||||
0.974508191172544#617
|
||||
0.9788001291185322#618
|
||||
0.9827005421419915#619
|
||||
0.9862078700583026#620
|
||||
0.989320709918845#621
|
||||
0.9920378165721839#622
|
||||
0.9943581031621368#623
|
||||
0.9962806415625208#624
|
||||
0.9978046627484086#625
|
||||
0.9989295571037418#626
|
||||
0.9996548746651802#627
|
||||
0.9999803253020899#628
|
||||
0.9999057788325965#629
|
||||
0.9994312650756588#630
|
||||
0.998556973839141#631
|
||||
0.9972832548438884#632
|
||||
0.9956106175838376#633
|
||||
0.9935397311222164#634
|
||||
0.9910714238239149#635
|
||||
0.9882066830241357#636
|
||||
0.9849466546334548#637
|
||||
0.9812926426794514#638
|
||||
0.9772461087850911#639
|
||||
0.9728086715840686#640
|
||||
0.9679821060733467#641
|
||||
0.9627683429031486#642
|
||||
0.9571694676046879#643
|
||||
0.9511877197559462#644
|
||||
0.9448254920858304#645
|
||||
0.9380853295170695#646
|
||||
0.9309699281482325#647
|
||||
0.923482134175276#648
|
||||
0.9156249427530513#649
|
||||
0.9074014967972275#650
|
||||
0.8988150857271101#651
|
||||
0.8898691441498562#652
|
||||
0.8805672504866153#653
|
||||
0.8709131255411423#654
|
||||
0.8609106310114581#655
|
||||
0.8505637679451508#656
|
||||
0.8398766751389367#657
|
||||
0.8288536274831215#658
|
||||
0.8174990342516223#659
|
||||
0.8058174373382364#660
|
||||
0.7938135094398614#661
|
||||
0.7814920521873926#662
|
||||
0.7688579942250473#663
|
||||
0.7559163892388825#664
|
||||
0.7426724139352946#665
|
||||
0.7291313659703125#666
|
||||
0.7152986618305073#667
|
||||
0.7011798346663719#668
|
||||
0.6867805320790326#669
|
||||
0.6721065138611806#670
|
||||
0.6571636496931266#671
|
||||
0.6419579167948992#672
|
||||
0.6264953975353273#673
|
||||
0.610782276999062#674
|
||||
0.5948248405125122#675
|
||||
0.5786294711296829#676
|
||||
0.5622026470789215#677
|
||||
0.5455509391715946#678
|
||||
0.52868100817373#679
|
||||
0.5115996021416783#680
|
||||
0.49431355372285585#681
|
||||
0.4768297774226521#682
|
||||
0.45915526683859303#683
|
||||
0.44129709186286736#684
|
||||
0.4232623958543345#685
|
||||
0.4050583927811453#686
|
||||
0.3866923643351191#687
|
||||
0.36817165701903065#688
|
||||
0.34950367920797243#689
|
||||
0.3306958981859679#690
|
||||
0.31175583715902044#691
|
||||
0.2926910722457939#692
|
||||
0.2735092294471269#693
|
||||
0.2542179815955952#694
|
||||
0.23482504528633993#695
|
||||
0.21533817779039144#696
|
||||
0.19576517395172216#697
|
||||
0.17611386306927027#698
|
||||
0.15639210576518112#699
|
||||
0.13660779084051936#700
|
||||
0.11676883211970907#701
|
||||
0.0968831652849648#702
|
||||
0.07695874470197908#703
|
||||
0.057003540238136606#704
|
||||
0.03702553407452759#705
|
||||
0.017032717513035638#706
|
||||
-0.002966912220222811#707
|
||||
-0.022965355173828687#708
|
||||
-0.0429546118710807#709
|
||||
-0.06292668650982579#710
|
||||
-0.08287359016081984#711
|
||||
-0.10278734396333908#712
|
||||
-0.12265998231676409#713
|
||||
-0.1424835560668597#714
|
||||
-0.1622501356854762#715
|
||||
-0.18195181444240016#716
|
||||
-0.20158071156808577#717
|
||||
-0.2211289754060019#718
|
||||
-0.2405887865533338#719
|
||||
-0.2599523609887831#720
|
||||
-0.2792119531862151#721
|
||||
-0.2983598592129078#722
|
||||
-0.3173884198111633#723
|
||||
-0.33629002346204884#724
|
||||
-0.3550571094300426#725
|
||||
-0.37368217078736515#726
|
||||
-0.39215775741678827#727
|
||||
-0.4104764789917186#728
|
||||
-0.4286310079323652#729
|
||||
-0.446614082336808#730
|
||||
-0.46441850888579467#731
|
||||
-0.48203716572010397#732
|
||||
-0.4994630052893251#733
|
||||
-0.5166890571709126#734
|
||||
-0.5337084308583907#735
|
||||
-0.5505143185175893#736
|
||||
-0.5670999977098123#737
|
||||
-0.5834588340808463#738
|
||||
-0.5995842840147351#739
|
||||
-0.6154698972512584#740
|
||||
-0.6311093194660693#741
|
||||
-0.6464962948124537#742
|
||||
-0.6616246684237019#743
|
||||
-0.6764883888750848#744
|
||||
-0.6910815106044541#745
|
||||
-0.7053981962904975#746
|
||||
-0.719432719187695#747
|
||||
-0.7331794654170467#748
|
||||
-0.7466329362116519#749
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,100 @@
|
||||
0.0#0
|
||||
0.05#1
|
||||
0.1#2
|
||||
0.15#3
|
||||
0.2#4
|
||||
0.25#5
|
||||
0.3#6
|
||||
0.35000002#7
|
||||
0.40000004#8
|
||||
0.45000005#9
|
||||
0.50000006#10
|
||||
0.5500001#11
|
||||
0.6000001#12
|
||||
0.6500001#13
|
||||
0.7000001#14
|
||||
0.7500001#15
|
||||
0.80000013#16
|
||||
0.85000014#17
|
||||
0.90000015#18
|
||||
0.95000017#19
|
||||
1.0000001#20
|
||||
1.0500001#21
|
||||
1.1#22
|
||||
1.15#23
|
||||
1.1999999#24
|
||||
1.2499999#25
|
||||
1.2999998#26
|
||||
1.3499998#27
|
||||
1.3999997#28
|
||||
1.4499997#29
|
||||
1.4999996#30
|
||||
1.5499996#31
|
||||
1.5999995#32
|
||||
1.6499995#33
|
||||
1.6999995#34
|
||||
1.7499994#35
|
||||
1.7999994#36
|
||||
1.8499993#37
|
||||
1.8999993#38
|
||||
1.9499992#39
|
||||
1.9999992#40
|
||||
2.0499992#41
|
||||
2.0999992#42
|
||||
2.1499991#43
|
||||
2.199999#44
|
||||
2.249999#45
|
||||
2.299999#46
|
||||
2.349999#47
|
||||
2.399999#48
|
||||
2.4499989#49
|
||||
2.4999988#50
|
||||
2.5499988#51
|
||||
2.5999987#52
|
||||
2.6499987#53
|
||||
2.6999986#54
|
||||
2.7499986#55
|
||||
2.7999985#56
|
||||
2.8499985#57
|
||||
2.8999984#58
|
||||
2.9499984#59
|
||||
2.9999983#60
|
||||
3.0499983#61
|
||||
3.0999982#62
|
||||
3.1499982#63
|
||||
3.1999981#64
|
||||
3.249998#65
|
||||
3.299998#66
|
||||
3.349998#67
|
||||
3.399998#68
|
||||
3.449998#69
|
||||
3.4999979#70
|
||||
3.5499978#71
|
||||
3.5999978#72
|
||||
3.6499977#73
|
||||
3.6999977#74
|
||||
3.7499976#75
|
||||
3.7999976#76
|
||||
3.8499975#77
|
||||
3.8999975#78
|
||||
3.9499974#79
|
||||
3.9999974#80
|
||||
4.0499973#81
|
||||
4.0999975#82
|
||||
4.1499977#83
|
||||
4.199998#84
|
||||
4.249998#85
|
||||
4.2999983#86
|
||||
4.3499985#87
|
||||
4.3999987#88
|
||||
4.449999#89
|
||||
4.499999#90
|
||||
4.549999#91
|
||||
4.5999994#92
|
||||
4.6499996#93
|
||||
4.7#94
|
||||
4.75#95
|
||||
4.8#96
|
||||
4.8500004#97
|
||||
4.9000006#98
|
||||
4.950001#99
|
||||
@@ -0,0 +1,100 @@
|
||||
0.0#0
|
||||
-0.14978661516463596#1
|
||||
-0.2302585112404076#2
|
||||
-0.28456800308013386#3
|
||||
-0.32188758430308656#4
|
||||
-0.34657359027997264#5
|
||||
-0.36119184372932583#6
|
||||
-0.36743774476238833#7
|
||||
-0.3665162897559837#8
|
||||
-0.359328453690093#9
|
||||
-0.3465735719901158#10
|
||||
-0.32881032165064733#11
|
||||
-0.3064953334396977#12
|
||||
-0.28000884117531694#13
|
||||
-0.24967239173581385#14
|
||||
-0.21576146942391214#15
|
||||
-0.1785147391820012#16
|
||||
-0.13814097027046854#17
|
||||
-0.0948243254478918#18
|
||||
-0.04872847133564503#19
|
||||
1.1920929665620834E-7#20
|
||||
0.05122974739322425#21
|
||||
0.10484122389898727#22
|
||||
0.16072620655739048#23
|
||||
0.21878578358651998#24
|
||||
0.2789292933326941#25
|
||||
0.34107333312798316#26
|
||||
0.4051409208357928#27
|
||||
0.4710607807659298#28
|
||||
0.538766731719029#29
|
||||
0.6081971595287982#30
|
||||
0.6792945600019588#31
|
||||
0.7520051408885056#32
|
||||
0.8262784736489888#33
|
||||
0.9020671874662887#34
|
||||
0.9793266992836409#35
|
||||
1.0580149747177598#36
|
||||
1.1380923155552924#37
|
||||
1.219521170237435#38
|
||||
1.3022659643057064#39
|
||||
1.3862929482479571#40
|
||||
1.4715702653505391#41
|
||||
1.5580670118770785#42
|
||||
1.6457543452870462#43
|
||||
1.7346045724760228#44
|
||||
1.8245912594493057#45
|
||||
1.9156891473526845#46
|
||||
2.0078740758078952#47
|
||||
2.1011229127752893#48
|
||||
2.195413490263484#49
|
||||
2.290724545289105#50
|
||||
2.3870356655613914#51
|
||||
2.4843272394282487#52
|
||||
2.582580409673842#53
|
||||
2.6817770308042372#54
|
||||
2.7818996294980054#55
|
||||
2.8829313679339723#56
|
||||
2.984856009739134#57
|
||||
3.0876578883268277#58
|
||||
3.191321877419036#59
|
||||
3.2958333635676733#60
|
||||
3.401178220508231#61
|
||||
3.507342785195528#62
|
||||
3.6143138353859015#63
|
||||
3.7220785686430475#64
|
||||
3.8306245826562813#65
|
||||
3.939939856770217#66
|
||||
4.050012734634095#67
|
||||
4.160831907887155#68
|
||||
4.272386400803882#69
|
||||
4.384665555829532#70
|
||||
4.497659019942356#71
|
||||
4.6113567317842685#72
|
||||
4.725748909506607#73
|
||||
4.840826039281976#74
|
||||
4.956578864437172#75
|
||||
5.072998375165778#76
|
||||
5.190075798782273#77
|
||||
5.307802590482506#78
|
||||
5.4261704245780376#79
|
||||
5.545171186174402#80
|
||||
5.664796963265484#81
|
||||
5.785040614042304#82
|
||||
5.9058940410526075#83
|
||||
6.027349897205024#84
|
||||
6.149401010352234#85
|
||||
6.2720403771158635#86
|
||||
6.395261156998629#87
|
||||
6.519056666767231#88
|
||||
6.643420375090577#89
|
||||
6.768345897419035#90
|
||||
6.893826991091276#91
|
||||
7.019857550656251#92
|
||||
7.146431603398553#93
|
||||
7.273543305056277#94
|
||||
7.401186935721112#95
|
||||
7.529356895911067#96
|
||||
7.658047702806867#97
|
||||
7.787253986643549#98
|
||||
7.916970487249359#99
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,750 @@
|
||||
0.0#0
|
||||
0.019998666246387648#1
|
||||
0.039989333293279646#2
|
||||
0.059964005140753354#3
|
||||
0.07991469218675235#4
|
||||
0.0998334181294999#5
|
||||
0.11971221202299985#6
|
||||
0.1395431152344512#7
|
||||
0.15931820308364608#8
|
||||
0.17902956580240917#9
|
||||
0.19866931911175714#10
|
||||
0.21822960737550368#11
|
||||
0.23770260674240787#12
|
||||
0.25708054267594205#13
|
||||
0.2763556497097811#14
|
||||
0.29552021804983797#15
|
||||
0.31456658211607685#16
|
||||
0.33348712360864613#17
|
||||
0.35227427455509996#18
|
||||
0.3709205203374898#19
|
||||
0.38941840269811434#20
|
||||
0.40776052272272667#21
|
||||
0.42593954380000415#22
|
||||
0.4439481945560986#23
|
||||
0.46177927176309164#24
|
||||
0.4794256432201933#25
|
||||
0.49688022474350485#26
|
||||
0.5141360611809643#27
|
||||
0.5311862504412359#28
|
||||
0.5480239726889556#29
|
||||
0.5646424930725696#30
|
||||
0.5810351644181799#31
|
||||
0.5971954298883201#32
|
||||
0.6131168256045979#33
|
||||
0.6287929832331555#34
|
||||
0.6442176325319131#35
|
||||
0.659384603858578#36
|
||||
0.6742878306384138#37
|
||||
0.6889213517907848#38
|
||||
0.7032793141135052#39
|
||||
0.7173559746240362#40
|
||||
0.7311457028565987#41
|
||||
0.7446429831142805#42
|
||||
0.7578424166752367#43
|
||||
0.7707387239521026#44
|
||||
0.7833267466037546#45
|
||||
0.795601449598573#46
|
||||
0.8075579232283849#47
|
||||
0.8191913850722774#48
|
||||
0.8304971819094986#49
|
||||
0.8414707915806806#50
|
||||
0.8521078247966395#51
|
||||
0.8624040268940288#52
|
||||
0.8723552795371456#53
|
||||
0.8819576023652057#54
|
||||
0.8912071545844327#55
|
||||
0.9001002365043209#56
|
||||
0.9086332910174598#57
|
||||
0.9168029050223264#58
|
||||
0.9246058107884779#59
|
||||
0.9320388872635981#60
|
||||
0.9390991613218737#61
|
||||
0.9457838089532035#62
|
||||
0.952090156392762#63
|
||||
0.9580156811904679#64
|
||||
0.9635580132199286#65
|
||||
0.9687149356264573#66
|
||||
0.9734843857137836#67
|
||||
0.9778644557691029#68
|
||||
0.9818533938261347#69
|
||||
0.9854496043658845#70
|
||||
0.9886516489548286#71
|
||||
0.9914582468202678#72
|
||||
0.9938682753626178#73
|
||||
0.9958807706044335#74
|
||||
0.9974949275759862#75
|
||||
0.9987101006372409#76
|
||||
0.9995258037361018#77
|
||||
0.9999417106028279#78
|
||||
0.9999576548805349#79
|
||||
0.9995736301917366#80
|
||||
0.9987897901408953#81
|
||||
0.9976064482529823#82
|
||||
0.9960240778480722#83
|
||||
0.9940433118520219#84
|
||||
0.9916649425433088#85
|
||||
0.988889921236131#86
|
||||
0.9857193578998942#87
|
||||
0.9821545207152407#88
|
||||
0.9781968355667943#89
|
||||
0.9738478854728265#90
|
||||
0.9691094099520721#91
|
||||
0.9639833043279455#92
|
||||
0.9584716189704385#93
|
||||
0.9525765584760014#94
|
||||
0.9463004807857347#95
|
||||
0.9396458962422467#96
|
||||
0.9326154665855515#97
|
||||
0.9252120038884106#98
|
||||
0.9174384694315432#99
|
||||
0.909297972519156#100
|
||||
0.9007937174689649#101
|
||||
0.8919292072378467#102
|
||||
0.8827079378965067#103
|
||||
0.8731335978226978#104
|
||||
0.8632100166174893#105
|
||||
0.85294116357348#106
|
||||
0.8423311460871373#107
|
||||
0.8313842080158964#108
|
||||
0.8201047279806774#109
|
||||
0.8084972176144982#110
|
||||
0.7965663197578854#111
|
||||
0.7843168066018031#112
|
||||
0.7717535777788443#113
|
||||
0.7588816584034461#114
|
||||
0.7457061970619157#115
|
||||
0.7322324637530676#116
|
||||
0.7184658477802992#117
|
||||
0.7044118555959447#118
|
||||
0.6900761085987721#119
|
||||
0.6754643408855032#120
|
||||
0.660582396957255#121
|
||||
0.6454362293818222#122
|
||||
0.630031896412734#123
|
||||
0.6143755595660381#124
|
||||
0.5984734811557804#125
|
||||
0.5823320217891688#126
|
||||
0.5659576378224191#127
|
||||
0.5493568787783043#128
|
||||
0.5325363847264367#129
|
||||
0.5155028836273348#130
|
||||
0.498263188641333#131
|
||||
0.48082419540341453#132
|
||||
0.46319287926505354#133
|
||||
0.44537629250417365#134
|
||||
0.42738156150433587#135
|
||||
0.4092158839042855#136
|
||||
0.39088652571899846#137
|
||||
0.37240081843337736#138
|
||||
0.3537661560697612#139
|
||||
0.33498999223042036#140
|
||||
0.3160798371162209#141
|
||||
0.29704325452265024#142
|
||||
0.2778878588144052#143
|
||||
0.25862131187975385#144
|
||||
0.2392513200658879#145
|
||||
0.21978563109649268#146
|
||||
0.20023203097276676#147
|
||||
0.1805983408591312#148
|
||||
0.1608924139548741#149
|
||||
0.1411221323529816#150
|
||||
0.12129540388741163#151
|
||||
0.10142015897007202#152
|
||||
0.08150434741876739#153
|
||||
0.06155593527738411#154
|
||||
0.04158290162958502#155
|
||||
0.02159323540728851#156
|
||||
0.0015949321952082743#157
|
||||
-0.01840400896726781#158
|
||||
-0.038395588785580706#159
|
||||
-0.05837181090960527#160
|
||||
-0.07832468513207759#161
|
||||
-0.09824623058456528#162
|
||||
-0.11812847892970231#163
|
||||
-0.13796347754841165#164
|
||||
-0.15774329272084087#165
|
||||
-0.1774600127997381#166
|
||||
-0.19710575137499955#167
|
||||
-0.2166726504281223#168
|
||||
-0.23615288347530097#169
|
||||
-0.2555386586979109#170
|
||||
-0.2748222220591258#171
|
||||
-0.29399586040542314#172
|
||||
-0.3130519045517368#173
|
||||
-0.33198273234902315#174
|
||||
-0.350780771733013#175
|
||||
-0.36943850375293075#176
|
||||
-0.38794846557896867#177
|
||||
-0.40630325348731355#178
|
||||
-0.42449552582153194#179
|
||||
-0.44251800592912927#180
|
||||
-0.4603634850721081#181
|
||||
-0.47802482531036194#182
|
||||
-0.49549496235675056#183
|
||||
-0.5127669084027151#184
|
||||
-0.5298337549133033#185
|
||||
-0.5466886753904862#186
|
||||
-0.5633249281036602#187
|
||||
-0.5797358587862456#188
|
||||
-0.5959149032972986#189
|
||||
-0.6118555902470753#190
|
||||
-0.6275515435854963#191
|
||||
-0.6429964851524771#192
|
||||
-0.6581842371891036#193
|
||||
-0.6731087248086483#194
|
||||
-0.6877639784264394#195
|
||||
-0.7021441361476113#196
|
||||
-0.7162434461117786#197
|
||||
-0.7300562687937001#198
|
||||
-0.7435770792590093#199
|
||||
-0.7568004693741099#200
|
||||
-0.7697213021710452#201
|
||||
-0.7823341014558161#202
|
||||
-0.7946339781278204#203
|
||||
-0.806616012409769#204
|
||||
-0.8182754116568484#205
|
||||
-0.8296075122737109#206
|
||||
-0.8406077815798478#207
|
||||
-0.8512718196225969#208
|
||||
-0.8615953609370618#209
|
||||
-0.8715742762522378#210
|
||||
-0.8812045741426621#211
|
||||
-0.8904824026249275#212
|
||||
-0.8994040506984219#213
|
||||
-0.9079659498296758#214
|
||||
-0.9161646753797257#215
|
||||
-0.923996947973921#216
|
||||
-0.9314596348136281#217
|
||||
-0.9385497509293057#218
|
||||
-0.9452644603744499#219
|
||||
-0.9516010773599336#220
|
||||
-0.9575570673282837#221
|
||||
-0.9631300479674688#222
|
||||
-0.9683177901637904#223
|
||||
-0.9731182188934963#224
|
||||
-0.9775294140527618#225
|
||||
-0.9815496112257037#226
|
||||
-0.9851772023901216#227
|
||||
-0.9884107365606845#228
|
||||
-0.991248920369304#229
|
||||
-0.9936906185824641#230
|
||||
-0.9957348545552975#231
|
||||
-0.997380810622231#232
|
||||
-0.9986278284240393#233
|
||||
-0.9994754091711795#234
|
||||
-0.9999232138433003#235
|
||||
-0.9999710633248452#236
|
||||
-0.999618938476696#237
|
||||
-0.9988669801438286#238
|
||||
-0.9977154890989762#239
|
||||
-0.9961649259223255#240
|
||||
-0.9942159108172903#241
|
||||
-0.9918692233624392#242
|
||||
-0.989125802199675#243
|
||||
-0.9859867446587918#244
|
||||
-0.9824533063185572#245
|
||||
-0.9785269005045#246
|
||||
-0.9742090977235991#247
|
||||
-0.9695016250361028#248
|
||||
-0.9644063653647295#249
|
||||
-0.9589253567415246#250
|
||||
-0.953060791492677#251
|
||||
-0.9468150153616188#252
|
||||
-0.940190526570762#253
|
||||
-0.9331899748222436#254
|
||||
-0.9258161602380832#255
|
||||
-0.9180720322401726#256
|
||||
-0.9099606883705496#257
|
||||
-0.901485373052424#258
|
||||
-0.8926494762924547#259
|
||||
-0.8834565323247946#260
|
||||
-0.8739102181974464#261
|
||||
-0.864014352301496#262
|
||||
-0.8537728928438092#263
|
||||
-0.8431899362638049#264
|
||||
-0.8322697155949375#265
|
||||
-0.8210165987715422#266
|
||||
-0.8094350868817244#267
|
||||
-0.7975298123669863#268
|
||||
-0.7853055371693165#269
|
||||
-0.7727671508264802#270
|
||||
-0.7599196685162729#271
|
||||
-0.7467682290505201#272
|
||||
-0.7333180928196247#273
|
||||
-0.7195746396884855#274
|
||||
-0.7055433668446264#275
|
||||
-0.6912298865993995#276
|
||||
-0.6766399241431399#277
|
||||
-0.6617793152551689#278
|
||||
-0.646654003969566#279
|
||||
-0.6312700401976384#280
|
||||
-0.6156335773080419#281
|
||||
-0.5997508696655202#282
|
||||
-0.5836282701292467#283
|
||||
-0.5672722275117711#284
|
||||
-0.5506892839995849#285
|
||||
-0.5338860725363392#286
|
||||
-0.5168693141697605#287
|
||||
-0.4996458153633263#288
|
||||
-0.48222246527377605#289
|
||||
-0.4646062329955453#290
|
||||
-0.44680416477322615#291
|
||||
-0.42882338118316876#292
|
||||
-0.4106710742853512#293
|
||||
-0.392354504746657#294
|
||||
-0.37388099893671045#295
|
||||
-0.3552579459974321#296
|
||||
-0.33649279488748635#297
|
||||
-0.31759305140280275#298
|
||||
-0.2985662751743636#299
|
||||
-0.27942007664445806#300
|
||||
-0.2601621140226123#301
|
||||
-0.24080009022241405#302
|
||||
-0.22134174978045548#303
|
||||
-0.2017948757586277#304
|
||||
-0.18216728663100587#305
|
||||
-0.1624668331565697#306
|
||||
-0.1427013952390105#307
|
||||
-0.12287887877488078#308
|
||||
-0.10300721249134719#309
|
||||
-0.08309434477481123#310
|
||||
-0.06314824049166687#311
|
||||
-0.04317687780246621#312
|
||||
-0.02318824497076772#313
|
||||
-0.0031903371679434384#314
|
||||
0.016808846724776887#315
|
||||
0.03680130731574554#316
|
||||
0.056779047902540736#317
|
||||
0.07673407767053486#318
|
||||
0.09665841488910769#319
|
||||
0.11654409010422613#320
|
||||
0.13638314932611348#321
|
||||
0.1561676572107332#322
|
||||
0.17588970023381478#323
|
||||
0.19554138985615177#324
|
||||
0.21511486567890625#325
|
||||
0.23460229858765777#326
|
||||
0.2539958938839385#327
|
||||
0.2732878944030029#328
|
||||
0.2924705836165842#329
|
||||
0.311536288719397#330
|
||||
0.3304773836981512#331
|
||||
0.3492862923818499#332
|
||||
0.3679554914721506#333
|
||||
0.38647751355257925#334
|
||||
0.40484495007539084#335
|
||||
0.42305045432488436#336
|
||||
0.44108674435598566#337
|
||||
0.45894660590692266#338
|
||||
0.4766228952848283#339
|
||||
0.49410854222311723#340
|
||||
0.5113965527094926#341
|
||||
0.5284800117834523#342
|
||||
0.545352086302176#343
|
||||
0.5620060276736858#344
|
||||
0.5784351745561876#345
|
||||
0.5946329555225146#346
|
||||
0.6105928916886046#347
|
||||
0.6263085993049634#348
|
||||
0.6417737923100737#349
|
||||
0.6569822848447313#350
|
||||
0.6719279937263022#351
|
||||
0.6866049408819089#352
|
||||
0.7010072557395762#353
|
||||
0.7151291775763766#354
|
||||
0.7289650578226388#355
|
||||
0.7425093623212952#356
|
||||
0.7557566735414675#357
|
||||
0.7687016927454025#358
|
||||
0.781339242107892#359
|
||||
0.7936642667873305#360
|
||||
0.8056718369475803#361
|
||||
0.8173571497298365#362
|
||||
0.8287155311737031#363
|
||||
0.8397424380867105#364
|
||||
0.8504334598615295#365
|
||||
0.8607843202401511#366
|
||||
0.8707908790243301#367
|
||||
0.8804491337316057#368
|
||||
0.8897552211962383#369
|
||||
0.8987054191144209#370
|
||||
0.9072961475331487#371
|
||||
0.9155239702821494#372
|
||||
0.9233855963483032#373
|
||||
0.9308778811920015#374
|
||||
0.9379978280049185#375
|
||||
0.9447425889086918#376
|
||||
0.9511094660940346#377
|
||||
0.9570959128998204#378
|
||||
0.9626995348317123#379
|
||||
0.9679180905199263#380
|
||||
0.9727494926157481#381
|
||||
0.977191808626443#382
|
||||
0.9812432616882257#383
|
||||
0.9849022312769813#384
|
||||
0.988167253856451#385
|
||||
0.991037023463627#386
|
||||
0.9935103922311188#387
|
||||
0.9955863708462842#388
|
||||
0.9972641289469402#389
|
||||
0.9985429954534961#390
|
||||
0.9994224588373765#391
|
||||
0.9999021673256246#392
|
||||
0.9999819290416072#393
|
||||
0.9996617120817624#394
|
||||
0.9989416445283599#395
|
||||
0.9978220143982713#396
|
||||
0.9963032695277663#397
|
||||
0.9943860173933846#398
|
||||
0.9920710248689544#399
|
||||
0.9893592179188533#400
|
||||
0.986251602430098#401
|
||||
0.9827494813924079#402
|
||||
0.9788542556716259#403
|
||||
0.9745674833774243#404
|
||||
0.9698908792400535#405
|
||||
0.9648263139244408#406
|
||||
0.959375813281916#407
|
||||
0.9535415575398596#408
|
||||
0.947325880429602#409
|
||||
0.9407312682529189#410
|
||||
0.9337603588874981#411
|
||||
0.9264159407317759#412
|
||||
0.918700951589563#413
|
||||
0.9106184774949092#414
|
||||
0.9021717514776737#415
|
||||
0.8933641522702975#416
|
||||
0.8841992029562936#417
|
||||
0.8746805695609958#418
|
||||
0.8648120595851305#419
|
||||
0.8545976204817978#420
|
||||
0.8440413380774695#421
|
||||
0.8331474349376399#422
|
||||
0.8219202686777767#423
|
||||
0.8103643302202548#424
|
||||
0.7984842419979638#425
|
||||
0.7862847561053125#426
|
||||
0.7737707523973671#427
|
||||
0.7609472365378854#428
|
||||
0.7478193379970259#429
|
||||
0.7343923079995343#430
|
||||
0.7206715174242275#431
|
||||
0.7066624546556156#432
|
||||
0.6923707233885205#433
|
||||
0.67780204038657#434
|
||||
0.6629622331954643#435
|
||||
0.6478572378119283#436
|
||||
0.6324930963092836#437
|
||||
0.6168759544205892#438
|
||||
0.6010120590803173#439
|
||||
0.5849077559255487#440
|
||||
0.5685694867576866#441
|
||||
0.5520037869657035#442
|
||||
0.5352172829119535#443
|
||||
0.5182166892815939#444
|
||||
0.5010088063966786#445
|
||||
0.48360051749599425#446
|
||||
0.4659987859817315#447
|
||||
0.44821065263408894#448
|
||||
0.4302432327949262#449
|
||||
0.4121037135215916#450
|
||||
0.39379935071206357#451
|
||||
0.3753374662025555#452
|
||||
0.35672544483874447#453
|
||||
0.3379707315217965#454
|
||||
0.31908082823036904#455
|
||||
0.30006329101978185#456
|
||||
0.2809257269995578#457
|
||||
0.2616757912905407#458
|
||||
0.2423211839628092#459
|
||||
0.2228696469556102#460
|
||||
0.2033289609805449#461
|
||||
0.18370694240924518#462
|
||||
0.16401144014678615#463
|
||||
0.14425033249208516#464
|
||||
0.12443152398654284#465
|
||||
0.10456294225218733#466
|
||||
0.084652534820586#467
|
||||
0.06470826595379324#468
|
||||
0.04473811345860604#469
|
||||
0.024750065495401534#470
|
||||
0.004752117382833131#471
|
||||
-0.015247731600336746#472
|
||||
-0.03524148141498798#473
|
||||
-0.05522113446169821#474
|
||||
-0.0751786987798224#475
|
||||
-0.09510619124431689#476
|
||||
-0.11499564075902909#477
|
||||
-0.13483909144517564#478
|
||||
-0.15462860582373356#479
|
||||
-0.17435626799047124#480
|
||||
-0.19401418678234966#481
|
||||
-0.21359449893402682#482
|
||||
-0.23308937222320295#483
|
||||
-0.25249100860354845#484
|
||||
-0.27179164732396127#485
|
||||
-0.290983568032906#486
|
||||
-0.3100590938665927#487
|
||||
-0.32901059451976084#488
|
||||
-0.3478304892978393#489
|
||||
-0.36651125014926184#490
|
||||
-0.3850454046767254#491
|
||||
-0.40342553912618595#492
|
||||
-0.42164430135239717#493
|
||||
-0.4396944037598051#494
|
||||
-0.4575686262176226#495
|
||||
-0.4752598189479177#496
|
||||
-0.49276090538556006#497
|
||||
-0.5100648850088826#498
|
||||
-0.5271648361399248#499
|
||||
-0.5440539187131385#500
|
||||
-0.5607253770114478#501
|
||||
-0.5771725423685697#502
|
||||
-0.5933888358365144#503
|
||||
-0.6093677708171961#504
|
||||
-0.625102955657105#505
|
||||
-0.6405880962040014#506
|
||||
-0.6558169983246062#507
|
||||
-0.6707835703822864#508
|
||||
-0.6854818256737397#509
|
||||
-0.6999058848237054#510
|
||||
-0.7140499781367439#511
|
||||
-0.7279084479051434#512
|
||||
-0.7414757506720319#513
|
||||
-0.7547464594487863#514
|
||||
-0.7677152658858558#515
|
||||
-0.780376982396128#516
|
||||
-0.7927265442299892#517
|
||||
-0.8047590115012498#518
|
||||
-0.8164695711631232#519
|
||||
-0.8278535389334684#520
|
||||
-0.8389063611685262#521
|
||||
-0.8496236166843997#522
|
||||
-0.8600010185255492#523
|
||||
-0.8700344156795967#524
|
||||
-0.8797197947377503#525
|
||||
-0.8890532815001886#526
|
||||
-0.8980311425257598#527
|
||||
-0.9066497866253763#528
|
||||
-0.9149057662985087#529
|
||||
-0.9227957791122028#530
|
||||
-0.9303166690220693#531
|
||||
-0.9374654276347177#532
|
||||
-0.9442391954111279#533
|
||||
-0.9506352628104804#534
|
||||
-0.9566510713739863#535
|
||||
-0.9622842147482832#536
|
||||
-0.9675324396479887#537
|
||||
-0.9723936467570258#538
|
||||
-0.9768658915683597#539
|
||||
-0.9809473851618101#540
|
||||
-0.9846364949196288#541
|
||||
-0.9879317451795541#542
|
||||
-0.9908318178250837#543
|
||||
-0.9933355528127273#544
|
||||
-0.9954419486360307#545
|
||||
-0.9971501627261821#546
|
||||
-0.9984595117890447#547
|
||||
-0.9993694720784776#548
|
||||
-0.9998796796058368#549
|
||||
-0.9999899302855721#550
|
||||
-0.9997001800168633#551
|
||||
-0.9990105447012596#552
|
||||
-0.9979213001963191#553
|
||||
-0.9964328822052644#554
|
||||
-0.9945458861026987#555
|
||||
-0.9922610666964535#556
|
||||
-0.9895793379256616#557
|
||||
-0.9865017724951763#558
|
||||
-0.9830296014464852#559
|
||||
-0.9791642136652865#560
|
||||
-0.9749071553259283#561
|
||||
-0.9702601292729311#562
|
||||
-0.9652249943398415#563
|
||||
-0.9598037646056896#564
|
||||
-0.9539986085893469#565
|
||||
-0.9478118483821087#566
|
||||
-0.9412459587188456#567
|
||||
-0.9343035659880974#568
|
||||
-0.926987447181504#569
|
||||
-0.9193005287829963#570
|
||||
-0.9112458855981864#571
|
||||
-0.9028267395244314#572
|
||||
-0.8940464582620574#573
|
||||
-0.8849085539672636#574
|
||||
-0.8754166818472415#575
|
||||
-0.8655746386980744#576
|
||||
-0.8553863613859995#577
|
||||
-0.8448559252726426#578
|
||||
-0.8339875425848524#579
|
||||
-0.8227855607297891#580
|
||||
-0.8112544605559403#581
|
||||
-0.7993988545607584#582
|
||||
-0.7872234850456398#583
|
||||
-0.7747332222189794#584
|
||||
-0.7619330622480646#585
|
||||
-0.7488281252605818#586
|
||||
-0.7354236532965415#587
|
||||
-0.7217250082114348#588
|
||||
-0.7077376695314656#589
|
||||
-0.6934672322617121#590
|
||||
-0.6789194046480973#591
|
||||
-0.6641000058940624#592
|
||||
-0.6490149638328556#593
|
||||
-0.6336703125563705#594
|
||||
-0.6180721900014786#595
|
||||
-0.6022268354948238#596
|
||||
-0.5861405872570615#597
|
||||
-0.569819879867538#598
|
||||
-0.5532712416904271#599
|
||||
-0.5365012922633521#600
|
||||
-0.5195167396495373#601
|
||||
-0.5023243777545499#602
|
||||
-0.4849310836087036#603
|
||||
-0.4673438146162124#604
|
||||
-0.44956960577219424#605
|
||||
-0.43161556684863794#606
|
||||
-0.4134888795504591#607
|
||||
-0.3951967946427822#608
|
||||
-0.3767466290505987#609
|
||||
-0.3581457629319605#610
|
||||
-0.33940163672588003#611
|
||||
-0.32052174817611767#612
|
||||
-0.30151364933204683#613
|
||||
-0.28238494352779664#614
|
||||
-0.26314328234088047#615
|
||||
-0.24379636253152692#616
|
||||
-0.2243519229639374#617
|
||||
-0.20481774151070187#618
|
||||
-0.1852016319416111#619
|
||||
-0.16551144079810998#620
|
||||
-0.14575504425464175#621
|
||||
-0.12594034496813916#622
|
||||
-0.10607526891692229#623
|
||||
-0.08616776223026779#624
|
||||
-0.06622578800991763#625
|
||||
-0.04625732314479881#626
|
||||
-0.02627035512022804#627
|
||||
-0.006272878822877913#628
|
||||
0.013727106657217596#629
|
||||
0.03372160122633892#630
|
||||
0.053702606987158195#631
|
||||
0.07366213143793802#632
|
||||
0.0935921906695719#633
|
||||
0.11348481255918764#634
|
||||
0.13333203995903614#635
|
||||
0.1531259338793901#636
|
||||
0.17285857666417945#637
|
||||
0.19252207515809314#638
|
||||
0.21210856386388055#639
|
||||
0.2316102080885896#640
|
||||
0.2510192070774827#641
|
||||
0.2703277971343779#642
|
||||
0.2895282547271654#643
|
||||
0.3086128995772594#644
|
||||
0.3275740977317474#645
|
||||
0.34640426461700946#646
|
||||
0.36509586807258537#647
|
||||
0.38364143136407647#648
|
||||
0.4020335361738763#649
|
||||
0.4202648255685349#650
|
||||
0.43832800694156854#651
|
||||
0.45621585493053873#652
|
||||
0.4739212143072332#653
|
||||
0.49143700283979275#654
|
||||
0.508756214125639#655
|
||||
0.5258719203940706#656
|
||||
0.5427772752774059#657
|
||||
0.5594655165495643#658
|
||||
0.5759299688309899#659
|
||||
0.5921640462588365#660
|
||||
0.6081612551213462#661
|
||||
0.6239151964553658#662
|
||||
0.6394195686059639#663
|
||||
0.6546681697471249#664
|
||||
0.6696549003625094#665
|
||||
0.6843737656852915#666
|
||||
0.6988188780960954#667
|
||||
0.7129844594780727#668
|
||||
0.7268648435281768#669
|
||||
0.740454478023714#670
|
||||
0.7537479270432587#671
|
||||
0.7667398731410499#672
|
||||
0.7794251194739955#673
|
||||
0.7917985918804359#674
|
||||
0.8038553409098333#675
|
||||
0.8155905438025771#676
|
||||
0.8269995064191112#677
|
||||
0.8380776651176137#678
|
||||
0.8488205885794762#679
|
||||
0.8592239795818529#680
|
||||
0.8692836767165718#681
|
||||
0.878995656054718#682
|
||||
0.8883560327562258#683
|
||||
0.8973610626238337#684
|
||||
0.9060071436007824#685
|
||||
0.9142908172116547#686
|
||||
0.9222087699457837#687
|
||||
0.929757834582673#688
|
||||
0.9369349914589009#689
|
||||
0.9437373696760004#690
|
||||
0.9501622482488337#691
|
||||
0.9562070571939989#692
|
||||
0.9618693785578367#693
|
||||
0.9671469473836236#694
|
||||
0.9720376526175663#695
|
||||
0.976539537953233#696
|
||||
0.9806508026140864#697
|
||||
0.9843698020738031#698
|
||||
0.9876950487140919#699
|
||||
0.990625212419749#700
|
||||
0.9931591211107106#701
|
||||
0.9952957612108906#702
|
||||
0.9970342780536162#703
|
||||
0.9983739762234987#704
|
||||
0.9993143198346034#705
|
||||
0.9998549327448063#706
|
||||
0.9999955987062531#707
|
||||
0.999736261451859#708
|
||||
0.9990770247178167#709
|
||||
0.9980181522021#710
|
||||
0.9965600674589848#711
|
||||
0.9947033537296244#712
|
||||
0.99244875370875#713
|
||||
0.9897971692475899#714
|
||||
0.9867496609931237#715
|
||||
0.9833074479638189#716
|
||||
0.9794719070620168#717
|
||||
0.9752445725231655#718
|
||||
0.9706271353021171#719
|
||||
0.9656214423967383#720
|
||||
0.9602294961091015#721
|
||||
0.9544534532445539#722
|
||||
0.9482956242489854#723
|
||||
0.9417584722846377#724
|
||||
0.934844612244828#725
|
||||
0.9275568097079782#726
|
||||
0.9198979798313699#727
|
||||
0.911871186185067#728
|
||||
0.9034796395264725#729
|
||||
0.8947266965160092#730
|
||||
0.8856158583744393#731
|
||||
0.8761507694823586#732
|
||||
0.8663352159224256#733
|
||||
0.8561731239649102#734
|
||||
0.8456685584971658#735
|
||||
0.8348257213976545#736
|
||||
0.8236489498551739#737
|
||||
0.812142714633961#738
|
||||
0.8003116182853636#739
|
||||
0.7881603933067972#740
|
||||
0.7756939002487224#741
|
||||
0.7629171257704004#742
|
||||
0.7498351806452045#743
|
||||
0.7364532977162856#744
|
||||
0.7227768298034087#745
|
||||
0.7088112475617983#746
|
||||
0.6945621372938487#747
|
||||
0.6800351987145765#748
|
||||
0.6652362426717048#749
|
||||
@@ -0,0 +1,100 @@
|
||||
0.0#0
|
||||
0.0025000000745058065#1
|
||||
0.010000000298023226#2
|
||||
0.02250000178813938#3
|
||||
0.040000001192092904#4
|
||||
0.0625#5
|
||||
0.09000000715255752#6
|
||||
0.1225000166893011#7
|
||||
0.16000002861023077#8
|
||||
0.2025000429153465#9
|
||||
0.25000005960464833#10
|
||||
0.3025000786781362#11
|
||||
0.3600001001358102#12
|
||||
0.42250012397767023#13
|
||||
0.49000015020371634#14
|
||||
0.5625001788139485#15
|
||||
0.6400002098083668#16
|
||||
0.7225002431869711#17
|
||||
0.8100002789497616#18
|
||||
0.9025003170967381#19
|
||||
1.0000002384185933#20
|
||||
1.10250015020371#21
|
||||
1.210000052452088#22
|
||||
1.3224999451637274#23
|
||||
1.4399998283386282#24
|
||||
1.5624997019767903#25
|
||||
1.6899995660782139#26
|
||||
1.8224994206428988#27
|
||||
1.9599992656708451#28
|
||||
2.102499101162053#29
|
||||
2.249998927116522#30
|
||||
2.4024987435342524#31
|
||||
2.5599985504152443#32
|
||||
2.7224983477594975#33
|
||||
2.889998135567012#34
|
||||
3.062497913837788#35
|
||||
3.2399976825718255#36
|
||||
3.4224974417691243#37
|
||||
3.6099971914296844#38
|
||||
3.802496931553506#39
|
||||
3.999996662140589#40
|
||||
4.202496871948824#41
|
||||
4.4099965953833475#42
|
||||
4.622496309281132#43
|
||||
4.839996013642178#44
|
||||
5.062495708466486#45
|
||||
5.2899953937540545#46
|
||||
5.522495069504885#47
|
||||
5.759994735718976#48
|
||||
6.002494392396329#49
|
||||
6.2499940395369435#50
|
||||
6.502493677140819#51
|
||||
6.759993305207956#52
|
||||
7.022492923738355#53
|
||||
7.289992532732015#54
|
||||
7.562492132188936#55
|
||||
7.839991722109119#56
|
||||
8.122491302492563#57
|
||||
8.409990873339268#58
|
||||
8.702490434649235#59
|
||||
8.999989986422463#60
|
||||
9.302489528658953#61
|
||||
9.609989061358704#62
|
||||
9.922488584521716#63
|
||||
10.23998809814799#64
|
||||
10.562487602237525#65
|
||||
10.889987096790321#66
|
||||
11.222486581806379#67
|
||||
11.559986057285698#68
|
||||
11.902485523228279#69
|
||||
12.249984979634121#70
|
||||
12.602484426503224#71
|
||||
12.959983863835589#72
|
||||
13.322483291631215#73
|
||||
13.689982709890103#74
|
||||
14.062482118612252#75
|
||||
14.439981517797662#76
|
||||
14.822480907446334#77
|
||||
15.209980287558267#78
|
||||
15.602479658133461#79
|
||||
15.999979019171917#80
|
||||
16.402478370673634#81
|
||||
16.809979667669722#82
|
||||
17.222481002812856#83
|
||||
17.639982376103035#84
|
||||
18.06248378754026#85
|
||||
18.48998523712453#86
|
||||
18.922486724855844#87
|
||||
19.359988250734204#88
|
||||
19.80248981475961#89
|
||||
20.249991416932062#90
|
||||
20.70249305725156#91
|
||||
21.1599947357181#92
|
||||
21.62249645233169#93
|
||||
22.08999820709232#94
|
||||
22.5625#95
|
||||
23.040001831054724#96
|
||||
23.522503700256493#97
|
||||
24.010005607605308#98
|
||||
24.502507553101168#99
|
||||
@@ -0,0 +1,7 @@
|
||||
4#2#6#0
|
||||
0#2#8#1
|
||||
3#8#2#2
|
||||
0#7#0#3
|
||||
5#5#2#4
|
||||
9#0#0#5
|
||||
3#3#6#6
|
||||
@@ -0,0 +1,100 @@
|
||||
0.0#0
|
||||
1.2500000558793553E-4#1
|
||||
0.0010000000447034842#2
|
||||
0.0033750004023313683#3
|
||||
0.008000000357627874#4
|
||||
0.015625#5
|
||||
0.027000003218650946#6
|
||||
0.04287500876188338#7
|
||||
0.06400001716613923#8
|
||||
0.09112502896786043#9
|
||||
0.1250000447034889#10
|
||||
0.1663750649094666#11
|
||||
0.21600009012223542#12
|
||||
0.2746251208782373#13
|
||||
0.34300015771391423#14
|
||||
0.4218752011657081#15
|
||||
0.5120002517700608#16
|
||||
0.6141253100634143#17
|
||||
0.7290003765822105#18
|
||||
0.8573754518628914#19
|
||||
1.0000003576279113#20
|
||||
1.1576252365708513#21
|
||||
1.3310000865459461#22
|
||||
1.5208749054074306#23
|
||||
1.7279996910095399#24
|
||||
1.9531244412065085#25
|
||||
2.1969991538525715#26
|
||||
2.4603738268019635#27
|
||||
2.743998457908919#28
|
||||
3.048623045027674#29
|
||||
3.374997586012462#30
|
||||
3.723872078717519#31
|
||||
4.095996520997079#32
|
||||
4.492120910705377#33
|
||||
4.9129952456966475#34
|
||||
5.359369523825126#35
|
||||
5.8319937429450475#36
|
||||
6.331617900910646#37
|
||||
6.858991995576157#38
|
||||
7.414866024795816#39
|
||||
7.999989986423856#40
|
||||
8.615115381244424#41
|
||||
9.260989275459615#42
|
||||
9.938363097434028#43
|
||||
10.647986845021897#44
|
||||
11.390610516077459#45
|
||||
12.166984108454947#46
|
||||
12.977857620008598#47
|
||||
13.823981048592644#48
|
||||
14.706104392061324#49
|
||||
15.624977648268867#50
|
||||
16.581350815069513#51
|
||||
17.575973890317496#52
|
||||
18.609596871867048#53
|
||||
19.682969757572405#54
|
||||
20.796842545287802#55
|
||||
21.951965232867476#56
|
||||
23.149087818165658#57
|
||||
24.388960299036587#58
|
||||
25.672332673334495#59
|
||||
26.999954938913618#60
|
||||
28.37257709362819#61
|
||||
29.790949135332447#62
|
||||
31.25582106188062#63
|
||||
32.76794287112695#64
|
||||
34.32806456092567#65
|
||||
35.93693612913101#66
|
||||
37.59530757359721#67
|
||||
39.303928892178504#68
|
||||
41.06355008272912#69
|
||||
42.87492114310331#70
|
||||
44.73879207115529#71
|
||||
46.65591286473931#72
|
||||
48.627033521709585#73
|
||||
50.65290403992037#74
|
||||
52.73427441722589#75
|
||||
54.87189465148038#76
|
||||
57.06651474053808#77
|
||||
59.31888468225323#78
|
||||
61.629754474480045#79
|
||||
63.99987411507277#80
|
||||
66.42999360188564#81
|
||||
68.9208749562066#82
|
||||
71.47325674254265#83
|
||||
74.08788896947685#84
|
||||
76.76552164559234#85
|
||||
79.50690477947222#86
|
||||
82.31278837969957#87
|
||||
85.18392245485751#88
|
||||
88.12105701352914#89
|
||||
91.12494206429756#90
|
||||
94.19632761574586#91
|
||||
97.33596367645715#92
|
||||
100.54460025501454#93
|
||||
103.82298736000112#94
|
||||
107.171875#95
|
||||
110.59201318359428#96
|
||||
114.08415191936705#97
|
||||
117.64904121590142#98
|
||||
121.2874310817805#99
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package com.android.stockapp.application;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import androidx.appcompat.app.AppCompatDelegate;
|
||||
|
||||
import com.android.stockapp.common.data.Constants;
|
||||
import com.android.stockapp.ui.base.BaseApp;
|
||||
|
||||
|
||||
public class MyApplication extends BaseApp {
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
initDayNight();
|
||||
}
|
||||
|
||||
public static MyApplication getApplication() {
|
||||
return (MyApplication) getApp();
|
||||
}
|
||||
|
||||
public void initDayNight(){
|
||||
//初始化夜间模式
|
||||
SharedPreferences sp = getSharedPreferences(Constants.SP_FILE,Context.MODE_PRIVATE);
|
||||
if(sp.getBoolean(Constants.DAY_NIGHT_MODE,false)){
|
||||
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
|
||||
}else {
|
||||
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
|
||||
}
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
package com.android.stockapp.common.adapter;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentStatePagerAdapter;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 装载Fragment的通用适配器
|
||||
*/
|
||||
public class SimpleFragmentPagerAdapter extends FragmentStatePagerAdapter {
|
||||
private List<Fragment> mFragments;
|
||||
private List<String> mTitles;
|
||||
|
||||
public SimpleFragmentPagerAdapter(FragmentManager fm, Fragment[] fragments) {
|
||||
super(fm);
|
||||
mFragments = Arrays.asList(fragments);
|
||||
}
|
||||
|
||||
public SimpleFragmentPagerAdapter(FragmentManager fm, List<Fragment> fragments) {
|
||||
super(fm);
|
||||
mFragments = fragments;
|
||||
}
|
||||
|
||||
public SimpleFragmentPagerAdapter(FragmentManager fm, Fragment[] fragments, String[] titles) {
|
||||
this(fm, fragments);
|
||||
mTitles = Arrays.asList(titles);
|
||||
}
|
||||
|
||||
public SimpleFragmentPagerAdapter(FragmentManager fm, List<Fragment> fragments, List<String> titles) {
|
||||
this(fm, fragments);
|
||||
mTitles = titles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fragment getItem(int position) {
|
||||
return mFragments.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return mFragments.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getPageTitle(int position) {
|
||||
if (mTitles != null && mTitles.size() > 0) {
|
||||
return mTitles.get(position);
|
||||
}
|
||||
return super.getPageTitle(position);
|
||||
}
|
||||
|
||||
}
|
||||
+16
File diff suppressed because one or more lines are too long
+9
@@ -0,0 +1,9 @@
|
||||
package com.android.stockapp.common.data;
|
||||
|
||||
/**
|
||||
* 公共常量
|
||||
*/
|
||||
public class Constants {
|
||||
public static String SP_FILE = "dayNightModeFile";//SharedPreferences存储文件名
|
||||
public static String DAY_NIGHT_MODE = "dayNightMode";//夜间模式key
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.android.stockapp.common.viewpager;
|
||||
|
||||
import android.content.Context;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
public class NoTouchScrollViewpager extends ViewPager{
|
||||
public NoTouchScrollViewpager(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public NoTouchScrollViewpager(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent ev) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent arg0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.android.stockapp.ui.base;
|
||||
|
||||
import android.app.Application;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
/**
|
||||
* Description:应用程序(基类)
|
||||
*/
|
||||
public class BaseApp extends Application {
|
||||
|
||||
public static BaseApp mContext = null; //获取到主线程的上下文
|
||||
public static Handler mAppHandler = null; //获取到主线程的handler
|
||||
public static Looper mAppLooper = null; //获取到主线程的looper
|
||||
public static Thread mMainThead = null; //获取到主线程
|
||||
public static int mMainTheadId; //获取到主线程的id
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
mContext = this;
|
||||
mAppHandler = new Handler();
|
||||
mAppLooper = getMainLooper();
|
||||
mMainThead = Thread.currentThread();
|
||||
mMainTheadId = android.os.Process.myTid();//主線程id
|
||||
}
|
||||
|
||||
public static BaseApp getApp() {
|
||||
return mContext;
|
||||
}
|
||||
|
||||
public static Handler getAppHandler() {
|
||||
return mAppHandler;
|
||||
}
|
||||
|
||||
public static Looper getAppLooper() {
|
||||
return mAppLooper;
|
||||
}
|
||||
|
||||
public static Thread getMainThread() {
|
||||
return mMainThead;
|
||||
}
|
||||
|
||||
public static int getMainThreadId() {
|
||||
return mMainTheadId;
|
||||
}
|
||||
}
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
package com.android.stockapp.ui.base;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Toast;
|
||||
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
public abstract class BaseFragment extends Fragment {
|
||||
public Activity mAct;
|
||||
private View view;
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
mAct = activity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
view = inflater.inflate(setLayoutId(), container, false);
|
||||
ButterKnife.bind(this,view);
|
||||
initBase(view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
}
|
||||
|
||||
protected abstract int setLayoutId();
|
||||
|
||||
protected abstract void initBase(View view);
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetach() {
|
||||
super.onDetach();
|
||||
}
|
||||
|
||||
protected void startToActivity(Class<?> cls){
|
||||
Intent intent = new Intent(mAct, cls);
|
||||
mAct.startActivity(intent);
|
||||
}
|
||||
|
||||
Toast toast;
|
||||
public void showToast(String string) {
|
||||
if(toast == null){
|
||||
toast = Toast.makeText(mAct, string, Toast.LENGTH_SHORT);
|
||||
}else{
|
||||
toast.setText(string);
|
||||
}
|
||||
toast.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
if(toast != null){
|
||||
toast.cancel();
|
||||
}
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
package com.android.stockapp.ui.main;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.application.MyApplication;
|
||||
import com.android.stockapp.ui.market.activity.StockDetailActivity;
|
||||
import com.android.stockapp.ui.mpchartexample.notimportant.MPMainActivity;
|
||||
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
ButterKnife.bind(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostResume() {
|
||||
super.onPostResume();
|
||||
MyApplication.getApplication().initDayNight();
|
||||
}
|
||||
|
||||
@OnClick({R.id.btn_test, R.id.btn_mp})
|
||||
public void onViewClicked(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.btn_test:
|
||||
startActivity(new Intent(MainActivity.this, StockDetailActivity.class));
|
||||
break;
|
||||
case R.id.btn_mp:
|
||||
startActivity(new Intent(MainActivity.this, MPMainActivity.class));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
package com.android.stockapp.ui.market.activity;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.app.AppCompatDelegate;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.common.adapter.SimpleFragmentPagerAdapter;
|
||||
import com.android.stockapp.common.data.Constants;
|
||||
import com.android.stockapp.common.viewpager.NoTouchScrollViewpager;
|
||||
import com.android.stockapp.ui.market.fragment.ChartFiveDayFragment;
|
||||
import com.android.stockapp.ui.market.fragment.ChartKLineFragment;
|
||||
import com.android.stockapp.ui.market.fragment.ChartOneDayFragment;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
/**
|
||||
* 股票详情页
|
||||
*/
|
||||
public class StockDetailActivity extends AppCompatActivity {
|
||||
|
||||
@BindView(R.id.tab)
|
||||
TabLayout tabLayout;
|
||||
@BindView(R.id.view_pager)
|
||||
NoTouchScrollViewpager viewPager;
|
||||
@BindView(R.id.toolbar)
|
||||
Toolbar toolbar;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_stock_detail);
|
||||
ButterKnife.bind(this);
|
||||
|
||||
|
||||
toolbar.setTitle("图表");
|
||||
toolbar.inflateMenu(R.menu.menu_right);
|
||||
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.item_model:
|
||||
SharedPreferences sp = getSharedPreferences(Constants.SP_FILE,
|
||||
Context.MODE_PRIVATE);
|
||||
if(!sp.getBoolean(Constants.DAY_NIGHT_MODE,false)){
|
||||
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
|
||||
sp.edit().putBoolean(Constants.DAY_NIGHT_MODE,true).apply();
|
||||
Toast.makeText(StockDetailActivity.this, "夜间模式!", Toast.LENGTH_SHORT).show();
|
||||
}else {
|
||||
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
|
||||
sp.edit().putBoolean(Constants.DAY_NIGHT_MODE,false).apply();
|
||||
Toast.makeText(StockDetailActivity.this, "白天模式!", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
recreate();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
Fragment[] fragments = {ChartOneDayFragment.newInstance(false), ChartFiveDayFragment.newInstance(false),
|
||||
ChartKLineFragment.newInstance(1, false), ChartKLineFragment.newInstance(7, false),
|
||||
ChartKLineFragment.newInstance(30, false)};
|
||||
String[] titles = {"分时", "五日", "日K", "周K", "月K"};
|
||||
viewPager.setOffscreenPageLimit(fragments.length);
|
||||
viewPager.setAdapter(new SimpleFragmentPagerAdapter(getSupportFragmentManager(), fragments, titles));
|
||||
tabLayout.setupWithViewPager(viewPager);
|
||||
}
|
||||
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
package com.android.stockapp.ui.market.activity;
|
||||
|
||||
import android.os.Bundle;
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.common.adapter.SimpleFragmentPagerAdapter;
|
||||
import com.android.stockapp.common.viewpager.NoTouchScrollViewpager;
|
||||
import com.android.stockapp.ui.market.fragment.ChartFiveDayFragment;
|
||||
import com.android.stockapp.ui.market.fragment.ChartKLineFragment;
|
||||
import com.android.stockapp.ui.market.fragment.ChartOneDayFragment;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
/**
|
||||
* 股票详情页-横屏
|
||||
*/
|
||||
public class StockDetailLandActivity extends AppCompatActivity {
|
||||
|
||||
@BindView(R.id.tab)
|
||||
TabLayout tabLayout;
|
||||
@BindView(R.id.view_pager)
|
||||
NoTouchScrollViewpager viewPager;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_stock_detail_land);
|
||||
ButterKnife.bind(this);
|
||||
|
||||
Fragment[] fragments = {ChartOneDayFragment.newInstance(true), ChartFiveDayFragment.newInstance(true),
|
||||
ChartKLineFragment.newInstance(1,true), ChartKLineFragment.newInstance(7,true),
|
||||
ChartKLineFragment.newInstance(30,true)};
|
||||
String[] titles = {"分时", "五日", "日K", "周K", "月K"};
|
||||
viewPager.setOffscreenPageLimit(fragments.length);
|
||||
viewPager.setAdapter(new SimpleFragmentPagerAdapter(getSupportFragmentManager(), fragments, titles));
|
||||
tabLayout.setupWithViewPager(viewPager);
|
||||
}
|
||||
}
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
package com.android.stockapp.ui.market.fragment;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.Nullable;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.common.data.ChartData;
|
||||
import com.android.stockapp.ui.base.BaseFragment;
|
||||
import com.android.stockapp.ui.market.activity.StockDetailLandActivity;
|
||||
import com.github.mikephil.charting.stockChart.charts.CoupleChartGestureListener;
|
||||
import com.github.mikephil.charting.stockChart.dataManage.TimeDataManage;
|
||||
import com.github.mikephil.charting.stockChart.FiveDayChart;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
|
||||
/**
|
||||
* 分时页
|
||||
*/
|
||||
public class ChartFiveDayFragment extends BaseFragment {
|
||||
|
||||
@BindView(R.id.chart)
|
||||
FiveDayChart chart;
|
||||
Unbinder unbinder;
|
||||
|
||||
private boolean land;//是否横屏
|
||||
private TimeDataManage kTimeData = new TimeDataManage();
|
||||
private JSONObject object;
|
||||
|
||||
public static ChartFiveDayFragment newInstance(boolean land) {
|
||||
ChartFiveDayFragment fragment = new ChartFiveDayFragment();
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putBoolean("landscape", land);
|
||||
fragment.setArguments(bundle);
|
||||
return fragment;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setLayoutId() {
|
||||
return R.layout.fragment_five_day;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initBase(View view) {
|
||||
|
||||
chart.initChart(land);
|
||||
|
||||
//测试数据
|
||||
try {
|
||||
object = new JSONObject(ChartData.FiveTIMEDATA);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
//上证指数代码000001.IDX.SH
|
||||
kTimeData.parseTimeData(object,"000001.IDX.SH",0);
|
||||
chart.setDataToChart(kTimeData);
|
||||
|
||||
//非横屏页单击转横屏页
|
||||
if (!land) {
|
||||
chart.getGestureListenerLine().setCoupleClick(new CoupleChartGestureListener.CoupleClick() {
|
||||
@Override
|
||||
public void singleClickListener() {
|
||||
Intent intent = new Intent(getActivity(), StockDetailLandActivity.class);
|
||||
getActivity().startActivity(intent);
|
||||
}
|
||||
});
|
||||
chart.getGestureListenerBar().setCoupleClick(new CoupleChartGestureListener.CoupleClick() {
|
||||
@Override
|
||||
public void singleClickListener() {
|
||||
Intent intent = new Intent(getActivity(), StockDetailLandActivity.class);
|
||||
getActivity().startActivity(intent);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
land = getArguments().getBoolean("landscape");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
// TODO: inflate a fragment view
|
||||
View rootView = super.onCreateView(inflater, container, savedInstanceState);
|
||||
unbinder = ButterKnife.bind(this, rootView);
|
||||
return rootView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
}
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
package com.android.stockapp.ui.market.fragment;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.Nullable;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.common.data.ChartData;
|
||||
import com.android.stockapp.ui.base.BaseFragment;
|
||||
import com.android.stockapp.ui.market.activity.StockDetailLandActivity;
|
||||
import com.github.mikephil.charting.stockChart.charts.CoupleChartGestureListener;
|
||||
import com.github.mikephil.charting.stockChart.dataManage.KLineDataManage;
|
||||
import com.github.mikephil.charting.stockChart.KLineChart;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
|
||||
/**
|
||||
* K线
|
||||
*/
|
||||
public class ChartKLineFragment extends BaseFragment {
|
||||
|
||||
|
||||
@BindView(R.id.combinedchart)
|
||||
KLineChart combinedchart;
|
||||
Unbinder unbinder;
|
||||
|
||||
private int mType;//日K:1;周K:7;月K:30
|
||||
private boolean land;//是否横屏
|
||||
private KLineDataManage kLineData;
|
||||
private JSONObject object;
|
||||
private int indexType = 1;
|
||||
|
||||
public static ChartKLineFragment newInstance(int type,boolean land){
|
||||
ChartKLineFragment fragment = new ChartKLineFragment();
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt("type", type);
|
||||
bundle.putBoolean("landscape",land);
|
||||
fragment.setArguments(bundle);
|
||||
return fragment;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int setLayoutId() {
|
||||
return R.layout.fragment_kline;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initBase(View view) {
|
||||
kLineData = new KLineDataManage(getActivity());
|
||||
combinedchart.initChart(land);
|
||||
try {
|
||||
if(mType == 1){
|
||||
object = new JSONObject(ChartData.KLINEDATA);
|
||||
}else if(mType == 7){
|
||||
object = new JSONObject(ChartData.KLINEWEEKDATA);
|
||||
}else if(mType == 30){
|
||||
object = new JSONObject(ChartData.KLINEMONTHDATA);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
//上证指数代码000001.IDX.SH
|
||||
kLineData.parseKlineData(object,"000001.IDX.SH",land);
|
||||
combinedchart.setDataToChart(kLineData);
|
||||
|
||||
combinedchart.getGestureListenerCandle().setCoupleClick(new CoupleChartGestureListener.CoupleClick() {
|
||||
@Override
|
||||
public void singleClickListener() {
|
||||
if(!land) {
|
||||
Intent intent = new Intent(getActivity(), StockDetailLandActivity.class);
|
||||
getActivity().startActivity(intent);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
combinedchart.getGestureListenerBar().setCoupleClick(new CoupleChartGestureListener.CoupleClick() {
|
||||
@Override
|
||||
public void singleClickListener() {
|
||||
if(land) {
|
||||
loadIndexData(indexType < 5 ? ++indexType : 1);
|
||||
}else {
|
||||
Intent intent = new Intent(getActivity(), StockDetailLandActivity.class);
|
||||
getActivity().startActivity(intent);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
mType = getArguments().getInt("type");
|
||||
land = getArguments().getBoolean("landscape");
|
||||
}
|
||||
|
||||
private void loadIndexData(int type) {
|
||||
indexType = type;
|
||||
switch (indexType) {
|
||||
case 1://成交量
|
||||
combinedchart.doBarChartSwitch(indexType);
|
||||
break;
|
||||
case 2://请求MACD
|
||||
kLineData.initMACD();
|
||||
combinedchart.doBarChartSwitch(indexType);
|
||||
break;
|
||||
case 3://请求KDJ
|
||||
kLineData.initKDJ();
|
||||
combinedchart.doBarChartSwitch(indexType);
|
||||
break;
|
||||
case 4://请求BOLL
|
||||
kLineData.initBOLL();
|
||||
combinedchart.doBarChartSwitch(indexType);
|
||||
break;
|
||||
case 5://请求RSI
|
||||
kLineData.initRSI();
|
||||
combinedchart.doBarChartSwitch(indexType);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
// TODO: inflate a fragment view
|
||||
View rootView = super.onCreateView(inflater, container, savedInstanceState);
|
||||
unbinder = ButterKnife.bind(this, rootView);
|
||||
return rootView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
}
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
package com.android.stockapp.ui.market.fragment;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.Nullable;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.common.data.ChartData;
|
||||
import com.android.stockapp.ui.base.BaseFragment;
|
||||
import com.android.stockapp.ui.market.activity.StockDetailLandActivity;
|
||||
import com.github.mikephil.charting.stockChart.charts.CoupleChartGestureListener;
|
||||
import com.github.mikephil.charting.stockChart.dataManage.TimeDataManage;
|
||||
import com.github.mikephil.charting.stockChart.OneDayChart;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
|
||||
/**
|
||||
* 分时页
|
||||
*/
|
||||
public class ChartOneDayFragment extends BaseFragment {
|
||||
|
||||
@BindView(R.id.chart)
|
||||
OneDayChart chart;
|
||||
Unbinder unbinder;
|
||||
|
||||
private boolean land;//是否横屏
|
||||
private TimeDataManage kTimeData = new TimeDataManage();
|
||||
private JSONObject object;
|
||||
|
||||
public static ChartOneDayFragment newInstance(boolean land) {
|
||||
ChartOneDayFragment fragment = new ChartOneDayFragment();
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putBoolean("landscape", land);
|
||||
fragment.setArguments(bundle);
|
||||
return fragment;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setLayoutId() {
|
||||
return R.layout.fragment_one_day;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initBase(View view) {
|
||||
//初始化
|
||||
chart.initChart(land);
|
||||
//测试数据
|
||||
try {
|
||||
object = new JSONObject(ChartData.TIMEDATA);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
//上证指数代码000001.IDX.SH
|
||||
kTimeData.parseTimeData(object,"000001.IDX.SH",0);
|
||||
chart.setDataToChart(kTimeData);
|
||||
|
||||
//非横屏页单击转横屏页
|
||||
if (!land) {
|
||||
chart.getGestureListenerLine().setCoupleClick(new CoupleChartGestureListener.CoupleClick() {
|
||||
@Override
|
||||
public void singleClickListener() {
|
||||
Intent intent = new Intent(getActivity(), StockDetailLandActivity.class);
|
||||
getActivity().startActivity(intent);
|
||||
}
|
||||
});
|
||||
chart.getGestureListenerBar().setCoupleClick(new CoupleChartGestureListener.CoupleClick() {
|
||||
@Override
|
||||
public void singleClickListener() {
|
||||
Intent intent = new Intent(getActivity(), StockDetailLandActivity.class);
|
||||
getActivity().startActivity(intent);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
land = getArguments().getBoolean("landscape");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
// TODO: inflate a fragment view
|
||||
View rootView = super.onCreateView(inflater, container, savedInstanceState);
|
||||
unbinder = ButterKnife.bind(this, rootView);
|
||||
return rootView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
}
|
||||
+215
@@ -0,0 +1,215 @@
|
||||
|
||||
package com.android.stockapp.ui.mpchartexample;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.SeekBar.OnSeekBarChangeListener;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.ui.mpchartexample.notimportant.DemoBase;
|
||||
import com.github.mikephil.charting.charts.BarChart;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.XAxis.XAxisPosition;
|
||||
import com.github.mikephil.charting.data.BarData;
|
||||
import com.github.mikephil.charting.data.BarDataSet;
|
||||
import com.github.mikephil.charting.data.BarEntry;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IBarDataSet;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IDataSet;
|
||||
import com.github.mikephil.charting.utils.ColorTemplate;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class AnotherBarActivity extends DemoBase implements OnSeekBarChangeListener {
|
||||
|
||||
private BarChart chart;
|
||||
private SeekBar seekBarX, seekBarY;
|
||||
private TextView tvX, tvY;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_barchart);
|
||||
|
||||
setTitle("AnotherBarActivity");
|
||||
|
||||
tvX = findViewById(R.id.tvXMax);
|
||||
tvY = findViewById(R.id.tvYMax);
|
||||
|
||||
seekBarX = findViewById(R.id.seekBar1);
|
||||
seekBarX.setOnSeekBarChangeListener(this);
|
||||
|
||||
seekBarY = findViewById(R.id.seekBar2);
|
||||
seekBarY.setOnSeekBarChangeListener(this);
|
||||
|
||||
chart = findViewById(R.id.chart1);
|
||||
|
||||
chart.getDescription().setEnabled(false);
|
||||
|
||||
// if more than 60 entries are displayed in the chart, no values will be
|
||||
// drawn
|
||||
chart.setMaxVisibleValueCount(60);
|
||||
|
||||
// scaling can now only be done on x- and y-axis separately
|
||||
chart.setPinchZoom(false);
|
||||
|
||||
chart.setDrawBarShadow(false);
|
||||
chart.setDrawGridBackground(false);
|
||||
|
||||
XAxis xAxis = chart.getXAxis();
|
||||
xAxis.setPosition(XAxisPosition.BOTTOM);
|
||||
xAxis.setDrawGridLines(false);
|
||||
|
||||
chart.getAxisLeft().setDrawGridLines(false);
|
||||
|
||||
// setting data
|
||||
seekBarX.setProgress(10);
|
||||
seekBarY.setProgress(100);
|
||||
|
||||
// add a nice and smooth animation
|
||||
chart.animateY(1500);
|
||||
|
||||
chart.getLegend().setEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
|
||||
tvX.setText(String.valueOf(seekBarX.getProgress()));
|
||||
tvY.setText(String.valueOf(seekBarY.getProgress()));
|
||||
|
||||
ArrayList<BarEntry> values = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < seekBarX.getProgress(); i++) {
|
||||
float multi = (seekBarY.getProgress() + 1);
|
||||
float val = (float) (Math.random() * multi) + multi / 3;
|
||||
values.add(new BarEntry(i, val));
|
||||
}
|
||||
|
||||
BarDataSet set1;
|
||||
|
||||
if (chart.getData() != null &&
|
||||
chart.getData().getDataSetCount() > 0) {
|
||||
set1 = (BarDataSet) chart.getData().getDataSetByIndex(0);
|
||||
set1.setValues(values);
|
||||
chart.getData().notifyDataChanged();
|
||||
chart.notifyDataSetChanged();
|
||||
} else {
|
||||
set1 = new BarDataSet(values, "Data Set");
|
||||
set1.setColors(ColorTemplate.VORDIPLOM_COLORS);
|
||||
set1.setDrawValues(false);
|
||||
|
||||
ArrayList<IBarDataSet> dataSets = new ArrayList<>();
|
||||
dataSets.add(set1);
|
||||
|
||||
BarData data = new BarData(dataSets);
|
||||
chart.setData(data);
|
||||
chart.setFitBars(true);
|
||||
}
|
||||
|
||||
chart.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.bar, menu);
|
||||
menu.removeItem(R.id.actionToggleIcons);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.viewGithub: {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/AnotherBarActivity.java"));
|
||||
startActivity(i);
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleValues: {
|
||||
|
||||
for (IDataSet set : chart.getData().getDataSets())
|
||||
set.setDrawValues(!set.isDrawValuesEnabled());
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
/*
|
||||
case R.id.actionToggleIcons: { break; }
|
||||
*/
|
||||
case R.id.actionToggleHighlight: {
|
||||
|
||||
if(chart.getData() != null) {
|
||||
chart.getData().setHighlightEnabled(!chart.getData().isHighlightEnabled());
|
||||
chart.invalidate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case R.id.actionTogglePinch: {
|
||||
if (chart.isPinchZoomEnabled())
|
||||
chart.setPinchZoom(false);
|
||||
else
|
||||
chart.setPinchZoom(true);
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleAutoScaleMinMax: {
|
||||
chart.setAutoScaleMinMaxEnabled(!chart.isAutoScaleMinMaxEnabled());
|
||||
chart.notifyDataSetChanged();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleBarBorders: {
|
||||
for (IBarDataSet set : chart.getData().getDataSets())
|
||||
((BarDataSet)set).setBarBorderWidth(set.getBarBorderWidth() == 1.f ? 0.f : 1.f);
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.animateX: {
|
||||
chart.animateX(2000);
|
||||
break;
|
||||
}
|
||||
case R.id.animateY: {
|
||||
chart.animateY(2000);
|
||||
break;
|
||||
}
|
||||
case R.id.animateXY: {
|
||||
|
||||
chart.animateXY(2000, 2000);
|
||||
break;
|
||||
}
|
||||
case R.id.actionSave: {
|
||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
|
||||
saveToGallery();
|
||||
} else {
|
||||
requestStoragePermission(chart);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveToGallery() {
|
||||
saveToGallery(chart, "AnotherBarActivity");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {}
|
||||
}
|
||||
+334
@@ -0,0 +1,334 @@
|
||||
package com.android.stockapp.ui.mpchartexample;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.RectF;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.SeekBar.OnSeekBarChangeListener;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.ui.mpchartexample.custom.DayAxisValueFormatter;
|
||||
import com.android.stockapp.ui.mpchartexample.custom.MyValueFormatter;
|
||||
import com.android.stockapp.ui.mpchartexample.custom.XYMarkerView;
|
||||
import com.android.stockapp.ui.mpchartexample.notimportant.DemoBase;
|
||||
import com.github.mikephil.charting.charts.BarChart;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.components.Legend.LegendForm;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.XAxis.XAxisPosition;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
import com.github.mikephil.charting.components.YAxis.AxisDependency;
|
||||
import com.github.mikephil.charting.components.YAxis.YAxisLabelPosition;
|
||||
import com.github.mikephil.charting.data.BarData;
|
||||
import com.github.mikephil.charting.data.BarDataSet;
|
||||
import com.github.mikephil.charting.data.BarEntry;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IBarDataSet;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IDataSet;
|
||||
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
|
||||
import com.github.mikephil.charting.model.GradientColor;
|
||||
import com.github.mikephil.charting.utils.MPPointF;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class BarChartActivity extends DemoBase implements OnSeekBarChangeListener,
|
||||
OnChartValueSelectedListener {
|
||||
|
||||
private BarChart chart;
|
||||
private SeekBar seekBarX, seekBarY;
|
||||
private TextView tvX, tvY;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_barchart);
|
||||
|
||||
setTitle("BarChartActivity");
|
||||
|
||||
tvX = findViewById(R.id.tvXMax);
|
||||
tvY = findViewById(R.id.tvYMax);
|
||||
|
||||
seekBarX = findViewById(R.id.seekBar1);
|
||||
seekBarY = findViewById(R.id.seekBar2);
|
||||
|
||||
seekBarY.setOnSeekBarChangeListener(this);
|
||||
seekBarX.setOnSeekBarChangeListener(this);
|
||||
|
||||
chart = findViewById(R.id.chart1);
|
||||
chart.setOnChartValueSelectedListener(this);
|
||||
|
||||
chart.setDrawBarShadow(false);
|
||||
chart.setDrawValueAboveBar(true);
|
||||
|
||||
chart.getDescription().setEnabled(false);
|
||||
|
||||
// if more than 60 entries are displayed in the chart, no values will be
|
||||
// drawn
|
||||
chart.setMaxVisibleValueCount(60);
|
||||
|
||||
// scaling can now only be done on x- and y-axis separately
|
||||
chart.setPinchZoom(false);
|
||||
|
||||
chart.setDrawGridBackground(false);
|
||||
// chart.setDrawYLabels(false);
|
||||
|
||||
ValueFormatter xAxisFormatter = new DayAxisValueFormatter(chart);
|
||||
|
||||
XAxis xAxis = chart.getXAxis();
|
||||
xAxis.setPosition(XAxisPosition.BOTTOM);
|
||||
xAxis.setTypeface(tfLight);
|
||||
xAxis.setDrawGridLines(false);
|
||||
xAxis.setGranularity(1f); // only intervals of 1 day
|
||||
xAxis.setLabelCount(7);
|
||||
xAxis.setValueFormatter(xAxisFormatter);
|
||||
|
||||
ValueFormatter custom = new MyValueFormatter("$");
|
||||
|
||||
YAxis leftAxis = chart.getAxisLeft();
|
||||
leftAxis.setTypeface(tfLight);
|
||||
leftAxis.setLabelCount(8, false);
|
||||
leftAxis.setValueFormatter(custom);
|
||||
leftAxis.setPosition(YAxisLabelPosition.OUTSIDE_CHART);
|
||||
leftAxis.setSpaceTop(15f);
|
||||
leftAxis.setAxisMinimum(0f); // this replaces setStartAtZero(true)
|
||||
|
||||
YAxis rightAxis = chart.getAxisRight();
|
||||
rightAxis.setDrawGridLines(false);
|
||||
rightAxis.setTypeface(tfLight);
|
||||
rightAxis.setLabelCount(8, false);
|
||||
rightAxis.setValueFormatter(custom);
|
||||
rightAxis.setSpaceTop(15f);
|
||||
rightAxis.setAxisMinimum(0f); // this replaces setStartAtZero(true)
|
||||
|
||||
Legend l = chart.getLegend();
|
||||
l.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);
|
||||
l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.LEFT);
|
||||
l.setOrientation(Legend.LegendOrientation.HORIZONTAL);
|
||||
l.setDrawInside(false);
|
||||
l.setForm(LegendForm.SQUARE);
|
||||
l.setFormSize(9f);
|
||||
l.setTextSize(11f);
|
||||
l.setXEntrySpace(4f);
|
||||
|
||||
XYMarkerView mv = new XYMarkerView(this, xAxisFormatter);
|
||||
mv.setChartView(chart); // For bounds control
|
||||
chart.setMarker(mv); // Set the marker to the chart
|
||||
|
||||
// setting data
|
||||
seekBarY.setProgress(50);
|
||||
seekBarX.setProgress(12);
|
||||
|
||||
// chart.setDrawLegend(false);
|
||||
}
|
||||
|
||||
private void setData(int count, float range) {
|
||||
|
||||
float start = 1f;
|
||||
|
||||
ArrayList<BarEntry> values = new ArrayList<>();
|
||||
|
||||
for (int i = (int) start; i < start + count; i++) {
|
||||
float val = (float) (Math.random() * (range + 1));
|
||||
|
||||
if (Math.random() * 100 < 25) {
|
||||
values.add(new BarEntry(i, val, getResources().getDrawable(R.drawable.star)));
|
||||
} else {
|
||||
values.add(new BarEntry(i, val));
|
||||
}
|
||||
}
|
||||
|
||||
BarDataSet set1;
|
||||
|
||||
if (chart.getData() != null &&
|
||||
chart.getData().getDataSetCount() > 0) {
|
||||
set1 = (BarDataSet) chart.getData().getDataSetByIndex(0);
|
||||
set1.setValues(values);
|
||||
chart.getData().notifyDataChanged();
|
||||
chart.notifyDataSetChanged();
|
||||
|
||||
} else {
|
||||
set1 = new BarDataSet(values, "The year 2017");
|
||||
|
||||
set1.setDrawIcons(false);
|
||||
|
||||
// set1.setColors(ColorTemplate.MATERIAL_COLORS);
|
||||
|
||||
/*int startColor = ContextCompat.getColor(this, android.R.color.holo_blue_dark);
|
||||
int endColor = ContextCompat.getColor(this, android.R.color.holo_blue_bright);
|
||||
set1.setGradientColor(startColor, endColor);*/
|
||||
|
||||
int startColor1 = ContextCompat.getColor(this, android.R.color.holo_orange_light);
|
||||
int startColor2 = ContextCompat.getColor(this, android.R.color.holo_blue_light);
|
||||
int startColor3 = ContextCompat.getColor(this, android.R.color.holo_orange_light);
|
||||
int startColor4 = ContextCompat.getColor(this, android.R.color.holo_green_light);
|
||||
int startColor5 = ContextCompat.getColor(this, android.R.color.holo_red_light);
|
||||
int endColor1 = ContextCompat.getColor(this, android.R.color.holo_blue_dark);
|
||||
int endColor2 = ContextCompat.getColor(this, android.R.color.holo_purple);
|
||||
int endColor3 = ContextCompat.getColor(this, android.R.color.holo_green_dark);
|
||||
int endColor4 = ContextCompat.getColor(this, android.R.color.holo_red_dark);
|
||||
int endColor5 = ContextCompat.getColor(this, android.R.color.holo_orange_dark);
|
||||
|
||||
List<GradientColor> gradientColors = new ArrayList<>();
|
||||
gradientColors.add(new GradientColor(startColor1, endColor1));
|
||||
gradientColors.add(new GradientColor(startColor2, endColor2));
|
||||
gradientColors.add(new GradientColor(startColor3, endColor3));
|
||||
gradientColors.add(new GradientColor(startColor4, endColor4));
|
||||
gradientColors.add(new GradientColor(startColor5, endColor5));
|
||||
|
||||
set1.setGradientColors(gradientColors);
|
||||
|
||||
ArrayList<IBarDataSet> dataSets = new ArrayList<>();
|
||||
dataSets.add(set1);
|
||||
|
||||
BarData data = new BarData(dataSets);
|
||||
data.setValueTextSize(10f);
|
||||
data.setValueTypeface(tfLight);
|
||||
data.setBarWidth(0.9f);
|
||||
|
||||
chart.setData(data);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.bar, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.viewGithub: {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/BarChartActivity.java"));
|
||||
startActivity(i);
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleValues: {
|
||||
for (IDataSet set : chart.getData().getDataSets())
|
||||
set.setDrawValues(!set.isDrawValuesEnabled());
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleIcons: {
|
||||
for (IDataSet set : chart.getData().getDataSets())
|
||||
set.setDrawIcons(!set.isDrawIconsEnabled());
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleHighlight: {
|
||||
if (chart.getData() != null) {
|
||||
chart.getData().setHighlightEnabled(!chart.getData().isHighlightEnabled());
|
||||
chart.invalidate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case R.id.actionTogglePinch: {
|
||||
if (chart.isPinchZoomEnabled())
|
||||
chart.setPinchZoom(false);
|
||||
else
|
||||
chart.setPinchZoom(true);
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleAutoScaleMinMax: {
|
||||
chart.setAutoScaleMinMaxEnabled(!chart.isAutoScaleMinMaxEnabled());
|
||||
chart.notifyDataSetChanged();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleBarBorders: {
|
||||
for (IBarDataSet set : chart.getData().getDataSets())
|
||||
((BarDataSet) set).setBarBorderWidth(set.getBarBorderWidth() == 1.f ? 0.f : 1.f);
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.animateX: {
|
||||
chart.animateX(2000);
|
||||
break;
|
||||
}
|
||||
case R.id.animateY: {
|
||||
chart.animateY(2000);
|
||||
break;
|
||||
}
|
||||
case R.id.animateXY: {
|
||||
chart.animateXY(2000, 2000);
|
||||
break;
|
||||
}
|
||||
case R.id.actionSave: {
|
||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
|
||||
saveToGallery();
|
||||
} else {
|
||||
requestStoragePermission(chart);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
|
||||
tvX.setText(String.valueOf(seekBarX.getProgress()));
|
||||
tvY.setText(String.valueOf(seekBarY.getProgress()));
|
||||
|
||||
setData(seekBarX.getProgress(), seekBarY.getProgress());
|
||||
chart.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveToGallery() {
|
||||
saveToGallery(chart, "BarChartActivity");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {}
|
||||
|
||||
private final RectF onValueSelectedRectF = new RectF();
|
||||
|
||||
@Override
|
||||
public void onValueSelected(Entry e, Highlight h) {
|
||||
|
||||
if (e == null)
|
||||
return;
|
||||
|
||||
RectF bounds = onValueSelectedRectF;
|
||||
chart.getBarBounds((BarEntry) e, bounds);
|
||||
MPPointF position = chart.getPosition(e, AxisDependency.LEFT);
|
||||
|
||||
Log.i("bounds", bounds.toString());
|
||||
Log.i("position", position.toString());
|
||||
|
||||
Log.i("x-index",
|
||||
"low: " + chart.getLowestVisibleX() + ", high: "
|
||||
+ chart.getHighestVisibleX());
|
||||
|
||||
MPPointF.recycleInstance(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected() { }
|
||||
}
|
||||
+289
@@ -0,0 +1,289 @@
|
||||
package com.android.stockapp.ui.mpchartexample;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Color;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.SeekBar.OnSeekBarChangeListener;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.ui.mpchartexample.custom.MyMarkerView;
|
||||
import com.android.stockapp.ui.mpchartexample.notimportant.DemoBase;
|
||||
import com.github.mikephil.charting.charts.BarChart;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
import com.github.mikephil.charting.data.BarData;
|
||||
import com.github.mikephil.charting.data.BarDataSet;
|
||||
import com.github.mikephil.charting.data.BarEntry;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.formatter.LargeValueFormatter;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IBarDataSet;
|
||||
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Locale;
|
||||
|
||||
public class BarChartActivityMultiDataset extends DemoBase implements OnSeekBarChangeListener,
|
||||
OnChartValueSelectedListener {
|
||||
|
||||
private BarChart chart;
|
||||
private SeekBar seekBarX, seekBarY;
|
||||
private TextView tvX, tvY;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_barchart);
|
||||
|
||||
setTitle("BarChartActivityMultiDataset");
|
||||
|
||||
tvX = findViewById(R.id.tvXMax);
|
||||
tvX.setTextSize(10);
|
||||
tvY = findViewById(R.id.tvYMax);
|
||||
|
||||
seekBarX = findViewById(R.id.seekBar1);
|
||||
seekBarX.setMax(50);
|
||||
seekBarX.setOnSeekBarChangeListener(this);
|
||||
|
||||
seekBarY = findViewById(R.id.seekBar2);
|
||||
seekBarY.setOnSeekBarChangeListener(this);
|
||||
|
||||
chart = findViewById(R.id.chart1);
|
||||
chart.setOnChartValueSelectedListener(this);
|
||||
chart.getDescription().setEnabled(false);
|
||||
|
||||
// chart.setDrawBorders(true);
|
||||
|
||||
// scaling can now only be done on x- and y-axis separately
|
||||
chart.setPinchZoom(false);
|
||||
|
||||
chart.setDrawBarShadow(false);
|
||||
|
||||
chart.setDrawGridBackground(false);
|
||||
|
||||
// create a custom MarkerView (extend MarkerView) and specify the layout
|
||||
// to use for it
|
||||
MyMarkerView mv = new MyMarkerView(this, R.layout.custom_marker_view);
|
||||
mv.setChartView(chart); // For bounds control
|
||||
chart.setMarker(mv); // Set the marker to the chart
|
||||
|
||||
seekBarX.setProgress(10);
|
||||
seekBarY.setProgress(100);
|
||||
|
||||
Legend l = chart.getLegend();
|
||||
l.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
|
||||
l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT);
|
||||
l.setOrientation(Legend.LegendOrientation.VERTICAL);
|
||||
l.setDrawInside(true);
|
||||
l.setTypeface(tfLight);
|
||||
l.setYOffset(0f);
|
||||
l.setXOffset(10f);
|
||||
l.setYEntrySpace(0f);
|
||||
l.setTextSize(8f);
|
||||
|
||||
XAxis xAxis = chart.getXAxis();
|
||||
xAxis.setTypeface(tfLight);
|
||||
xAxis.setGranularity(1f);
|
||||
xAxis.setCenterAxisLabels(true);
|
||||
xAxis.setValueFormatter(new ValueFormatter() {
|
||||
@Override
|
||||
public String getFormattedValue(float value) {
|
||||
return String.valueOf((int) value);
|
||||
}
|
||||
});
|
||||
|
||||
YAxis leftAxis = chart.getAxisLeft();
|
||||
leftAxis.setTypeface(tfLight);
|
||||
leftAxis.setValueFormatter(new LargeValueFormatter());
|
||||
leftAxis.setDrawGridLines(false);
|
||||
leftAxis.setSpaceTop(35f);
|
||||
leftAxis.setAxisMinimum(0f); // this replaces setStartAtZero(true)
|
||||
|
||||
chart.getAxisRight().setEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
|
||||
float groupSpace = 0.08f;
|
||||
float barSpace = 0.03f; // x4 DataSet
|
||||
float barWidth = 0.2f; // x4 DataSet
|
||||
// (0.2 + 0.03) * 4 + 0.08 = 1.00 -> interval per "group"
|
||||
|
||||
int groupCount = seekBarX.getProgress() + 1;
|
||||
int startYear = 1980;
|
||||
int endYear = startYear + groupCount;
|
||||
|
||||
tvX.setText(String.format(Locale.ENGLISH, "%d-%d", startYear, endYear));
|
||||
tvY.setText(String.valueOf(seekBarY.getProgress()));
|
||||
|
||||
ArrayList<BarEntry> values1 = new ArrayList<>();
|
||||
ArrayList<BarEntry> values2 = new ArrayList<>();
|
||||
ArrayList<BarEntry> values3 = new ArrayList<>();
|
||||
ArrayList<BarEntry> values4 = new ArrayList<>();
|
||||
|
||||
float randomMultiplier = seekBarY.getProgress() * 100000f;
|
||||
|
||||
for (int i = startYear; i < endYear; i++) {
|
||||
values1.add(new BarEntry(i, (float) (Math.random() * randomMultiplier)));
|
||||
values2.add(new BarEntry(i, (float) (Math.random() * randomMultiplier)));
|
||||
values3.add(new BarEntry(i, (float) (Math.random() * randomMultiplier)));
|
||||
values4.add(new BarEntry(i, (float) (Math.random() * randomMultiplier)));
|
||||
}
|
||||
|
||||
BarDataSet set1, set2, set3, set4;
|
||||
|
||||
if (chart.getData() != null && chart.getData().getDataSetCount() > 0) {
|
||||
|
||||
set1 = (BarDataSet) chart.getData().getDataSetByIndex(0);
|
||||
set2 = (BarDataSet) chart.getData().getDataSetByIndex(1);
|
||||
set3 = (BarDataSet) chart.getData().getDataSetByIndex(2);
|
||||
set4 = (BarDataSet) chart.getData().getDataSetByIndex(3);
|
||||
set1.setValues(values1);
|
||||
set2.setValues(values2);
|
||||
set3.setValues(values3);
|
||||
set4.setValues(values4);
|
||||
chart.getData().notifyDataChanged();
|
||||
chart.notifyDataSetChanged();
|
||||
|
||||
} else {
|
||||
// create 4 DataSets
|
||||
set1 = new BarDataSet(values1, "Company A");
|
||||
set1.setColor(Color.rgb(104, 241, 175));
|
||||
set2 = new BarDataSet(values2, "Company B");
|
||||
set2.setColor(Color.rgb(164, 228, 251));
|
||||
set3 = new BarDataSet(values3, "Company C");
|
||||
set3.setColor(Color.rgb(242, 247, 158));
|
||||
set4 = new BarDataSet(values4, "Company D");
|
||||
set4.setColor(Color.rgb(255, 102, 0));
|
||||
|
||||
BarData data = new BarData(set1, set2, set3, set4);
|
||||
data.setValueFormatter(new LargeValueFormatter());
|
||||
data.setValueTypeface(tfLight);
|
||||
|
||||
chart.setData(data);
|
||||
}
|
||||
|
||||
// specify the width each bar should have
|
||||
chart.getBarData().setBarWidth(barWidth);
|
||||
|
||||
// restrict the x-axis range
|
||||
chart.getXAxis().setAxisMinimum(startYear);
|
||||
|
||||
// barData.getGroupWith(...) is a helper that calculates the width each group needs based on the provided parameters
|
||||
chart.getXAxis().setAxisMaximum(startYear + chart.getBarData().getGroupWidth(groupSpace, barSpace) * groupCount);
|
||||
chart.groupBars(startYear, groupSpace, barSpace);
|
||||
chart.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.bar, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.viewGithub: {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/BarChartActivityMultiDataset.java"));
|
||||
startActivity(i);
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleValues: {
|
||||
for (IBarDataSet set : chart.getData().getDataSets())
|
||||
set.setDrawValues(!set.isDrawValuesEnabled());
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionTogglePinch: {
|
||||
if (chart.isPinchZoomEnabled())
|
||||
chart.setPinchZoom(false);
|
||||
else
|
||||
chart.setPinchZoom(true);
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleAutoScaleMinMax: {
|
||||
chart.setAutoScaleMinMaxEnabled(!chart.isAutoScaleMinMaxEnabled());
|
||||
chart.notifyDataSetChanged();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleBarBorders: {
|
||||
for (IBarDataSet set : chart.getData().getDataSets())
|
||||
((BarDataSet) set).setBarBorderWidth(set.getBarBorderWidth() == 1.f ? 0.f : 1.f);
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleHighlight: {
|
||||
if (chart.getData() != null) {
|
||||
chart.getData().setHighlightEnabled(!chart.getData().isHighlightEnabled());
|
||||
chart.invalidate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case R.id.actionSave: {
|
||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
|
||||
saveToGallery();
|
||||
} else {
|
||||
requestStoragePermission(chart);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case R.id.animateX: {
|
||||
chart.animateX(2000);
|
||||
break;
|
||||
}
|
||||
case R.id.animateY: {
|
||||
chart.animateY(2000);
|
||||
break;
|
||||
}
|
||||
case R.id.animateXY: {
|
||||
chart.animateXY(2000, 2000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveToGallery() {
|
||||
saveToGallery(chart, "BarChartActivityMultiDataset");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {}
|
||||
|
||||
@Override
|
||||
public void onValueSelected(Entry e, Highlight h) {
|
||||
Log.i("Activity", "Selected: " + e.toString() + ", dataSet: " + h.getDataSetIndex());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected() {
|
||||
Log.i("Activity", "Nothing selected.");
|
||||
}
|
||||
}
|
||||
+241
@@ -0,0 +1,241 @@
|
||||
|
||||
package com.android.stockapp.ui.mpchartexample;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Color;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.SeekBar.OnSeekBarChangeListener;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.ui.mpchartexample.notimportant.DemoBase;
|
||||
import com.github.mikephil.charting.charts.BarChart;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.components.Legend.LegendForm;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
import com.github.mikephil.charting.data.BarData;
|
||||
import com.github.mikephil.charting.data.BarDataSet;
|
||||
import com.github.mikephil.charting.data.BarEntry;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IBarDataSet;
|
||||
import com.github.mikephil.charting.utils.FileUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class BarChartActivitySinus extends DemoBase implements OnSeekBarChangeListener {
|
||||
|
||||
private BarChart chart;
|
||||
private SeekBar seekBarX;
|
||||
private TextView tvX;
|
||||
|
||||
private List<BarEntry> data;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_barchart_sinus);
|
||||
|
||||
setTitle("BarChartActivitySinus");
|
||||
|
||||
data = FileUtils.loadBarEntriesFromAssets(getAssets(), "othersine.txt");
|
||||
|
||||
tvX = findViewById(R.id.tvValueCount);
|
||||
|
||||
seekBarX = findViewById(R.id.seekbarValues);
|
||||
|
||||
chart = findViewById(R.id.chart1);
|
||||
|
||||
chart.setDrawBarShadow(false);
|
||||
chart.setDrawValueAboveBar(true);
|
||||
|
||||
chart.getDescription().setEnabled(false);
|
||||
|
||||
// if more than 60 entries are displayed in the chart, no values will be
|
||||
// drawn
|
||||
chart.setMaxVisibleValueCount(60);
|
||||
|
||||
// scaling can now only be done on x- and y-axis separately
|
||||
chart.setPinchZoom(false);
|
||||
|
||||
// draw shadows for each bar that show the maximum value
|
||||
// chart.setDrawBarShadow(true);
|
||||
|
||||
// chart.setDrawXLabels(false);
|
||||
|
||||
chart.setDrawGridBackground(false);
|
||||
// chart.setDrawYLabels(false);
|
||||
|
||||
XAxis xAxis = chart.getXAxis();
|
||||
xAxis.setEnabled(false);
|
||||
|
||||
YAxis leftAxis = chart.getAxisLeft();
|
||||
leftAxis.setTypeface(tfLight);
|
||||
leftAxis.setLabelCount(6, false);
|
||||
leftAxis.setAxisMinimum(-2.5f);
|
||||
leftAxis.setAxisMaximum(2.5f);
|
||||
leftAxis.setGranularityEnabled(true);
|
||||
leftAxis.setGranularity(0.1f);
|
||||
|
||||
YAxis rightAxis = chart.getAxisRight();
|
||||
rightAxis.setDrawGridLines(false);
|
||||
rightAxis.setTypeface(tfLight);
|
||||
rightAxis.setLabelCount(6, false);
|
||||
rightAxis.setAxisMinimum(-2.5f);
|
||||
rightAxis.setAxisMaximum(2.5f);
|
||||
rightAxis.setGranularity(0.1f);
|
||||
|
||||
seekBarX.setOnSeekBarChangeListener(this);
|
||||
seekBarX.setProgress(150); // set data
|
||||
|
||||
Legend l = chart.getLegend();
|
||||
l.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);
|
||||
l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.LEFT);
|
||||
l.setOrientation(Legend.LegendOrientation.HORIZONTAL);
|
||||
l.setDrawInside(false);
|
||||
l.setForm(LegendForm.SQUARE);
|
||||
l.setFormSize(9f);
|
||||
l.setTextSize(11f);
|
||||
l.setXEntrySpace(4f);
|
||||
|
||||
chart.animateXY(1500, 1500);
|
||||
}
|
||||
|
||||
private void setData(int count) {
|
||||
|
||||
ArrayList<BarEntry> entries = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
entries.add(data.get(i));
|
||||
}
|
||||
|
||||
BarDataSet set;
|
||||
|
||||
if (chart.getData() != null &&
|
||||
chart.getData().getDataSetCount() > 0) {
|
||||
set = (BarDataSet) chart.getData().getDataSetByIndex(0);
|
||||
set.setValues(entries);
|
||||
chart.getData().notifyDataChanged();
|
||||
chart.notifyDataSetChanged();
|
||||
} else {
|
||||
set = new BarDataSet(entries, "Sinus Function");
|
||||
set.setColor(Color.rgb(240, 120, 124));
|
||||
}
|
||||
|
||||
BarData data = new BarData(set);
|
||||
data.setValueTextSize(10f);
|
||||
data.setValueTypeface(tfLight);
|
||||
data.setDrawValues(false);
|
||||
data.setBarWidth(0.8f);
|
||||
|
||||
chart.setData(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.bar, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.viewGithub: {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/BarChartActivitySinus.java"));
|
||||
startActivity(i);
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleValues: {
|
||||
for (IBarDataSet set : chart.getData().getDataSets())
|
||||
set.setDrawValues(!set.isDrawValuesEnabled());
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleHighlight: {
|
||||
if (chart.getData() != null) {
|
||||
chart.getData().setHighlightEnabled(!chart.getData().isHighlightEnabled());
|
||||
chart.invalidate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case R.id.actionTogglePinch: {
|
||||
if (chart.isPinchZoomEnabled())
|
||||
chart.setPinchZoom(false);
|
||||
else
|
||||
chart.setPinchZoom(true);
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleAutoScaleMinMax: {
|
||||
chart.setAutoScaleMinMaxEnabled(!chart.isAutoScaleMinMaxEnabled());
|
||||
chart.notifyDataSetChanged();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleBarBorders: {
|
||||
for (IBarDataSet set : chart.getData().getDataSets())
|
||||
((BarDataSet) set).setBarBorderWidth(set.getBarBorderWidth() == 1.f ? 0.f : 1.f);
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.animateX: {
|
||||
chart.animateX(2000);
|
||||
break;
|
||||
}
|
||||
case R.id.animateY: {
|
||||
chart.animateY(2000);
|
||||
break;
|
||||
}
|
||||
case R.id.animateXY: {
|
||||
|
||||
chart.animateXY(2000, 2000);
|
||||
break;
|
||||
}
|
||||
case R.id.actionSave: {
|
||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
|
||||
saveToGallery();
|
||||
} else {
|
||||
requestStoragePermission(chart);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
|
||||
tvX.setText(String.valueOf(seekBarX.getProgress()));
|
||||
|
||||
setData(seekBarX.getProgress());
|
||||
chart.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveToGallery() {
|
||||
saveToGallery(chart, "BarChartActivitySinus");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {}
|
||||
|
||||
}
|
||||
+196
@@ -0,0 +1,196 @@
|
||||
package com.android.stockapp.ui.mpchartexample;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.ui.mpchartexample.notimportant.DemoBase;
|
||||
import com.github.mikephil.charting.charts.BarChart;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.XAxis.XAxisPosition;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
import com.github.mikephil.charting.data.BarData;
|
||||
import com.github.mikephil.charting.data.BarDataSet;
|
||||
import com.github.mikephil.charting.data.BarEntry;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class BarChartPositiveNegative extends DemoBase {
|
||||
|
||||
private BarChart chart;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_barchart_noseekbar);
|
||||
|
||||
setTitle("BarChartPositiveNegative");
|
||||
|
||||
chart = findViewById(R.id.chart1);
|
||||
chart.setBackgroundColor(Color.WHITE);
|
||||
chart.setExtraTopOffset(-30f);
|
||||
chart.setExtraBottomOffset(10f);
|
||||
chart.setExtraLeftOffset(70f);
|
||||
chart.setExtraRightOffset(70f);
|
||||
|
||||
chart.setDrawBarShadow(false);
|
||||
chart.setDrawValueAboveBar(true);
|
||||
|
||||
chart.getDescription().setEnabled(false);
|
||||
|
||||
// scaling can now only be done on x- and y-axis separately
|
||||
chart.setPinchZoom(false);
|
||||
|
||||
chart.setDrawGridBackground(false);
|
||||
|
||||
XAxis xAxis = chart.getXAxis();
|
||||
xAxis.setPosition(XAxisPosition.BOTTOM);
|
||||
xAxis.setTypeface(tfRegular);
|
||||
xAxis.setDrawGridLines(false);
|
||||
xAxis.setDrawAxisLine(false);
|
||||
xAxis.setTextColor(Color.LTGRAY);
|
||||
xAxis.setTextSize(13f);
|
||||
xAxis.setLabelCount(5);
|
||||
xAxis.setCenterAxisLabels(true);
|
||||
xAxis.setGranularity(1f);
|
||||
|
||||
YAxis left = chart.getAxisLeft();
|
||||
left.setDrawLabels(false);
|
||||
left.setSpaceTop(25f);
|
||||
left.setSpaceBottom(25f);
|
||||
left.setDrawAxisLine(false);
|
||||
left.setDrawGridLines(false);
|
||||
left.setDrawZeroLine(true); // draw a zero line
|
||||
left.setZeroLineColor(Color.GRAY);
|
||||
left.setZeroLineWidth(0.7f);
|
||||
chart.getAxisRight().setEnabled(false);
|
||||
chart.getLegend().setEnabled(false);
|
||||
|
||||
// THIS IS THE ORIGINAL DATA YOU WANT TO PLOT
|
||||
final List<Data> data = new ArrayList<>();
|
||||
data.add(new Data(0f, -224.1f, "12-29"));
|
||||
data.add(new Data(1f, 238.5f, "12-30"));
|
||||
data.add(new Data(2f, 1280.1f, "12-31"));
|
||||
data.add(new Data(3f, -442.3f, "01-01"));
|
||||
data.add(new Data(4f, -2280.1f, "01-02"));
|
||||
|
||||
xAxis.setValueFormatter(new ValueFormatter() {
|
||||
@Override
|
||||
public String getFormattedValue(float value) {
|
||||
return data.get(Math.min(Math.max((int) value, 0), data.size()-1)).xAxisValue;
|
||||
}
|
||||
});
|
||||
|
||||
setData(data);
|
||||
}
|
||||
|
||||
private void setData(List<Data> dataList) {
|
||||
|
||||
ArrayList<BarEntry> values = new ArrayList<>();
|
||||
List<Integer> colors = new ArrayList<>();
|
||||
|
||||
int green = Color.rgb(110, 190, 102);
|
||||
int red = Color.rgb(211, 74, 88);
|
||||
|
||||
for (int i = 0; i < dataList.size(); i++) {
|
||||
|
||||
Data d = dataList.get(i);
|
||||
BarEntry entry = new BarEntry(d.xValue, d.yValue);
|
||||
values.add(entry);
|
||||
|
||||
// specific colors
|
||||
if (d.yValue >= 0)
|
||||
colors.add(red);
|
||||
else
|
||||
colors.add(green);
|
||||
}
|
||||
|
||||
BarDataSet set;
|
||||
|
||||
if (chart.getData() != null &&
|
||||
chart.getData().getDataSetCount() > 0) {
|
||||
set = (BarDataSet) chart.getData().getDataSetByIndex(0);
|
||||
set.setValues(values);
|
||||
chart.getData().notifyDataChanged();
|
||||
chart.notifyDataSetChanged();
|
||||
} else {
|
||||
set = new BarDataSet(values, "Values");
|
||||
set.setColors(colors);
|
||||
set.setValueTextColors(colors);
|
||||
|
||||
BarData data = new BarData(set);
|
||||
data.setValueTextSize(13f);
|
||||
data.setValueTypeface(tfRegular);
|
||||
data.setValueFormatter(new Formatter());
|
||||
data.setBarWidth(0.8f);
|
||||
|
||||
chart.setData(data);
|
||||
chart.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Demo class representing data.
|
||||
*/
|
||||
private class Data {
|
||||
|
||||
final String xAxisValue;
|
||||
final float yValue;
|
||||
final float xValue;
|
||||
|
||||
Data(float xValue, float yValue, String xAxisValue) {
|
||||
this.xAxisValue = xAxisValue;
|
||||
this.yValue = yValue;
|
||||
this.xValue = xValue;
|
||||
}
|
||||
}
|
||||
|
||||
private class Formatter extends ValueFormatter
|
||||
{
|
||||
|
||||
private final DecimalFormat mFormat;
|
||||
|
||||
Formatter() {
|
||||
mFormat = new DecimalFormat("######.0");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormattedValue(float value) {
|
||||
return mFormat.format(value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.only_github, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.viewGithub: {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/BarChartPositiveNegative.java"));
|
||||
startActivity(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveToGallery() { /* Intentionally left empty */ }
|
||||
}
|
||||
+250
@@ -0,0 +1,250 @@
|
||||
|
||||
package com.android.stockapp.ui.mpchartexample;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Color;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.SeekBar.OnSeekBarChangeListener;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.ui.mpchartexample.notimportant.DemoBase;
|
||||
import com.github.mikephil.charting.charts.BubbleChart;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
import com.github.mikephil.charting.data.BubbleData;
|
||||
import com.github.mikephil.charting.data.BubbleDataSet;
|
||||
import com.github.mikephil.charting.data.BubbleEntry;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IBubbleDataSet;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IDataSet;
|
||||
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
|
||||
import com.github.mikephil.charting.utils.ColorTemplate;
|
||||
import com.github.mikephil.charting.utils.MPPointF;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class BubbleChartActivity extends DemoBase implements OnSeekBarChangeListener,
|
||||
OnChartValueSelectedListener {
|
||||
|
||||
private BubbleChart chart;
|
||||
private SeekBar seekBarX, seekBarY;
|
||||
private TextView tvX, tvY;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_bubblechart);
|
||||
|
||||
setTitle("BubbleChartActivity");
|
||||
|
||||
tvX = findViewById(R.id.tvXMax);
|
||||
tvY = findViewById(R.id.tvYMax);
|
||||
|
||||
seekBarX = findViewById(R.id.seekBar1);
|
||||
seekBarX.setOnSeekBarChangeListener(this);
|
||||
|
||||
seekBarY = findViewById(R.id.seekBar2);
|
||||
seekBarY.setOnSeekBarChangeListener(this);
|
||||
|
||||
chart = findViewById(R.id.chart1);
|
||||
chart.getDescription().setEnabled(false);
|
||||
|
||||
chart.setOnChartValueSelectedListener(this);
|
||||
|
||||
chart.setDrawGridBackground(false);
|
||||
|
||||
chart.setTouchEnabled(true);
|
||||
|
||||
// enable scaling and dragging
|
||||
chart.setDragEnabled(true);
|
||||
chart.setScaleEnabled(true);
|
||||
|
||||
chart.setMaxVisibleValueCount(200);
|
||||
chart.setPinchZoom(true);
|
||||
|
||||
seekBarX.setProgress(10);
|
||||
seekBarY.setProgress(50);
|
||||
|
||||
Legend l = chart.getLegend();
|
||||
l.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
|
||||
l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT);
|
||||
l.setOrientation(Legend.LegendOrientation.VERTICAL);
|
||||
l.setDrawInside(false);
|
||||
l.setTypeface(tfLight);
|
||||
|
||||
YAxis yl = chart.getAxisLeft();
|
||||
yl.setTypeface(tfLight);
|
||||
yl.setSpaceTop(30f);
|
||||
yl.setSpaceBottom(30f);
|
||||
yl.setDrawZeroLine(false);
|
||||
|
||||
chart.getAxisRight().setEnabled(false);
|
||||
|
||||
XAxis xl = chart.getXAxis();
|
||||
xl.setPosition(XAxis.XAxisPosition.BOTTOM);
|
||||
xl.setTypeface(tfLight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
|
||||
int count = seekBarX.getProgress();
|
||||
int range = seekBarY.getProgress();
|
||||
|
||||
tvX.setText(String.valueOf(count));
|
||||
tvY.setText(String.valueOf(range));
|
||||
|
||||
ArrayList<BubbleEntry> values1 = new ArrayList<>();
|
||||
ArrayList<BubbleEntry> values2 = new ArrayList<>();
|
||||
ArrayList<BubbleEntry> values3 = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
values1.add(new BubbleEntry(i, (float) (Math.random() * range), (float) (Math.random() * range), getResources().getDrawable(R.drawable.star)));
|
||||
values2.add(new BubbleEntry(i, (float) (Math.random() * range), (float) (Math.random() * range), getResources().getDrawable(R.drawable.star)));
|
||||
values3.add(new BubbleEntry(i, (float) (Math.random() * range), (float) (Math.random() * range)));
|
||||
}
|
||||
|
||||
// create a dataset and give it a type
|
||||
BubbleDataSet set1 = new BubbleDataSet(values1, "DS 1");
|
||||
set1.setDrawIcons(false);
|
||||
set1.setColor(ColorTemplate.COLORFUL_COLORS[0], 130);
|
||||
set1.setDrawValues(true);
|
||||
|
||||
BubbleDataSet set2 = new BubbleDataSet(values2, "DS 2");
|
||||
set2.setDrawIcons(false);
|
||||
set2.setIconsOffset(new MPPointF(0, 15));
|
||||
set2.setColor(ColorTemplate.COLORFUL_COLORS[1], 130);
|
||||
set2.setDrawValues(true);
|
||||
|
||||
BubbleDataSet set3 = new BubbleDataSet(values3, "DS 3");
|
||||
set3.setColor(ColorTemplate.COLORFUL_COLORS[2], 130);
|
||||
set3.setDrawValues(true);
|
||||
|
||||
ArrayList<IBubbleDataSet> dataSets = new ArrayList<>();
|
||||
dataSets.add(set1); // add the data sets
|
||||
dataSets.add(set2);
|
||||
dataSets.add(set3);
|
||||
|
||||
// create a data object with the data sets
|
||||
BubbleData data = new BubbleData(dataSets);
|
||||
data.setDrawValues(false);
|
||||
data.setValueTypeface(tfLight);
|
||||
data.setValueTextSize(8f);
|
||||
data.setValueTextColor(Color.WHITE);
|
||||
data.setHighlightCircleWidth(1.5f);
|
||||
|
||||
chart.setData(data);
|
||||
chart.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.bubble, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.viewGithub: {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/BubbleChartActivity.java"));
|
||||
startActivity(i);
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleValues: {
|
||||
for (IDataSet set : chart.getData().getDataSets())
|
||||
set.setDrawValues(!set.isDrawValuesEnabled());
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleIcons: {
|
||||
for (IDataSet set : chart.getData().getDataSets())
|
||||
set.setDrawIcons(!set.isDrawIconsEnabled());
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleHighlight: {
|
||||
if(chart.getData() != null) {
|
||||
chart.getData().setHighlightEnabled(!chart.getData().isHighlightEnabled());
|
||||
chart.invalidate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case R.id.actionTogglePinch: {
|
||||
if (chart.isPinchZoomEnabled())
|
||||
chart.setPinchZoom(false);
|
||||
else
|
||||
chart.setPinchZoom(true);
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleAutoScaleMinMax: {
|
||||
chart.setAutoScaleMinMaxEnabled(!chart.isAutoScaleMinMaxEnabled());
|
||||
chart.notifyDataSetChanged();
|
||||
break;
|
||||
}
|
||||
case R.id.actionSave: {
|
||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
|
||||
saveToGallery();
|
||||
} else {
|
||||
requestStoragePermission(chart);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case R.id.animateX: {
|
||||
chart.animateX(2000);
|
||||
break;
|
||||
}
|
||||
case R.id.animateY: {
|
||||
chart.animateY(2000);
|
||||
break;
|
||||
}
|
||||
case R.id.animateXY: {
|
||||
chart.animateXY(2000, 2000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveToGallery() {
|
||||
saveToGallery(chart, "BubbleChartActivity");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onValueSelected(Entry e, Highlight h) {
|
||||
Log.i("VAL SELECTED",
|
||||
"Value: " + e.getY() + ", xIndex: " + e.getX()
|
||||
+ ", DataSet index: " + h.getDataSetIndex());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected() {}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {}
|
||||
}
|
||||
+240
@@ -0,0 +1,240 @@
|
||||
|
||||
package com.android.stockapp.ui.mpchartexample;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.SeekBar.OnSeekBarChangeListener;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.ui.mpchartexample.notimportant.DemoBase;
|
||||
import com.github.mikephil.charting.charts.CandleStickChart;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.XAxis.XAxisPosition;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
import com.github.mikephil.charting.components.YAxis.AxisDependency;
|
||||
import com.github.mikephil.charting.data.CandleData;
|
||||
import com.github.mikephil.charting.data.CandleDataSet;
|
||||
import com.github.mikephil.charting.data.CandleEntry;
|
||||
import com.github.mikephil.charting.interfaces.datasets.ICandleDataSet;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IDataSet;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class CandleStickChartActivity extends DemoBase implements OnSeekBarChangeListener {
|
||||
|
||||
private CandleStickChart chart;
|
||||
private SeekBar seekBarX, seekBarY;
|
||||
private TextView tvX, tvY;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_candlechart);
|
||||
|
||||
setTitle("CandleStickChartActivity");
|
||||
|
||||
tvX = findViewById(R.id.tvXMax);
|
||||
tvY = findViewById(R.id.tvYMax);
|
||||
|
||||
seekBarX = findViewById(R.id.seekBar1);
|
||||
seekBarX.setOnSeekBarChangeListener(this);
|
||||
|
||||
seekBarY = findViewById(R.id.seekBar2);
|
||||
seekBarY.setOnSeekBarChangeListener(this);
|
||||
|
||||
chart = findViewById(R.id.chart1);
|
||||
chart.setBackgroundColor(Color.WHITE);
|
||||
|
||||
chart.getDescription().setEnabled(false);
|
||||
|
||||
// if more than 60 entries are displayed in the chart, no values will be
|
||||
// drawn
|
||||
chart.setMaxVisibleValueCount(60);
|
||||
|
||||
// scaling can now only be done on x- and y-axis separately
|
||||
chart.setPinchZoom(false);
|
||||
|
||||
chart.setDrawGridBackground(false);
|
||||
|
||||
XAxis xAxis = chart.getXAxis();
|
||||
xAxis.setPosition(XAxisPosition.BOTTOM);
|
||||
xAxis.setDrawGridLines(false);
|
||||
|
||||
YAxis leftAxis = chart.getAxisLeft();
|
||||
// leftAxis.setEnabled(false);
|
||||
leftAxis.setLabelCount(7, false);
|
||||
leftAxis.setDrawGridLines(false);
|
||||
leftAxis.setDrawAxisLine(false);
|
||||
|
||||
YAxis rightAxis = chart.getAxisRight();
|
||||
rightAxis.setEnabled(false);
|
||||
// rightAxis.setStartAtZero(false);
|
||||
|
||||
// setting data
|
||||
seekBarX.setProgress(40);
|
||||
seekBarY.setProgress(100);
|
||||
|
||||
chart.getLegend().setEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
|
||||
progress = (seekBarX.getProgress());
|
||||
|
||||
tvX.setText(String.valueOf(progress));
|
||||
tvY.setText(String.valueOf(seekBarY.getProgress()));
|
||||
|
||||
chart.resetTracking();
|
||||
|
||||
ArrayList<CandleEntry> values = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < progress; i++) {
|
||||
float multi = (seekBarY.getProgress() + 1);
|
||||
float val = (float) (Math.random() * 40) + multi;
|
||||
|
||||
float high = (float) (Math.random() * 9) + 8f;
|
||||
float low = (float) (Math.random() * 9) + 8f;
|
||||
|
||||
float open = (float) (Math.random() * 6) + 1f;
|
||||
float close = (float) (Math.random() * 6) + 1f;
|
||||
|
||||
boolean even = i % 2 == 0;
|
||||
|
||||
values.add(new CandleEntry(
|
||||
i, val + high,
|
||||
val - low,
|
||||
even ? val + open : val - open,
|
||||
even ? val - close : val + close,
|
||||
getResources().getDrawable(R.drawable.star)
|
||||
));
|
||||
}
|
||||
|
||||
CandleDataSet set1 = new CandleDataSet(values, "Data Set");
|
||||
|
||||
set1.setDrawIcons(false);
|
||||
set1.setAxisDependency(AxisDependency.LEFT);
|
||||
// set1.setColor(Color.rgb(80, 80, 80));
|
||||
set1.setShadowColor(Color.DKGRAY);
|
||||
set1.setShadowWidth(0.7f);
|
||||
set1.setDecreasingColor(Color.RED);
|
||||
set1.setDecreasingPaintStyle(Paint.Style.FILL);
|
||||
set1.setIncreasingColor(Color.rgb(122, 242, 84));
|
||||
set1.setIncreasingPaintStyle(Paint.Style.STROKE);
|
||||
set1.setNeutralColor(Color.BLUE);
|
||||
//set1.setHighlightLineWidth(1f);
|
||||
|
||||
CandleData data = new CandleData(set1);
|
||||
|
||||
chart.setData(data);
|
||||
chart.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.candle, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.viewGithub: {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/CandleStickChartActivity.java"));
|
||||
startActivity(i);
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleValues: {
|
||||
for (IDataSet set : chart.getData().getDataSets())
|
||||
set.setDrawValues(!set.isDrawValuesEnabled());
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleIcons: {
|
||||
for (IDataSet set : chart.getData().getDataSets())
|
||||
set.setDrawIcons(!set.isDrawIconsEnabled());
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleHighlight: {
|
||||
if(chart.getData() != null) {
|
||||
chart.getData().setHighlightEnabled(!chart.getData().isHighlightEnabled());
|
||||
chart.invalidate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case R.id.actionTogglePinch: {
|
||||
if (chart.isPinchZoomEnabled())
|
||||
chart.setPinchZoom(false);
|
||||
else
|
||||
chart.setPinchZoom(true);
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleAutoScaleMinMax: {
|
||||
chart.setAutoScaleMinMaxEnabled(!chart.isAutoScaleMinMaxEnabled());
|
||||
chart.notifyDataSetChanged();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleMakeShadowSameColorAsCandle: {
|
||||
for (ICandleDataSet set : chart.getData().getDataSets()) {
|
||||
((CandleDataSet) set).setShadowColorSameAsCandle(!set.getShadowColorSameAsCandle());
|
||||
}
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.animateX: {
|
||||
chart.animateX(2000);
|
||||
break;
|
||||
}
|
||||
case R.id.animateY: {
|
||||
chart.animateY(2000);
|
||||
break;
|
||||
}
|
||||
case R.id.animateXY: {
|
||||
chart.animateXY(2000, 2000);
|
||||
break;
|
||||
}
|
||||
case R.id.actionSave: {
|
||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
|
||||
saveToGallery();
|
||||
} else {
|
||||
requestStoragePermission(chart);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveToGallery() {
|
||||
saveToGallery(chart, "CandleStickChartActivity");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {}
|
||||
}
|
||||
+281
@@ -0,0 +1,281 @@
|
||||
package com.android.stockapp.ui.mpchartexample;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.ui.mpchartexample.notimportant.DemoBase;
|
||||
import com.github.mikephil.charting.charts.CombinedChart;
|
||||
import com.github.mikephil.charting.charts.CombinedChart.DrawOrder;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.XAxis.XAxisPosition;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
import com.github.mikephil.charting.data.BarData;
|
||||
import com.github.mikephil.charting.data.BarDataSet;
|
||||
import com.github.mikephil.charting.data.BarEntry;
|
||||
import com.github.mikephil.charting.data.BubbleData;
|
||||
import com.github.mikephil.charting.data.BubbleDataSet;
|
||||
import com.github.mikephil.charting.data.BubbleEntry;
|
||||
import com.github.mikephil.charting.data.CandleData;
|
||||
import com.github.mikephil.charting.data.CandleDataSet;
|
||||
import com.github.mikephil.charting.data.CandleEntry;
|
||||
import com.github.mikephil.charting.data.CombinedData;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.data.LineData;
|
||||
import com.github.mikephil.charting.data.LineDataSet;
|
||||
import com.github.mikephil.charting.data.ScatterData;
|
||||
import com.github.mikephil.charting.data.ScatterDataSet;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IDataSet;
|
||||
import com.github.mikephil.charting.utils.ColorTemplate;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class CombinedChartActivity extends DemoBase {
|
||||
|
||||
private CombinedChart chart;
|
||||
private final int count = 12;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_combined);
|
||||
|
||||
setTitle("CombinedChartActivity");
|
||||
|
||||
chart = findViewById(R.id.chart1);
|
||||
chart.getDescription().setEnabled(false);
|
||||
chart.setBackgroundColor(Color.WHITE);
|
||||
chart.setDrawGridBackground(false);
|
||||
chart.setDrawBarShadow(false);
|
||||
chart.setHighlightFullBarEnabled(false);
|
||||
|
||||
// draw bars behind lines
|
||||
chart.setDrawOrder(new DrawOrder[]{
|
||||
DrawOrder.BAR, DrawOrder.BUBBLE, DrawOrder.CANDLE, DrawOrder.LINE, DrawOrder.SCATTER
|
||||
});
|
||||
|
||||
Legend l = chart.getLegend();
|
||||
l.setWordWrapEnabled(true);
|
||||
l.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);
|
||||
l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER);
|
||||
l.setOrientation(Legend.LegendOrientation.HORIZONTAL);
|
||||
l.setDrawInside(false);
|
||||
|
||||
YAxis rightAxis = chart.getAxisRight();
|
||||
rightAxis.setDrawGridLines(false);
|
||||
rightAxis.setAxisMinimum(0f); // this replaces setStartAtZero(true)
|
||||
|
||||
YAxis leftAxis = chart.getAxisLeft();
|
||||
leftAxis.setDrawGridLines(false);
|
||||
leftAxis.setAxisMinimum(0f); // this replaces setStartAtZero(true)
|
||||
|
||||
XAxis xAxis = chart.getXAxis();
|
||||
xAxis.setPosition(XAxisPosition.BOTH_SIDED);
|
||||
xAxis.setAxisMinimum(0f);
|
||||
xAxis.setGranularity(1f);
|
||||
xAxis.setValueFormatter(new ValueFormatter() {
|
||||
@Override
|
||||
public String getFormattedValue(float value) {
|
||||
return months[(int) value % months.length];
|
||||
}
|
||||
});
|
||||
|
||||
CombinedData data = new CombinedData();
|
||||
|
||||
data.setData(generateLineData());
|
||||
data.setData(generateBarData());
|
||||
data.setData(generateBubbleData());
|
||||
data.setData(generateScatterData());
|
||||
data.setData(generateCandleData());
|
||||
data.setValueTypeface(tfLight);
|
||||
|
||||
xAxis.setAxisMaximum(data.getXMax() + 0.25f);
|
||||
|
||||
chart.setData(data);
|
||||
chart.invalidate();
|
||||
}
|
||||
|
||||
private LineData generateLineData() {
|
||||
|
||||
LineData d = new LineData();
|
||||
|
||||
ArrayList<Entry> entries = new ArrayList<>();
|
||||
|
||||
for (int index = 0; index < count; index++)
|
||||
entries.add(new Entry(index + 0.5f, getRandom(15, 5)));
|
||||
|
||||
LineDataSet set = new LineDataSet(entries, "Line DataSet");
|
||||
set.setColor(Color.rgb(240, 238, 70));
|
||||
set.setLineWidth(2.5f);
|
||||
set.setCircleColor(Color.rgb(240, 238, 70));
|
||||
set.setCircleRadius(5f);
|
||||
set.setFillColor(Color.rgb(240, 238, 70));
|
||||
set.setMode(LineDataSet.Mode.CUBIC_BEZIER);
|
||||
set.setDrawValues(true);
|
||||
set.setValueTextSize(10f);
|
||||
set.setValueTextColor(Color.rgb(240, 238, 70));
|
||||
|
||||
set.setAxisDependency(YAxis.AxisDependency.LEFT);
|
||||
d.addDataSet(set);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
private BarData generateBarData() {
|
||||
|
||||
ArrayList<BarEntry> entries1 = new ArrayList<>();
|
||||
ArrayList<BarEntry> entries2 = new ArrayList<>();
|
||||
|
||||
for (int index = 0; index < count; index++) {
|
||||
entries1.add(new BarEntry(0, getRandom(25, 25)));
|
||||
|
||||
// stacked
|
||||
entries2.add(new BarEntry(0, new float[]{getRandom(13, 12), getRandom(13, 12)}));
|
||||
}
|
||||
|
||||
BarDataSet set1 = new BarDataSet(entries1, "Bar 1");
|
||||
set1.setColor(Color.rgb(60, 220, 78));
|
||||
set1.setValueTextColor(Color.rgb(60, 220, 78));
|
||||
set1.setValueTextSize(10f);
|
||||
set1.setAxisDependency(YAxis.AxisDependency.LEFT);
|
||||
|
||||
BarDataSet set2 = new BarDataSet(entries2, "");
|
||||
set2.setStackLabels(new String[]{"Stack 1", "Stack 2"});
|
||||
set2.setColors(Color.rgb(61, 165, 255), Color.rgb(23, 197, 255));
|
||||
set2.setValueTextColor(Color.rgb(61, 165, 255));
|
||||
set2.setValueTextSize(10f);
|
||||
set2.setAxisDependency(YAxis.AxisDependency.LEFT);
|
||||
|
||||
float groupSpace = 0.06f;
|
||||
float barSpace = 0.02f; // x2 dataset
|
||||
float barWidth = 0.45f; // x2 dataset
|
||||
// (0.45 + 0.02) * 2 + 0.06 = 1.00 -> interval per "group"
|
||||
|
||||
BarData d = new BarData(set1, set2);
|
||||
d.setBarWidth(barWidth);
|
||||
|
||||
// make this BarData object grouped
|
||||
d.groupBars(0, groupSpace, barSpace); // start at x = 0
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
private ScatterData generateScatterData() {
|
||||
|
||||
ScatterData d = new ScatterData();
|
||||
|
||||
ArrayList<Entry> entries = new ArrayList<>();
|
||||
|
||||
for (float index = 0; index < count; index += 0.5f)
|
||||
entries.add(new Entry(index + 0.25f, getRandom(10, 55)));
|
||||
|
||||
ScatterDataSet set = new ScatterDataSet(entries, "Scatter DataSet");
|
||||
set.setColors(ColorTemplate.MATERIAL_COLORS);
|
||||
set.setScatterShapeSize(7.5f);
|
||||
set.setDrawValues(false);
|
||||
set.setValueTextSize(10f);
|
||||
d.addDataSet(set);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
private CandleData generateCandleData() {
|
||||
|
||||
CandleData d = new CandleData();
|
||||
|
||||
ArrayList<CandleEntry> entries = new ArrayList<>();
|
||||
|
||||
for (int index = 0; index < count; index += 2)
|
||||
entries.add(new CandleEntry(index + 1f, 90, 70, 85, 75f));
|
||||
|
||||
CandleDataSet set = new CandleDataSet(entries, "Candle DataSet");
|
||||
set.setDecreasingColor(Color.rgb(142, 150, 175));
|
||||
set.setShadowColor(Color.DKGRAY);
|
||||
set.setBarSpace(0.3f);
|
||||
set.setValueTextSize(10f);
|
||||
set.setDrawValues(false);
|
||||
d.addDataSet(set);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
private BubbleData generateBubbleData() {
|
||||
|
||||
BubbleData bd = new BubbleData();
|
||||
|
||||
ArrayList<BubbleEntry> entries = new ArrayList<>();
|
||||
|
||||
for (int index = 0; index < count; index++) {
|
||||
float y = getRandom(10, 105);
|
||||
float size = getRandom(100, 105);
|
||||
entries.add(new BubbleEntry(index + 0.5f, y, size));
|
||||
}
|
||||
|
||||
BubbleDataSet set = new BubbleDataSet(entries, "Bubble DataSet");
|
||||
set.setColors(ColorTemplate.VORDIPLOM_COLORS);
|
||||
set.setValueTextSize(10f);
|
||||
set.setValueTextColor(Color.WHITE);
|
||||
set.setHighlightCircleWidth(1.5f);
|
||||
set.setDrawValues(true);
|
||||
bd.addDataSet(set);
|
||||
|
||||
return bd;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.combined, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.viewGithub: {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/CombinedChartActivity.java"));
|
||||
startActivity(i);
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleLineValues: {
|
||||
for (IDataSet set : chart.getData().getDataSets()) {
|
||||
if (set instanceof LineDataSet)
|
||||
set.setDrawValues(!set.isDrawValuesEnabled());
|
||||
}
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleBarValues: {
|
||||
for (IDataSet set : chart.getData().getDataSets()) {
|
||||
if (set instanceof BarDataSet)
|
||||
set.setDrawValues(!set.isDrawValuesEnabled());
|
||||
}
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionRemoveDataSet: {
|
||||
int rnd = (int) getRandom(chart.getData().getDataSetCount(), 0);
|
||||
chart.getData().removeDataSet(chart.getData().getDataSetByIndex(rnd));
|
||||
chart.getData().notifyDataChanged();
|
||||
chart.notifyDataSetChanged();
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveToGallery() { /* Intentionally left empty */ }
|
||||
}
|
||||
+322
@@ -0,0 +1,322 @@
|
||||
|
||||
package com.android.stockapp.ui.mpchartexample;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Color;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.SeekBar.OnSeekBarChangeListener;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.ui.mpchartexample.notimportant.DemoBase;
|
||||
import com.github.mikephil.charting.charts.LineChart;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.data.LineData;
|
||||
import com.github.mikephil.charting.data.LineDataSet;
|
||||
import com.github.mikephil.charting.formatter.IFillFormatter;
|
||||
import com.github.mikephil.charting.interfaces.dataprovider.LineDataProvider;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IDataSet;
|
||||
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class CubicLineChartActivity extends DemoBase implements OnSeekBarChangeListener {
|
||||
|
||||
private LineChart chart;
|
||||
private SeekBar seekBarX, seekBarY;
|
||||
private TextView tvX, tvY;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_linechart);
|
||||
|
||||
setTitle("CubicLineChartActivity");
|
||||
|
||||
tvX = findViewById(R.id.tvXMax);
|
||||
tvY = findViewById(R.id.tvYMax);
|
||||
|
||||
seekBarX = findViewById(R.id.seekBar1);
|
||||
seekBarY = findViewById(R.id.seekBar2);
|
||||
|
||||
chart = findViewById(R.id.chart1);
|
||||
chart.setViewPortOffsets(0, 0, 0, 0);
|
||||
chart.setBackgroundColor(Color.rgb(104, 241, 175));
|
||||
|
||||
// no description text
|
||||
chart.getDescription().setEnabled(false);
|
||||
|
||||
// enable touch gestures
|
||||
chart.setTouchEnabled(true);
|
||||
|
||||
// enable scaling and dragging
|
||||
chart.setDragEnabled(true);
|
||||
chart.setScaleEnabled(true);
|
||||
|
||||
// if disabled, scaling can be done on x- and y-axis separately
|
||||
chart.setPinchZoom(false);
|
||||
|
||||
chart.setDrawGridBackground(false);
|
||||
chart.setMaxHighlightDistance(300);
|
||||
|
||||
XAxis x = chart.getXAxis();
|
||||
x.setEnabled(false);
|
||||
|
||||
YAxis y = chart.getAxisLeft();
|
||||
y.setTypeface(tfLight);
|
||||
y.setLabelCount(6, false);
|
||||
y.setTextColor(Color.WHITE);
|
||||
y.setPosition(YAxis.YAxisLabelPosition.INSIDE_CHART);
|
||||
y.setDrawGridLines(false);
|
||||
y.setAxisLineColor(Color.WHITE);
|
||||
|
||||
chart.getAxisRight().setEnabled(false);
|
||||
|
||||
// add data
|
||||
seekBarY.setOnSeekBarChangeListener(this);
|
||||
seekBarX.setOnSeekBarChangeListener(this);
|
||||
|
||||
// lower max, as cubic runs significantly slower than linear
|
||||
seekBarX.setMax(700);
|
||||
|
||||
seekBarX.setProgress(45);
|
||||
seekBarY.setProgress(100);
|
||||
|
||||
chart.getLegend().setEnabled(false);
|
||||
|
||||
chart.animateXY(2000, 2000);
|
||||
|
||||
// don't forget to refresh the drawing
|
||||
chart.invalidate();
|
||||
}
|
||||
|
||||
private void setData(int count, float range) {
|
||||
|
||||
ArrayList<Entry> values = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
float val = (float) (Math.random() * (range + 1)) + 20;
|
||||
values.add(new Entry(i, val));
|
||||
}
|
||||
|
||||
LineDataSet set1;
|
||||
|
||||
if (chart.getData() != null &&
|
||||
chart.getData().getDataSetCount() > 0) {
|
||||
set1 = (LineDataSet) chart.getData().getDataSetByIndex(0);
|
||||
set1.setValues(values);
|
||||
chart.getData().notifyDataChanged();
|
||||
chart.notifyDataSetChanged();
|
||||
} else {
|
||||
// create a dataset and give it a type
|
||||
set1 = new LineDataSet(values, "DataSet 1");
|
||||
|
||||
set1.setMode(LineDataSet.Mode.CUBIC_BEZIER);
|
||||
set1.setCubicIntensity(0.2f);
|
||||
set1.setDrawFilled(true);
|
||||
set1.setDrawCircles(false);
|
||||
set1.setLineWidth(1.8f);
|
||||
set1.setCircleRadius(4f);
|
||||
set1.setCircleColor(Color.WHITE);
|
||||
set1.setHighLightColor(Color.rgb(244, 117, 117));
|
||||
set1.setColor(Color.WHITE);
|
||||
set1.setFillColor(Color.WHITE);
|
||||
set1.setFillAlpha(100);
|
||||
set1.setDrawHorizontalHighlightIndicator(false);
|
||||
set1.setFillFormatter(new IFillFormatter() {
|
||||
@Override
|
||||
public float getFillLinePosition(ILineDataSet dataSet, LineDataProvider dataProvider) {
|
||||
return chart.getAxisLeft().getAxisMinimum();
|
||||
}
|
||||
});
|
||||
|
||||
// create a data object with the data sets
|
||||
LineData data = new LineData(set1);
|
||||
data.setValueTypeface(tfLight);
|
||||
data.setValueTextSize(9f);
|
||||
data.setDrawValues(false);
|
||||
|
||||
// set data
|
||||
chart.setData(data);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.line, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.viewGithub: {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/CubicLineChartActivity.java"));
|
||||
startActivity(i);
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleValues: {
|
||||
for (IDataSet set : chart.getData().getDataSets())
|
||||
set.setDrawValues(!set.isDrawValuesEnabled());
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleHighlight: {
|
||||
if(chart.getData() != null) {
|
||||
chart.getData().setHighlightEnabled(!chart.getData().isHighlightEnabled());
|
||||
chart.invalidate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleFilled: {
|
||||
|
||||
List<ILineDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (ILineDataSet iSet : sets) {
|
||||
|
||||
LineDataSet set = (LineDataSet) iSet;
|
||||
|
||||
if (set.isDrawFilledEnabled())
|
||||
set.setDrawFilled(false);
|
||||
else
|
||||
set.setDrawFilled(true);
|
||||
}
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleCircles: {
|
||||
List<ILineDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (ILineDataSet iSet : sets) {
|
||||
|
||||
LineDataSet set = (LineDataSet) iSet;
|
||||
if (set.isDrawCirclesEnabled())
|
||||
set.setDrawCircles(false);
|
||||
else
|
||||
set.setDrawCircles(true);
|
||||
}
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleCubic: {
|
||||
List<ILineDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (ILineDataSet iSet : sets) {
|
||||
|
||||
LineDataSet set = (LineDataSet) iSet;
|
||||
set.setMode(set.getMode() == LineDataSet.Mode.CUBIC_BEZIER
|
||||
? LineDataSet.Mode.LINEAR
|
||||
: LineDataSet.Mode.CUBIC_BEZIER);
|
||||
}
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleStepped: {
|
||||
List<ILineDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (ILineDataSet iSet : sets) {
|
||||
|
||||
LineDataSet set = (LineDataSet) iSet;
|
||||
set.setMode(set.getMode() == LineDataSet.Mode.STEPPED
|
||||
? LineDataSet.Mode.LINEAR
|
||||
: LineDataSet.Mode.STEPPED);
|
||||
}
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleHorizontalCubic: {
|
||||
List<ILineDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (ILineDataSet iSet : sets) {
|
||||
|
||||
LineDataSet set = (LineDataSet) iSet;
|
||||
set.setMode(set.getMode() == LineDataSet.Mode.HORIZONTAL_BEZIER
|
||||
? LineDataSet.Mode.LINEAR
|
||||
: LineDataSet.Mode.HORIZONTAL_BEZIER);
|
||||
}
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionTogglePinch: {
|
||||
if (chart.isPinchZoomEnabled())
|
||||
chart.setPinchZoom(false);
|
||||
else
|
||||
chart.setPinchZoom(true);
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleAutoScaleMinMax: {
|
||||
chart.setAutoScaleMinMaxEnabled(!chart.isAutoScaleMinMaxEnabled());
|
||||
chart.notifyDataSetChanged();
|
||||
break;
|
||||
}
|
||||
case R.id.animateX: {
|
||||
chart.animateX(2000);
|
||||
break;
|
||||
}
|
||||
case R.id.animateY: {
|
||||
chart.animateY(2000);
|
||||
break;
|
||||
}
|
||||
case R.id.animateXY: {
|
||||
chart.animateXY(2000, 2000);
|
||||
break;
|
||||
}
|
||||
case R.id.actionSave: {
|
||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
|
||||
saveToGallery();
|
||||
} else {
|
||||
requestStoragePermission(chart);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
|
||||
tvX.setText(String.valueOf(seekBarX.getProgress()));
|
||||
tvY.setText(String.valueOf(seekBarY.getProgress()));
|
||||
|
||||
setData(seekBarX.getProgress(), seekBarY.getProgress());
|
||||
|
||||
// redraw
|
||||
chart.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveToGallery() {
|
||||
saveToGallery(chart, "CubicLineChartActivity");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {}
|
||||
}
|
||||
+186
@@ -0,0 +1,186 @@
|
||||
// TODO: Finish and add to main activity list
|
||||
package com.android.stockapp.ui.mpchartexample;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.ui.mpchartexample.notimportant.DemoBase;
|
||||
import com.github.mikephil.charting.charts.Chart;
|
||||
import com.github.mikephil.charting.charts.LineChart;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
import com.github.mikephil.charting.data.DataSet;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.data.LineData;
|
||||
import com.github.mikephil.charting.data.LineDataSet;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
|
||||
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
|
||||
import com.github.mikephil.charting.listener.OnDrawListener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This Activity demonstrates drawing into the Chart with the finger. Both line,
|
||||
* bar and scatter charts can be used for drawing.
|
||||
*
|
||||
* @author Philipp Jahoda
|
||||
*/
|
||||
public class DrawChartActivity extends DemoBase implements OnChartValueSelectedListener,
|
||||
OnDrawListener {
|
||||
|
||||
private LineChart chart;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_draw_chart);
|
||||
|
||||
setTitle("DrawChartActivity");
|
||||
|
||||
chart = findViewById(R.id.chart1);
|
||||
|
||||
// listener for selecting and drawing
|
||||
chart.setOnChartValueSelectedListener(this);
|
||||
chart.setOnDrawListener(this);
|
||||
|
||||
// if disabled, drawn data sets with the finger will not be automatically
|
||||
// finished
|
||||
// chart.setAutoFinish(true);
|
||||
chart.setDrawGridBackground(false);
|
||||
|
||||
// add dummy-data to the chart
|
||||
initWithDummyData();
|
||||
|
||||
XAxis xl = chart.getXAxis();
|
||||
xl.setTypeface(tfRegular);
|
||||
xl.setAvoidFirstLastClipping(true);
|
||||
|
||||
YAxis yl = chart.getAxisLeft();
|
||||
yl.setTypeface(tfRegular);
|
||||
|
||||
chart.getLegend().setEnabled(false);
|
||||
|
||||
// chart.setYRange(-40f, 40f, true);
|
||||
// call this to reset the changed y-range
|
||||
// chart.resetYRange(true);
|
||||
}
|
||||
|
||||
private void initWithDummyData() {
|
||||
|
||||
ArrayList<Entry> values = new ArrayList<>();
|
||||
|
||||
// create a dataset and give it a type (0)
|
||||
LineDataSet set1 = new LineDataSet(values, "DataSet");
|
||||
set1.setLineWidth(3f);
|
||||
set1.setCircleRadius(5f);
|
||||
|
||||
// create a data object with the data sets
|
||||
LineData data = new LineData(set1);
|
||||
|
||||
chart.setData(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.draw, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.actionToggleValues: {
|
||||
List<ILineDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (ILineDataSet iSet : sets) {
|
||||
|
||||
LineDataSet set = (LineDataSet) iSet;
|
||||
set.setDrawValues(!set.isDrawValuesEnabled());
|
||||
}
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleHighlight: {
|
||||
if(chart.getData() != null) {
|
||||
chart.getData().setHighlightEnabled(!chart.getData().isHighlightEnabled());
|
||||
chart.invalidate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case R.id.actionTogglePinch: {
|
||||
if (chart.isPinchZoomEnabled())
|
||||
chart.setPinchZoom(false);
|
||||
else
|
||||
chart.setPinchZoom(true);
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleAutoScaleMinMax: {
|
||||
chart.setAutoScaleMinMaxEnabled(!chart.isAutoScaleMinMaxEnabled());
|
||||
chart.notifyDataSetChanged();
|
||||
break;
|
||||
}
|
||||
case R.id.actionSave: {
|
||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
|
||||
saveToGallery();
|
||||
} else {
|
||||
requestStoragePermission(chart);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveToGallery() {
|
||||
saveToGallery(chart, "DrawChartActivity");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onValueSelected(Entry e, Highlight h) {
|
||||
Log.i("VAL SELECTED",
|
||||
"Value: " + e.getY() + ", xIndex: " + e.getX()
|
||||
+ ", DataSet index: " + h.getDataSetIndex());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected() {
|
||||
}
|
||||
|
||||
/** callback for each new entry drawn with the finger */
|
||||
@Override
|
||||
public void onEntryAdded(Entry entry) {
|
||||
Log.i(Chart.LOG_TAG, entry.toString());
|
||||
}
|
||||
|
||||
/** callback when a DataSet has been drawn (when lifting the finger) */
|
||||
@Override
|
||||
public void onDrawFinished(DataSet<?> dataSet) {
|
||||
Log.i(Chart.LOG_TAG, "DataSet drawn. " + dataSet.toSimpleString());
|
||||
|
||||
// prepare the legend again
|
||||
chart.getLegendRenderer().computeLegend(chart.getData());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEntryMoved(Entry entry) {
|
||||
Log.i(Chart.LOG_TAG, "Point moved " + entry.toString());
|
||||
}
|
||||
}
|
||||
+244
@@ -0,0 +1,244 @@
|
||||
|
||||
package com.android.stockapp.ui.mpchartexample;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Color;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.ui.mpchartexample.notimportant.DemoBase;
|
||||
import com.github.mikephil.charting.charts.LineChart;
|
||||
import com.github.mikephil.charting.components.YAxis.AxisDependency;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.data.LineData;
|
||||
import com.github.mikephil.charting.data.LineDataSet;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
|
||||
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
|
||||
import com.github.mikephil.charting.utils.ColorTemplate;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class DynamicalAddingActivity extends DemoBase implements OnChartValueSelectedListener {
|
||||
|
||||
private LineChart chart;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_linechart_noseekbar);
|
||||
|
||||
setTitle("DynamicalAddingActivity");
|
||||
|
||||
chart = findViewById(R.id.chart1);
|
||||
chart.setOnChartValueSelectedListener(this);
|
||||
chart.setDrawGridBackground(false);
|
||||
chart.getDescription().setEnabled(false);
|
||||
chart.setNoDataText("No chart data available. Use the menu to add entries and data sets!");
|
||||
|
||||
// chart.getXAxis().setDrawLabels(false);
|
||||
// chart.getXAxis().setDrawGridLines(false);
|
||||
|
||||
chart.invalidate();
|
||||
}
|
||||
|
||||
private final int[] colors = ColorTemplate.VORDIPLOM_COLORS;
|
||||
|
||||
private void addEntry() {
|
||||
|
||||
LineData data = chart.getData();
|
||||
|
||||
if (data == null) {
|
||||
data = new LineData();
|
||||
chart.setData(data);
|
||||
}
|
||||
|
||||
ILineDataSet set = data.getDataSetByIndex(0);
|
||||
// set.addEntry(...); // can be called as well
|
||||
|
||||
if (set == null) {
|
||||
set = createSet();
|
||||
data.addDataSet(set);
|
||||
}
|
||||
|
||||
// choose a random dataSet
|
||||
int randomDataSetIndex = (int) (Math.random() * data.getDataSetCount());
|
||||
ILineDataSet randomSet = data.getDataSetByIndex(randomDataSetIndex);
|
||||
float value = (float) (Math.random() * 50) + 50f * (randomDataSetIndex + 1);
|
||||
|
||||
data.addEntry(new Entry(randomSet.getEntryCount(), value), randomDataSetIndex);
|
||||
data.notifyDataChanged();
|
||||
|
||||
// let the chart know it's data has changed
|
||||
chart.notifyDataSetChanged();
|
||||
|
||||
chart.setVisibleXRangeMaximum(6);
|
||||
//chart.setVisibleYRangeMaximum(15, AxisDependency.LEFT);
|
||||
//
|
||||
// // this automatically refreshes the chart (calls invalidate())
|
||||
chart.moveViewTo(data.getEntryCount() - 7, 50f, AxisDependency.LEFT);
|
||||
|
||||
}
|
||||
|
||||
private void removeLastEntry() {
|
||||
|
||||
LineData data = chart.getData();
|
||||
|
||||
if (data != null) {
|
||||
|
||||
ILineDataSet set = data.getDataSetByIndex(0);
|
||||
|
||||
if (set != null) {
|
||||
|
||||
Entry e = set.getEntryForXValue(set.getEntryCount() - 1, Float.NaN);
|
||||
|
||||
data.removeEntry(e, 0);
|
||||
// or remove by index
|
||||
// mData.removeEntryByXValue(xIndex, dataSetIndex);
|
||||
data.notifyDataChanged();
|
||||
chart.notifyDataSetChanged();
|
||||
chart.invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addDataSet() {
|
||||
|
||||
LineData data = chart.getData();
|
||||
|
||||
if (data == null) {
|
||||
chart.setData(new LineData());
|
||||
} else {
|
||||
int count = (data.getDataSetCount() + 1);
|
||||
int amount = data.getDataSetByIndex(0).getEntryCount();
|
||||
|
||||
ArrayList<Entry> values = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < amount; i++) {
|
||||
values.add(new Entry(i, (float) (Math.random() * 50f) + 50f * count));
|
||||
}
|
||||
|
||||
LineDataSet set = new LineDataSet(values, "DataSet " + count);
|
||||
set.setLineWidth(2.5f);
|
||||
set.setCircleRadius(4.5f);
|
||||
|
||||
int color = colors[count % colors.length];
|
||||
|
||||
set.setColor(color);
|
||||
set.setCircleColor(color);
|
||||
set.setHighLightColor(color);
|
||||
set.setValueTextSize(10f);
|
||||
set.setValueTextColor(color);
|
||||
|
||||
data.addDataSet(set);
|
||||
data.notifyDataChanged();
|
||||
chart.notifyDataSetChanged();
|
||||
chart.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
private void removeDataSet() {
|
||||
|
||||
LineData data = chart.getData();
|
||||
|
||||
if (data != null) {
|
||||
|
||||
data.removeDataSet(data.getDataSetByIndex(data.getDataSetCount() - 1));
|
||||
|
||||
chart.notifyDataSetChanged();
|
||||
chart.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
private LineDataSet createSet() {
|
||||
|
||||
LineDataSet set = new LineDataSet(null, "DataSet 1");
|
||||
set.setLineWidth(2.5f);
|
||||
set.setCircleRadius(4.5f);
|
||||
set.setColor(Color.rgb(240, 99, 99));
|
||||
set.setCircleColor(Color.rgb(240, 99, 99));
|
||||
set.setHighLightColor(Color.rgb(190, 190, 190));
|
||||
set.setAxisDependency(AxisDependency.LEFT);
|
||||
set.setValueTextSize(10f);
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onValueSelected(Entry e, Highlight h) {
|
||||
Toast.makeText(this, e.toString(), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected() {}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.dynamical, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.viewGithub: {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/DynamicalAddingActivity.java"));
|
||||
startActivity(i);
|
||||
break;
|
||||
}
|
||||
case R.id.actionAddEntry: {
|
||||
addEntry();
|
||||
Toast.makeText(this, "Entry added!", Toast.LENGTH_SHORT).show();
|
||||
break;
|
||||
}
|
||||
case R.id.actionRemoveEntry: {
|
||||
removeLastEntry();
|
||||
Toast.makeText(this, "Entry removed!", Toast.LENGTH_SHORT).show();
|
||||
break;
|
||||
}
|
||||
case R.id.actionAddDataSet: {
|
||||
addDataSet();
|
||||
Toast.makeText(this, "DataSet added!", Toast.LENGTH_SHORT).show();
|
||||
break;
|
||||
}
|
||||
case R.id.actionRemoveDataSet: {
|
||||
removeDataSet();
|
||||
Toast.makeText(this, "DataSet removed!", Toast.LENGTH_SHORT).show();
|
||||
break;
|
||||
}
|
||||
case R.id.actionClear: {
|
||||
chart.clear();
|
||||
Toast.makeText(this, "Chart cleared!", Toast.LENGTH_SHORT).show();
|
||||
break;
|
||||
}
|
||||
case R.id.actionSave: {
|
||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
|
||||
saveToGallery();
|
||||
} else {
|
||||
requestStoragePermission(chart);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveToGallery() {
|
||||
saveToGallery(chart, "DynamicalAddingActivity");
|
||||
}
|
||||
}
|
||||
+190
@@ -0,0 +1,190 @@
|
||||
|
||||
package com.android.stockapp.ui.mpchartexample;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.ui.mpchartexample.notimportant.DemoBase;
|
||||
import com.github.mikephil.charting.charts.LineChart;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.data.LineData;
|
||||
import com.github.mikephil.charting.data.LineDataSet;
|
||||
import com.github.mikephil.charting.formatter.IFillFormatter;
|
||||
import com.github.mikephil.charting.interfaces.dataprovider.LineDataProvider;
|
||||
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* This works by inverting the background and desired "fill" color. First, we draw the fill color
|
||||
* that we want between the lines as the actual background of the chart. Then, we fill the area
|
||||
* above the highest line and the area under the lowest line with the desired background color.
|
||||
*
|
||||
* This method makes it look like we filled the area between the lines, but really we are filling
|
||||
* the area OUTSIDE the lines!
|
||||
*/
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
public class FilledLineActivity extends DemoBase {
|
||||
|
||||
private LineChart chart;
|
||||
private final int fillColor = Color.argb(150, 51, 181, 229);
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_linechart_noseekbar);
|
||||
|
||||
setTitle("FilledLineActivity");
|
||||
|
||||
chart = findViewById(R.id.chart1);
|
||||
chart.setBackgroundColor(Color.WHITE);
|
||||
chart.setGridBackgroundColor(fillColor);
|
||||
chart.setDrawGridBackground(true);
|
||||
|
||||
chart.setDrawBorders(true);
|
||||
|
||||
// no description text
|
||||
chart.getDescription().setEnabled(false);
|
||||
|
||||
// if disabled, scaling can be done on x- and y-axis separately
|
||||
chart.setPinchZoom(false);
|
||||
|
||||
Legend l = chart.getLegend();
|
||||
l.setEnabled(false);
|
||||
|
||||
XAxis xAxis = chart.getXAxis();
|
||||
xAxis.setEnabled(false);
|
||||
|
||||
YAxis leftAxis = chart.getAxisLeft();
|
||||
leftAxis.setAxisMaximum(900f);
|
||||
leftAxis.setAxisMinimum(-250f);
|
||||
leftAxis.setDrawAxisLine(false);
|
||||
leftAxis.setDrawZeroLine(false);
|
||||
leftAxis.setDrawGridLines(false);
|
||||
|
||||
chart.getAxisRight().setEnabled(false);
|
||||
|
||||
// add data
|
||||
setData(100, 60);
|
||||
|
||||
chart.invalidate();
|
||||
}
|
||||
|
||||
private void setData(int count, float range) {
|
||||
|
||||
ArrayList<Entry> values1 = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
float val = (float) (Math.random() * range) + 50;
|
||||
values1.add(new Entry(i, val));
|
||||
}
|
||||
|
||||
ArrayList<Entry> values2 = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
float val = (float) (Math.random() * range) + 450;
|
||||
values2.add(new Entry(i, val));
|
||||
}
|
||||
|
||||
LineDataSet set1, set2;
|
||||
|
||||
if (chart.getData() != null &&
|
||||
chart.getData().getDataSetCount() > 0) {
|
||||
set1 = (LineDataSet) chart.getData().getDataSetByIndex(0);
|
||||
set2 = (LineDataSet) chart.getData().getDataSetByIndex(1);
|
||||
set1.setValues(values1);
|
||||
set2.setValues(values2);
|
||||
chart.getData().notifyDataChanged();
|
||||
chart.notifyDataSetChanged();
|
||||
} else {
|
||||
// create a dataset and give it a type
|
||||
set1 = new LineDataSet(values1, "DataSet 1");
|
||||
|
||||
set1.setAxisDependency(YAxis.AxisDependency.LEFT);
|
||||
set1.setColor(Color.rgb(255, 241, 46));
|
||||
set1.setDrawCircles(false);
|
||||
set1.setLineWidth(2f);
|
||||
set1.setCircleRadius(3f);
|
||||
set1.setFillAlpha(255);
|
||||
set1.setDrawFilled(true);
|
||||
set1.setFillColor(Color.WHITE);
|
||||
set1.setHighLightColor(Color.rgb(244, 117, 117));
|
||||
set1.setDrawCircleHole(false);
|
||||
set1.setFillFormatter(new IFillFormatter() {
|
||||
@Override
|
||||
public float getFillLinePosition(ILineDataSet dataSet, LineDataProvider dataProvider) {
|
||||
// change the return value here to better understand the effect
|
||||
// return 0;
|
||||
return chart.getAxisLeft().getAxisMinimum();
|
||||
}
|
||||
});
|
||||
|
||||
// create a dataset and give it a type
|
||||
set2 = new LineDataSet(values2, "DataSet 2");
|
||||
set2.setAxisDependency(YAxis.AxisDependency.LEFT);
|
||||
set2.setColor(Color.rgb(255, 241, 46));
|
||||
set2.setDrawCircles(false);
|
||||
set2.setLineWidth(2f);
|
||||
set2.setCircleRadius(3f);
|
||||
set2.setFillAlpha(255);
|
||||
set2.setDrawFilled(true);
|
||||
set2.setFillColor(Color.WHITE);
|
||||
set2.setDrawCircleHole(false);
|
||||
set2.setHighLightColor(Color.rgb(244, 117, 117));
|
||||
set2.setFillFormatter(new IFillFormatter() {
|
||||
@Override
|
||||
public float getFillLinePosition(ILineDataSet dataSet, LineDataProvider dataProvider) {
|
||||
// change the return value here to better understand the effect
|
||||
// return 600;
|
||||
return chart.getAxisLeft().getAxisMaximum();
|
||||
}
|
||||
});
|
||||
|
||||
ArrayList<ILineDataSet> dataSets = new ArrayList<>();
|
||||
dataSets.add(set1); // add the data sets
|
||||
dataSets.add(set2);
|
||||
|
||||
// create a data object with the data sets
|
||||
LineData data = new LineData(dataSets);
|
||||
data.setDrawValues(false);
|
||||
|
||||
// set data
|
||||
chart.setData(data);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.only_github, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.viewGithub: {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/FilledLineActivity.java"));
|
||||
startActivity(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveToGallery() { /* Intentionally left empty */ }
|
||||
}
|
||||
+169
@@ -0,0 +1,169 @@
|
||||
|
||||
package com.android.stockapp.ui.mpchartexample;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Typeface;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.text.SpannableString;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.text.style.RelativeSizeSpan;
|
||||
import android.text.style.StyleSpan;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.ui.mpchartexample.notimportant.DemoBase;
|
||||
import com.github.mikephil.charting.animation.Easing;
|
||||
import com.github.mikephil.charting.charts.PieChart;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.data.PieData;
|
||||
import com.github.mikephil.charting.data.PieDataSet;
|
||||
import com.github.mikephil.charting.data.PieEntry;
|
||||
import com.github.mikephil.charting.formatter.PercentFormatter;
|
||||
import com.github.mikephil.charting.utils.ColorTemplate;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
public class HalfPieChartActivity extends DemoBase {
|
||||
|
||||
private PieChart chart;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_piechart_half);
|
||||
|
||||
setTitle("HalfPieChartActivity");
|
||||
|
||||
chart = findViewById(R.id.chart1);
|
||||
chart.setBackgroundColor(Color.WHITE);
|
||||
|
||||
moveOffScreen();
|
||||
|
||||
chart.setUsePercentValues(true);
|
||||
chart.getDescription().setEnabled(false);
|
||||
|
||||
chart.setCenterTextTypeface(tfLight);
|
||||
chart.setCenterText(generateCenterSpannableText());
|
||||
|
||||
chart.setDrawHoleEnabled(true);
|
||||
chart.setHoleColor(Color.WHITE);
|
||||
|
||||
chart.setTransparentCircleColor(Color.WHITE);
|
||||
chart.setTransparentCircleAlpha(110);
|
||||
|
||||
chart.setHoleRadius(58f);
|
||||
chart.setTransparentCircleRadius(61f);
|
||||
|
||||
chart.setDrawCenterText(true);
|
||||
|
||||
chart.setRotationEnabled(false);
|
||||
chart.setHighlightPerTapEnabled(true);
|
||||
|
||||
chart.setMaxAngle(180f); // HALF CHART
|
||||
chart.setRotationAngle(180f);
|
||||
chart.setCenterTextOffset(0, -20);
|
||||
|
||||
setData(4, 100);
|
||||
|
||||
chart.animateY(1400, Easing.EaseInOutQuad);
|
||||
|
||||
Legend l = chart.getLegend();
|
||||
l.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
|
||||
l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER);
|
||||
l.setOrientation(Legend.LegendOrientation.HORIZONTAL);
|
||||
l.setDrawInside(false);
|
||||
l.setXEntrySpace(7f);
|
||||
l.setYEntrySpace(0f);
|
||||
l.setYOffset(0f);
|
||||
|
||||
// entry label styling
|
||||
chart.setEntryLabelColor(Color.WHITE);
|
||||
chart.setEntryLabelTypeface(tfRegular);
|
||||
chart.setEntryLabelTextSize(12f);
|
||||
}
|
||||
|
||||
private void setData(int count, float range) {
|
||||
|
||||
ArrayList<PieEntry> values = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
values.add(new PieEntry((float) ((Math.random() * range) + range / 5), parties[i % parties.length]));
|
||||
}
|
||||
|
||||
PieDataSet dataSet = new PieDataSet(values, "Election Results");
|
||||
dataSet.setSliceSpace(3f);
|
||||
dataSet.setSelectionShift(5f);
|
||||
|
||||
dataSet.setColors(ColorTemplate.MATERIAL_COLORS);
|
||||
//dataSet.setSelectionShift(0f);
|
||||
|
||||
PieData data = new PieData(dataSet);
|
||||
data.setValueFormatter(new PercentFormatter());
|
||||
data.setValueTextSize(11f);
|
||||
data.setValueTextColor(Color.WHITE);
|
||||
data.setValueTypeface(tfLight);
|
||||
chart.setData(data);
|
||||
|
||||
chart.invalidate();
|
||||
}
|
||||
|
||||
private SpannableString generateCenterSpannableText() {
|
||||
|
||||
SpannableString s = new SpannableString("MPAndroidChart\ndeveloped by Philipp Jahoda");
|
||||
s.setSpan(new RelativeSizeSpan(1.7f), 0, 14, 0);
|
||||
s.setSpan(new StyleSpan(Typeface.NORMAL), 14, s.length() - 15, 0);
|
||||
s.setSpan(new ForegroundColorSpan(Color.GRAY), 14, s.length() - 15, 0);
|
||||
s.setSpan(new RelativeSizeSpan(.8f), 14, s.length() - 15, 0);
|
||||
s.setSpan(new StyleSpan(Typeface.ITALIC), s.length() - 14, s.length(), 0);
|
||||
s.setSpan(new ForegroundColorSpan(ColorTemplate.getHoloBlue()), s.length() - 14, s.length(), 0);
|
||||
return s;
|
||||
}
|
||||
|
||||
private void moveOffScreen() {
|
||||
|
||||
DisplayMetrics displayMetrics = new DisplayMetrics();
|
||||
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
|
||||
|
||||
int height = displayMetrics.heightPixels;
|
||||
|
||||
int offset = (int)(height * 0.65); /* percent to move */
|
||||
|
||||
RelativeLayout.LayoutParams rlParams =
|
||||
(RelativeLayout.LayoutParams) chart.getLayoutParams();
|
||||
rlParams.setMargins(0, 0, 0, -offset);
|
||||
chart.setLayoutParams(rlParams);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.only_github, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.viewGithub: {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/HalfPieChartActivity.java"));
|
||||
startActivity(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveToGallery() { /* Intentionally left empty */ }
|
||||
}
|
||||
+293
@@ -0,0 +1,293 @@
|
||||
|
||||
package com.android.stockapp.ui.mpchartexample;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.RectF;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.SeekBar.OnSeekBarChangeListener;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.ui.mpchartexample.notimportant.DemoBase;
|
||||
import com.github.mikephil.charting.charts.HorizontalBarChart;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.XAxis.XAxisPosition;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
import com.github.mikephil.charting.data.BarData;
|
||||
import com.github.mikephil.charting.data.BarDataSet;
|
||||
import com.github.mikephil.charting.data.BarEntry;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IBarDataSet;
|
||||
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
|
||||
import com.github.mikephil.charting.utils.MPPointF;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class HorizontalBarChartActivity extends DemoBase implements OnSeekBarChangeListener,
|
||||
OnChartValueSelectedListener {
|
||||
|
||||
private HorizontalBarChart chart;
|
||||
private SeekBar seekBarX, seekBarY;
|
||||
private TextView tvX, tvY;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_horizontalbarchart);
|
||||
|
||||
setTitle("HorizontalBarChartActivity");
|
||||
|
||||
tvX = findViewById(R.id.tvXMax);
|
||||
tvY = findViewById(R.id.tvYMax);
|
||||
|
||||
seekBarX = findViewById(R.id.seekBar1);
|
||||
seekBarY = findViewById(R.id.seekBar2);
|
||||
|
||||
seekBarY.setOnSeekBarChangeListener(this);
|
||||
seekBarX.setOnSeekBarChangeListener(this);
|
||||
|
||||
chart = findViewById(R.id.chart1);
|
||||
chart.setOnChartValueSelectedListener(this);
|
||||
// chart.setHighlightEnabled(false);
|
||||
|
||||
chart.setDrawBarShadow(false);
|
||||
|
||||
chart.setDrawValueAboveBar(true);
|
||||
|
||||
chart.getDescription().setEnabled(false);
|
||||
|
||||
// if more than 60 entries are displayed in the chart, no values will be
|
||||
// drawn
|
||||
chart.setMaxVisibleValueCount(60);
|
||||
|
||||
// scaling can now only be done on x- and y-axis separately
|
||||
chart.setPinchZoom(false);
|
||||
|
||||
// draw shadows for each bar that show the maximum value
|
||||
// chart.setDrawBarShadow(true);
|
||||
|
||||
chart.setDrawGridBackground(false);
|
||||
|
||||
XAxis xl = chart.getXAxis();
|
||||
xl.setPosition(XAxisPosition.BOTTOM);
|
||||
xl.setTypeface(tfLight);
|
||||
xl.setDrawAxisLine(true);
|
||||
xl.setDrawGridLines(false);
|
||||
xl.setGranularity(10f);
|
||||
|
||||
YAxis yl = chart.getAxisLeft();
|
||||
yl.setTypeface(tfLight);
|
||||
yl.setDrawAxisLine(true);
|
||||
yl.setDrawGridLines(true);
|
||||
yl.setAxisMinimum(0f); // this replaces setStartAtZero(true)
|
||||
// yl.setInverted(true);
|
||||
|
||||
YAxis yr = chart.getAxisRight();
|
||||
yr.setTypeface(tfLight);
|
||||
yr.setDrawAxisLine(true);
|
||||
yr.setDrawGridLines(false);
|
||||
yr.setAxisMinimum(0f); // this replaces setStartAtZero(true)
|
||||
// yr.setInverted(true);
|
||||
|
||||
chart.setFitBars(true);
|
||||
chart.animateY(2500);
|
||||
|
||||
// setting data
|
||||
seekBarY.setProgress(50);
|
||||
seekBarX.setProgress(12);
|
||||
|
||||
Legend l = chart.getLegend();
|
||||
l.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);
|
||||
l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.LEFT);
|
||||
l.setOrientation(Legend.LegendOrientation.HORIZONTAL);
|
||||
l.setDrawInside(false);
|
||||
l.setFormSize(8f);
|
||||
l.setXEntrySpace(4f);
|
||||
}
|
||||
|
||||
private void setData(int count, float range) {
|
||||
|
||||
float barWidth = 9f;
|
||||
float spaceForBar = 10f;
|
||||
ArrayList<BarEntry> values = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
float val = (float) (Math.random() * range);
|
||||
values.add(new BarEntry(i * spaceForBar, val,
|
||||
getResources().getDrawable(R.drawable.star)));
|
||||
}
|
||||
|
||||
BarDataSet set1;
|
||||
|
||||
if (chart.getData() != null &&
|
||||
chart.getData().getDataSetCount() > 0) {
|
||||
set1 = (BarDataSet) chart.getData().getDataSetByIndex(0);
|
||||
set1.setValues(values);
|
||||
chart.getData().notifyDataChanged();
|
||||
chart.notifyDataSetChanged();
|
||||
} else {
|
||||
set1 = new BarDataSet(values, "DataSet 1");
|
||||
|
||||
set1.setDrawIcons(false);
|
||||
|
||||
ArrayList<IBarDataSet> dataSets = new ArrayList<>();
|
||||
dataSets.add(set1);
|
||||
|
||||
BarData data = new BarData(dataSets);
|
||||
data.setValueTextSize(10f);
|
||||
data.setValueTypeface(tfLight);
|
||||
data.setBarWidth(barWidth);
|
||||
chart.setData(data);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.bar, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.viewGithub: {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/HorizontalBarChartActivity.java"));
|
||||
startActivity(i);
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleValues: {
|
||||
List<IBarDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (IBarDataSet iSet : sets) {
|
||||
iSet.setDrawValues(!iSet.isDrawValuesEnabled());
|
||||
}
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleIcons: {
|
||||
List<IBarDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (IBarDataSet iSet : sets) {
|
||||
iSet.setDrawIcons(!iSet.isDrawIconsEnabled());
|
||||
}
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleHighlight: {
|
||||
if(chart.getData() != null) {
|
||||
chart.getData().setHighlightEnabled(!chart.getData().isHighlightEnabled());
|
||||
chart.invalidate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case R.id.actionTogglePinch: {
|
||||
if (chart.isPinchZoomEnabled())
|
||||
chart.setPinchZoom(false);
|
||||
else
|
||||
chart.setPinchZoom(true);
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleAutoScaleMinMax: {
|
||||
chart.setAutoScaleMinMaxEnabled(!chart.isAutoScaleMinMaxEnabled());
|
||||
chart.notifyDataSetChanged();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleBarBorders: {
|
||||
for (IBarDataSet set : chart.getData().getDataSets())
|
||||
((BarDataSet)set).setBarBorderWidth(set.getBarBorderWidth() == 1.f ? 0.f : 1.f);
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.animateX: {
|
||||
chart.animateX(2000);
|
||||
break;
|
||||
}
|
||||
case R.id.animateY: {
|
||||
chart.animateY(2000);
|
||||
break;
|
||||
}
|
||||
case R.id.animateXY: {
|
||||
chart.animateXY(2000, 2000);
|
||||
break;
|
||||
}
|
||||
case R.id.actionSave: {
|
||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
|
||||
saveToGallery();
|
||||
} else {
|
||||
requestStoragePermission(chart);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
|
||||
tvX.setText(String.valueOf(seekBarX.getProgress()));
|
||||
tvY.setText(String.valueOf(seekBarY.getProgress()));
|
||||
|
||||
setData(seekBarX.getProgress(), seekBarY.getProgress());
|
||||
chart.setFitBars(true);
|
||||
chart.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveToGallery() {
|
||||
saveToGallery(chart, "HorizontalBarChartActivity");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {}
|
||||
|
||||
private final RectF mOnValueSelectedRectF = new RectF();
|
||||
|
||||
@Override
|
||||
public void onValueSelected(Entry e, Highlight h) {
|
||||
|
||||
if (e == null)
|
||||
return;
|
||||
|
||||
RectF bounds = mOnValueSelectedRectF;
|
||||
chart.getBarBounds((BarEntry) e, bounds);
|
||||
|
||||
MPPointF position = chart.getPosition(e, chart.getData().getDataSetByIndex(h.getDataSetIndex())
|
||||
.getAxisDependency());
|
||||
|
||||
Log.i("bounds", bounds.toString());
|
||||
Log.i("position", position.toString());
|
||||
|
||||
MPPointF.recycleInstance(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected() {}
|
||||
}
|
||||
+285
@@ -0,0 +1,285 @@
|
||||
|
||||
package com.android.stockapp.ui.mpchartexample;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.SeekBar.OnSeekBarChangeListener;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.ui.mpchartexample.custom.MyMarkerView;
|
||||
import com.android.stockapp.ui.mpchartexample.notimportant.DemoBase;
|
||||
import com.github.mikephil.charting.charts.LineChart;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.components.Legend.LegendForm;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.data.LineData;
|
||||
import com.github.mikephil.charting.data.LineDataSet;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
|
||||
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
|
||||
import com.github.mikephil.charting.utils.EntryXComparator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class InvertedLineChartActivity extends DemoBase implements OnSeekBarChangeListener,
|
||||
OnChartValueSelectedListener {
|
||||
|
||||
private LineChart chart;
|
||||
private SeekBar seekBarX, seekBarY;
|
||||
private TextView tvX, tvY;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_linechart);
|
||||
|
||||
setTitle("InvertedLineChartActivity");
|
||||
|
||||
tvX = findViewById(R.id.tvXMax);
|
||||
tvY = findViewById(R.id.tvYMax);
|
||||
|
||||
seekBarX = findViewById(R.id.seekBar1);
|
||||
seekBarY = findViewById(R.id.seekBar2);
|
||||
|
||||
seekBarY.setOnSeekBarChangeListener(this);
|
||||
seekBarX.setOnSeekBarChangeListener(this);
|
||||
|
||||
chart = findViewById(R.id.chart1);
|
||||
chart.setOnChartValueSelectedListener(this);
|
||||
chart.setDrawGridBackground(false);
|
||||
|
||||
// no description text
|
||||
chart.getDescription().setEnabled(false);
|
||||
|
||||
// enable touch gestures
|
||||
chart.setTouchEnabled(true);
|
||||
|
||||
// enable scaling and dragging
|
||||
chart.setDragEnabled(true);
|
||||
chart.setScaleEnabled(true);
|
||||
|
||||
// if disabled, scaling can be done on x- and y-axis separately
|
||||
chart.setPinchZoom(true);
|
||||
|
||||
// set an alternative background color
|
||||
// chart.setBackgroundColor(Color.GRAY);
|
||||
|
||||
// create a custom MarkerView (extend MarkerView) and specify the layout
|
||||
// to use for it
|
||||
MyMarkerView mv = new MyMarkerView(this, R.layout.custom_marker_view);
|
||||
mv.setChartView(chart); // For bounds control
|
||||
chart.setMarker(mv); // Set the marker to the chart
|
||||
|
||||
XAxis xl = chart.getXAxis();
|
||||
xl.setAvoidFirstLastClipping(true);
|
||||
xl.setAxisMinimum(0f);
|
||||
|
||||
YAxis leftAxis = chart.getAxisLeft();
|
||||
leftAxis.setInverted(true);
|
||||
leftAxis.setAxisMinimum(0f); // this replaces setStartAtZero(true)
|
||||
|
||||
YAxis rightAxis = chart.getAxisRight();
|
||||
rightAxis.setEnabled(false);
|
||||
|
||||
// add data
|
||||
seekBarX.setProgress(25);
|
||||
seekBarY.setProgress(50);
|
||||
|
||||
// // restrain the maximum scale-out factor
|
||||
// chart.setScaleMinima(3f, 3f);
|
||||
//
|
||||
// // center the view to a specific position inside the chart
|
||||
// chart.centerViewPort(10, 50);
|
||||
|
||||
// get the legend (only possible after setting data)
|
||||
Legend l = chart.getLegend();
|
||||
|
||||
// modify the legend ...
|
||||
l.setForm(LegendForm.LINE);
|
||||
|
||||
// don't forget to refresh the drawing
|
||||
chart.invalidate();
|
||||
}
|
||||
|
||||
private void setData(int count, float range) {
|
||||
|
||||
ArrayList<Entry> entries = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
float xVal = (float) (Math.random() * range);
|
||||
float yVal = (float) (Math.random() * range);
|
||||
entries.add(new Entry(xVal, yVal));
|
||||
}
|
||||
|
||||
// sort by x-value
|
||||
Collections.sort(entries, new EntryXComparator());
|
||||
|
||||
// create a dataset and give it a type
|
||||
LineDataSet set1 = new LineDataSet(entries, "DataSet 1");
|
||||
|
||||
set1.setLineWidth(1.5f);
|
||||
set1.setCircleRadius(4f);
|
||||
|
||||
// create a data object with the data sets
|
||||
LineData data = new LineData(set1);
|
||||
|
||||
// set data
|
||||
chart.setData(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.line, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.viewGithub: {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/InvertedLineChartActivity.java"));
|
||||
startActivity(i);
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleValues: {
|
||||
List<ILineDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (ILineDataSet iSet : sets) {
|
||||
|
||||
LineDataSet set = (LineDataSet) iSet;
|
||||
set.setDrawValues(!set.isDrawValuesEnabled());
|
||||
}
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleHighlight: {
|
||||
if(chart.getData() != null) {
|
||||
chart.getData().setHighlightEnabled(!chart.getData().isHighlightEnabled());
|
||||
chart.invalidate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleFilled: {
|
||||
|
||||
List<ILineDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (ILineDataSet iSet : sets) {
|
||||
|
||||
LineDataSet set = (LineDataSet) iSet;
|
||||
if (set.isDrawFilledEnabled())
|
||||
set.setDrawFilled(false);
|
||||
else
|
||||
set.setDrawFilled(true);
|
||||
}
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleCircles: {
|
||||
List<ILineDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (ILineDataSet iSet : sets) {
|
||||
|
||||
LineDataSet set = (LineDataSet) iSet;
|
||||
if (set.isDrawCirclesEnabled())
|
||||
set.setDrawCircles(false);
|
||||
else
|
||||
set.setDrawCircles(true);
|
||||
}
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.animateX: {
|
||||
chart.animateX(2000);
|
||||
break;
|
||||
}
|
||||
case R.id.animateY: {
|
||||
chart.animateY(2000);
|
||||
break;
|
||||
}
|
||||
case R.id.animateXY: {
|
||||
|
||||
chart.animateXY(2000, 2000);
|
||||
break;
|
||||
}
|
||||
case R.id.actionTogglePinch: {
|
||||
if (chart.isPinchZoomEnabled())
|
||||
chart.setPinchZoom(false);
|
||||
else
|
||||
chart.setPinchZoom(true);
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleAutoScaleMinMax: {
|
||||
chart.setAutoScaleMinMaxEnabled(!chart.isAutoScaleMinMaxEnabled());
|
||||
chart.notifyDataSetChanged();
|
||||
break;
|
||||
}
|
||||
case R.id.actionSave: {
|
||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
|
||||
saveToGallery();
|
||||
} else {
|
||||
requestStoragePermission(chart);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
|
||||
tvX.setText(String.valueOf(seekBarX.getProgress()));
|
||||
tvY.setText(String.valueOf(seekBarY.getProgress()));
|
||||
|
||||
setData(seekBarX.getProgress(), seekBarY.getProgress());
|
||||
|
||||
// redraw
|
||||
chart.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveToGallery() {
|
||||
saveToGallery(chart, "InvertedLineChartActivity");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onValueSelected(Entry e, Highlight h) {
|
||||
Log.i("VAL SELECTED",
|
||||
"Value: " + e.getY() + ", xIndex: " + e.getX()
|
||||
+ ", DataSet index: " + h.getDataSetIndex());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected() {}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {}
|
||||
}
|
||||
+456
@@ -0,0 +1,456 @@
|
||||
|
||||
package com.android.stockapp.ui.mpchartexample;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.DashPathEffect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.SeekBar.OnSeekBarChangeListener;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.ui.mpchartexample.custom.MyMarkerView;
|
||||
import com.android.stockapp.ui.mpchartexample.notimportant.DemoBase;
|
||||
import com.github.mikephil.charting.animation.Easing;
|
||||
import com.github.mikephil.charting.charts.LineChart;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.components.Legend.LegendForm;
|
||||
import com.github.mikephil.charting.components.LimitLine;
|
||||
import com.github.mikephil.charting.components.LimitLine.LimitLabelPosition;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.data.LineData;
|
||||
import com.github.mikephil.charting.data.LineDataSet;
|
||||
import com.github.mikephil.charting.formatter.IFillFormatter;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.interfaces.dataprovider.LineDataProvider;
|
||||
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
|
||||
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
|
||||
import com.github.mikephil.charting.utils.Utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Example of a heavily customized {@link LineChart} with limit lines, custom line shapes, etc.
|
||||
*
|
||||
* @since 1.7.4
|
||||
* @version 3.1.0
|
||||
*/
|
||||
public class LineChartActivity1 extends DemoBase implements OnSeekBarChangeListener,
|
||||
OnChartValueSelectedListener {
|
||||
|
||||
private LineChart chart;
|
||||
private SeekBar seekBarX, seekBarY;
|
||||
private TextView tvX, tvY;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_linechart);
|
||||
|
||||
setTitle("LineChartActivity1");
|
||||
|
||||
tvX = findViewById(R.id.tvXMax);
|
||||
tvY = findViewById(R.id.tvYMax);
|
||||
|
||||
seekBarX = findViewById(R.id.seekBar1);
|
||||
seekBarX.setOnSeekBarChangeListener(this);
|
||||
|
||||
seekBarY = findViewById(R.id.seekBar2);
|
||||
seekBarY.setMax(180);
|
||||
seekBarY.setOnSeekBarChangeListener(this);
|
||||
|
||||
|
||||
{ // // Chart Style // //
|
||||
chart = findViewById(R.id.chart1);
|
||||
|
||||
// background color
|
||||
chart.setBackgroundColor(Color.WHITE);
|
||||
|
||||
// disable description text
|
||||
chart.getDescription().setEnabled(false);
|
||||
|
||||
// enable touch gestures
|
||||
chart.setTouchEnabled(true);
|
||||
|
||||
// set listeners
|
||||
chart.setOnChartValueSelectedListener(this);
|
||||
chart.setDrawGridBackground(false);
|
||||
|
||||
// create marker to display box when values are selected
|
||||
MyMarkerView mv = new MyMarkerView(this, R.layout.custom_marker_view);
|
||||
|
||||
// Set the marker to the chart
|
||||
mv.setChartView(chart);
|
||||
chart.setMarker(mv);
|
||||
|
||||
// enable scaling and dragging
|
||||
chart.setDragEnabled(true);
|
||||
chart.setScaleEnabled(true);
|
||||
// chart.setScaleXEnabled(true);
|
||||
// chart.setScaleYEnabled(true);
|
||||
|
||||
// force pinch zoom along both axis
|
||||
chart.setPinchZoom(true);
|
||||
}
|
||||
|
||||
XAxis xAxis;
|
||||
{ // // X-Axis Style // //
|
||||
xAxis = chart.getXAxis();
|
||||
|
||||
// vertical grid lines
|
||||
xAxis.enableGridDashedLine(10f, 10f, 0f);
|
||||
}
|
||||
|
||||
YAxis yAxis;
|
||||
{ // // Y-Axis Style // //
|
||||
yAxis = chart.getAxisLeft();
|
||||
|
||||
// disable dual axis (only use LEFT axis)
|
||||
chart.getAxisRight().setEnabled(false);
|
||||
|
||||
// horizontal grid lines
|
||||
yAxis.enableGridDashedLine(10f, 10f, 0f);
|
||||
|
||||
// axis range
|
||||
yAxis.setAxisMaximum(200f);
|
||||
yAxis.setAxisMinimum(-50f);
|
||||
}
|
||||
|
||||
|
||||
{ // // Create Limit Lines // //
|
||||
LimitLine llXAxis = new LimitLine(9f, "Index 10");
|
||||
llXAxis.setLineWidth(4f);
|
||||
llXAxis.enableDashedLine(10f, 10f, 0f);
|
||||
llXAxis.setLabelPosition(LimitLabelPosition.RIGHT_BOTTOM);
|
||||
llXAxis.setTextSize(10f);
|
||||
llXAxis.setTypeface(tfRegular);
|
||||
|
||||
LimitLine ll1 = new LimitLine(150f, "Upper Limit");
|
||||
ll1.setLineWidth(4f);
|
||||
ll1.enableDashedLine(10f, 10f, 0f);
|
||||
ll1.setLabelPosition(LimitLabelPosition.RIGHT_TOP);
|
||||
ll1.setTextSize(10f);
|
||||
ll1.setTypeface(tfRegular);
|
||||
|
||||
LimitLine ll2 = new LimitLine(-30f, "Lower Limit");
|
||||
ll2.setLineWidth(4f);
|
||||
ll2.enableDashedLine(10f, 10f, 0f);
|
||||
ll2.setLabelPosition(LimitLabelPosition.RIGHT_BOTTOM);
|
||||
ll2.setTextSize(10f);
|
||||
ll2.setTypeface(tfRegular);
|
||||
|
||||
// draw limit lines behind data instead of on top
|
||||
yAxis.setDrawLimitLinesBehindData(true);
|
||||
xAxis.setDrawLimitLinesBehindData(true);
|
||||
|
||||
// add limit lines
|
||||
yAxis.addLimitLine(ll1);
|
||||
yAxis.addLimitLine(ll2);
|
||||
//xAxis.addLimitLine(llXAxis);
|
||||
}
|
||||
|
||||
// add data
|
||||
seekBarX.setProgress(45);
|
||||
seekBarY.setProgress(180);
|
||||
setData(45, 180);
|
||||
|
||||
// draw points over time
|
||||
chart.animateX(1500);
|
||||
|
||||
// get the legend (only possible after setting data)
|
||||
Legend l = chart.getLegend();
|
||||
|
||||
// draw legend entries as lines
|
||||
l.setForm(LegendForm.LINE);
|
||||
}
|
||||
|
||||
private void setData(int count, float range) {
|
||||
|
||||
ArrayList<Entry> values = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
|
||||
float val = (float) (Math.random() * range) - 30;
|
||||
values.add(new Entry(i, val, getResources().getDrawable(R.drawable.star)));
|
||||
}
|
||||
|
||||
LineDataSet set1;
|
||||
|
||||
if (chart.getData() != null &&
|
||||
chart.getData().getDataSetCount() > 0) {
|
||||
set1 = (LineDataSet) chart.getData().getDataSetByIndex(0);
|
||||
set1.setValues(values);
|
||||
set1.notifyDataSetChanged();
|
||||
chart.getData().notifyDataChanged();
|
||||
chart.notifyDataSetChanged();
|
||||
} else {
|
||||
// create a dataset and give it a type
|
||||
set1 = new LineDataSet(values, "DataSet 1");
|
||||
|
||||
set1.setDrawIcons(false);
|
||||
|
||||
// draw dashed line
|
||||
set1.enableDashedLine(10f, 5f, 0f);
|
||||
|
||||
// black lines and points
|
||||
set1.setColor(Color.BLACK);
|
||||
set1.setCircleColor(Color.BLACK);
|
||||
|
||||
// line thickness and point size
|
||||
set1.setLineWidth(1f);
|
||||
set1.setCircleRadius(3f);
|
||||
|
||||
// draw points as solid circles
|
||||
set1.setDrawCircleHole(false);
|
||||
|
||||
// customize legend entry
|
||||
set1.setFormLineWidth(1f);
|
||||
set1.setFormLineDashEffect(new DashPathEffect(new float[]{10f, 5f}, 0f));
|
||||
set1.setFormSize(15.f);
|
||||
|
||||
// text size of values
|
||||
set1.setValueTextSize(9f);
|
||||
|
||||
// draw selection line as dashed
|
||||
set1.enableDashedHighlightLine(10f, 5f, 0f);
|
||||
|
||||
// set the filled area
|
||||
set1.setDrawFilled(true);
|
||||
set1.setFillFormatter(new IFillFormatter() {
|
||||
@Override
|
||||
public float getFillLinePosition(ILineDataSet dataSet, LineDataProvider dataProvider) {
|
||||
return chart.getAxisLeft().getAxisMinimum();
|
||||
}
|
||||
});
|
||||
|
||||
// set color of filled area
|
||||
if (Utils.getSDKInt() >= 18) {
|
||||
// drawables only supported on api level 18 and above
|
||||
Drawable drawable = ContextCompat.getDrawable(this, R.drawable.fade_red);
|
||||
set1.setFillDrawable(drawable);
|
||||
} else {
|
||||
set1.setFillColor(Color.BLACK);
|
||||
}
|
||||
|
||||
ArrayList<ILineDataSet> dataSets = new ArrayList<>();
|
||||
dataSets.add(set1); // add the data sets
|
||||
|
||||
// create a data object with the data sets
|
||||
LineData data = new LineData(dataSets);
|
||||
|
||||
// set data
|
||||
chart.setData(data);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.line, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.viewGithub: {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/LineChartActivity1.java"));
|
||||
startActivity(i);
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleValues: {
|
||||
List<ILineDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (ILineDataSet iSet : sets) {
|
||||
|
||||
LineDataSet set = (LineDataSet) iSet;
|
||||
set.setDrawValues(!set.isDrawValuesEnabled());
|
||||
}
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleIcons: {
|
||||
List<ILineDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (ILineDataSet iSet : sets) {
|
||||
|
||||
LineDataSet set = (LineDataSet) iSet;
|
||||
set.setDrawIcons(!set.isDrawIconsEnabled());
|
||||
}
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleHighlight: {
|
||||
if(chart.getData() != null) {
|
||||
chart.getData().setHighlightEnabled(!chart.getData().isHighlightEnabled());
|
||||
chart.invalidate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleFilled: {
|
||||
|
||||
List<ILineDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (ILineDataSet iSet : sets) {
|
||||
|
||||
LineDataSet set = (LineDataSet) iSet;
|
||||
if (set.isDrawFilledEnabled())
|
||||
set.setDrawFilled(false);
|
||||
else
|
||||
set.setDrawFilled(true);
|
||||
}
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleCircles: {
|
||||
List<ILineDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (ILineDataSet iSet : sets) {
|
||||
|
||||
LineDataSet set = (LineDataSet) iSet;
|
||||
if (set.isDrawCirclesEnabled())
|
||||
set.setDrawCircles(false);
|
||||
else
|
||||
set.setDrawCircles(true);
|
||||
}
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleCubic: {
|
||||
List<ILineDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (ILineDataSet iSet : sets) {
|
||||
|
||||
LineDataSet set = (LineDataSet) iSet;
|
||||
set.setMode(set.getMode() == LineDataSet.Mode.CUBIC_BEZIER
|
||||
? LineDataSet.Mode.LINEAR
|
||||
: LineDataSet.Mode.CUBIC_BEZIER);
|
||||
}
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleStepped: {
|
||||
List<ILineDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (ILineDataSet iSet : sets) {
|
||||
|
||||
LineDataSet set = (LineDataSet) iSet;
|
||||
set.setMode(set.getMode() == LineDataSet.Mode.STEPPED
|
||||
? LineDataSet.Mode.LINEAR
|
||||
: LineDataSet.Mode.STEPPED);
|
||||
}
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleHorizontalCubic: {
|
||||
List<ILineDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (ILineDataSet iSet : sets) {
|
||||
|
||||
LineDataSet set = (LineDataSet) iSet;
|
||||
set.setMode(set.getMode() == LineDataSet.Mode.HORIZONTAL_BEZIER
|
||||
? LineDataSet.Mode.LINEAR
|
||||
: LineDataSet.Mode.HORIZONTAL_BEZIER);
|
||||
}
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionTogglePinch: {
|
||||
if (chart.isPinchZoomEnabled())
|
||||
chart.setPinchZoom(false);
|
||||
else
|
||||
chart.setPinchZoom(true);
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleAutoScaleMinMax: {
|
||||
chart.setAutoScaleMinMaxEnabled(!chart.isAutoScaleMinMaxEnabled());
|
||||
chart.notifyDataSetChanged();
|
||||
break;
|
||||
}
|
||||
case R.id.animateX: {
|
||||
chart.animateX(2000);
|
||||
break;
|
||||
}
|
||||
case R.id.animateY: {
|
||||
chart.animateY(2000, Easing.EaseInCubic);
|
||||
break;
|
||||
}
|
||||
case R.id.animateXY: {
|
||||
chart.animateXY(2000, 2000);
|
||||
break;
|
||||
}
|
||||
case R.id.actionSave: {
|
||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
|
||||
saveToGallery();
|
||||
} else {
|
||||
requestStoragePermission(chart);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
|
||||
tvX.setText(String.valueOf(seekBarX.getProgress()));
|
||||
tvY.setText(String.valueOf(seekBarY.getProgress()));
|
||||
|
||||
setData(seekBarX.getProgress(), seekBarY.getProgress());
|
||||
|
||||
// redraw
|
||||
chart.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveToGallery() {
|
||||
saveToGallery(chart, "LineChartActivity1");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {}
|
||||
|
||||
@Override
|
||||
public void onValueSelected(Entry e, Highlight h) {
|
||||
Log.i("Entry selected", e.toString());
|
||||
Log.i("LOW HIGH", "low: " + chart.getLowestVisibleX() + ", high: " + chart.getHighestVisibleX());
|
||||
Log.i("MIN MAX", "xMin: " + chart.getXChartMin() + ", xMax: " + chart.getXChartMax() + ", yMin: " + chart.getYChartMin() + ", yMax: " + chart.getYChartMax());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected() {
|
||||
Log.i("Nothing selected", "Nothing selected.");
|
||||
}
|
||||
}
|
||||
+411
@@ -0,0 +1,411 @@
|
||||
|
||||
package com.android.stockapp.ui.mpchartexample;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Color;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.SeekBar.OnSeekBarChangeListener;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.ui.mpchartexample.notimportant.DemoBase;
|
||||
import com.github.mikephil.charting.charts.LineChart;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.components.Legend.LegendForm;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
import com.github.mikephil.charting.components.YAxis.AxisDependency;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.data.LineData;
|
||||
import com.github.mikephil.charting.data.LineDataSet;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
|
||||
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
|
||||
import com.github.mikephil.charting.utils.ColorTemplate;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Example of a dual axis {@link LineChart} with multiple data sets.
|
||||
*
|
||||
* @since 1.7.4
|
||||
* @version 3.1.0
|
||||
*/
|
||||
public class LineChartActivity2 extends DemoBase implements OnSeekBarChangeListener,
|
||||
OnChartValueSelectedListener {
|
||||
|
||||
private LineChart chart;
|
||||
private SeekBar seekBarX, seekBarY;
|
||||
private TextView tvX, tvY;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_linechart);
|
||||
|
||||
setTitle("LineChartActivity2");
|
||||
|
||||
tvX = findViewById(R.id.tvXMax);
|
||||
tvY = findViewById(R.id.tvYMax);
|
||||
|
||||
seekBarX = findViewById(R.id.seekBar1);
|
||||
seekBarX.setOnSeekBarChangeListener(this);
|
||||
|
||||
seekBarY = findViewById(R.id.seekBar2);
|
||||
seekBarY.setOnSeekBarChangeListener(this);
|
||||
|
||||
chart = findViewById(R.id.chart1);
|
||||
chart.setOnChartValueSelectedListener(this);
|
||||
|
||||
// no description text
|
||||
chart.getDescription().setEnabled(false);
|
||||
|
||||
// enable touch gestures
|
||||
chart.setTouchEnabled(true);
|
||||
|
||||
chart.setDragDecelerationFrictionCoef(0.9f);
|
||||
|
||||
// enable scaling and dragging
|
||||
chart.setDragEnabled(true);
|
||||
chart.setScaleEnabled(true);
|
||||
chart.setDrawGridBackground(false);
|
||||
chart.setHighlightPerDragEnabled(true);
|
||||
|
||||
// if disabled, scaling can be done on x- and y-axis separately
|
||||
chart.setPinchZoom(true);
|
||||
|
||||
// set an alternative background color
|
||||
chart.setBackgroundColor(Color.LTGRAY);
|
||||
|
||||
// add data
|
||||
seekBarX.setProgress(20);
|
||||
seekBarY.setProgress(30);
|
||||
|
||||
chart.animateX(1500);
|
||||
|
||||
// get the legend (only possible after setting data)
|
||||
Legend l = chart.getLegend();
|
||||
|
||||
// modify the legend ...
|
||||
l.setForm(LegendForm.LINE);
|
||||
l.setTypeface(tfLight);
|
||||
l.setTextSize(11f);
|
||||
l.setTextColor(Color.WHITE);
|
||||
l.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);
|
||||
l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.LEFT);
|
||||
l.setOrientation(Legend.LegendOrientation.HORIZONTAL);
|
||||
l.setDrawInside(false);
|
||||
// l.setYOffset(11f);
|
||||
|
||||
XAxis xAxis = chart.getXAxis();
|
||||
xAxis.setTypeface(tfLight);
|
||||
xAxis.setTextSize(11f);
|
||||
xAxis.setTextColor(Color.WHITE);
|
||||
xAxis.setDrawGridLines(false);
|
||||
xAxis.setDrawAxisLine(false);
|
||||
|
||||
YAxis leftAxis = chart.getAxisLeft();
|
||||
leftAxis.setTypeface(tfLight);
|
||||
leftAxis.setTextColor(ColorTemplate.getHoloBlue());
|
||||
leftAxis.setAxisMaximum(200f);
|
||||
leftAxis.setAxisMinimum(0f);
|
||||
leftAxis.setDrawGridLines(true);
|
||||
leftAxis.setGranularityEnabled(true);
|
||||
|
||||
YAxis rightAxis = chart.getAxisRight();
|
||||
rightAxis.setTypeface(tfLight);
|
||||
rightAxis.setTextColor(Color.RED);
|
||||
rightAxis.setAxisMaximum(900);
|
||||
rightAxis.setAxisMinimum(-200);
|
||||
rightAxis.setDrawGridLines(false);
|
||||
rightAxis.setDrawZeroLine(false);
|
||||
rightAxis.setGranularityEnabled(false);
|
||||
}
|
||||
|
||||
private void setData(int count, float range) {
|
||||
|
||||
ArrayList<Entry> values1 = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
float val = (float) (Math.random() * (range / 2f)) + 50;
|
||||
values1.add(new Entry(i, val));
|
||||
}
|
||||
|
||||
ArrayList<Entry> values2 = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
float val = (float) (Math.random() * range) + 450;
|
||||
values2.add(new Entry(i, val));
|
||||
}
|
||||
|
||||
ArrayList<Entry> values3 = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
float val = (float) (Math.random() * range) + 500;
|
||||
values3.add(new Entry(i, val));
|
||||
}
|
||||
|
||||
LineDataSet set1, set2, set3;
|
||||
|
||||
if (chart.getData() != null &&
|
||||
chart.getData().getDataSetCount() > 0) {
|
||||
set1 = (LineDataSet) chart.getData().getDataSetByIndex(0);
|
||||
set2 = (LineDataSet) chart.getData().getDataSetByIndex(1);
|
||||
set3 = (LineDataSet) chart.getData().getDataSetByIndex(2);
|
||||
set1.setValues(values1);
|
||||
set2.setValues(values2);
|
||||
set3.setValues(values3);
|
||||
chart.getData().notifyDataChanged();
|
||||
chart.notifyDataSetChanged();
|
||||
} else {
|
||||
// create a dataset and give it a type
|
||||
set1 = new LineDataSet(values1, "DataSet 1");
|
||||
|
||||
set1.setAxisDependency(AxisDependency.LEFT);
|
||||
set1.setColor(ColorTemplate.getHoloBlue());
|
||||
set1.setCircleColor(Color.WHITE);
|
||||
set1.setLineWidth(2f);
|
||||
set1.setCircleRadius(3f);
|
||||
set1.setFillAlpha(65);
|
||||
set1.setFillColor(ColorTemplate.getHoloBlue());
|
||||
set1.setHighLightColor(Color.rgb(244, 117, 117));
|
||||
set1.setDrawCircleHole(false);
|
||||
//set1.setFillFormatter(new MyFillFormatter(0f));
|
||||
//set1.setDrawHorizontalHighlightIndicator(false);
|
||||
//set1.setVisible(false);
|
||||
//set1.setCircleHoleColor(Color.WHITE);
|
||||
|
||||
// create a dataset and give it a type
|
||||
set2 = new LineDataSet(values2, "DataSet 2");
|
||||
set2.setAxisDependency(AxisDependency.RIGHT);
|
||||
set2.setColor(Color.RED);
|
||||
set2.setCircleColor(Color.WHITE);
|
||||
set2.setLineWidth(2f);
|
||||
set2.setCircleRadius(3f);
|
||||
set2.setFillAlpha(65);
|
||||
set2.setFillColor(Color.RED);
|
||||
set2.setDrawCircleHole(false);
|
||||
set2.setHighLightColor(Color.rgb(244, 117, 117));
|
||||
//set2.setFillFormatter(new MyFillFormatter(900f));
|
||||
|
||||
set3 = new LineDataSet(values3, "DataSet 3");
|
||||
set3.setAxisDependency(AxisDependency.RIGHT);
|
||||
set3.setColor(Color.YELLOW);
|
||||
set3.setCircleColor(Color.WHITE);
|
||||
set3.setLineWidth(2f);
|
||||
set3.setCircleRadius(3f);
|
||||
set3.setFillAlpha(65);
|
||||
set3.setFillColor(ColorTemplate.colorWithAlpha(Color.YELLOW, 200));
|
||||
set3.setDrawCircleHole(false);
|
||||
set3.setHighLightColor(Color.rgb(244, 117, 117));
|
||||
|
||||
// create a data object with the data sets
|
||||
LineData data = new LineData(set1, set2, set3);
|
||||
data.setValueTextColor(Color.WHITE);
|
||||
data.setValueTextSize(9f);
|
||||
|
||||
// set data
|
||||
chart.setData(data);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.line, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.viewGithub: {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/LineChartActivity2.java"));
|
||||
startActivity(i);
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleValues: {
|
||||
List<ILineDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (ILineDataSet iSet : sets) {
|
||||
|
||||
LineDataSet set = (LineDataSet) iSet;
|
||||
set.setDrawValues(!set.isDrawValuesEnabled());
|
||||
}
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleHighlight: {
|
||||
if (chart.getData() != null) {
|
||||
chart.getData().setHighlightEnabled(!chart.getData().isHighlightEnabled());
|
||||
chart.invalidate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleFilled: {
|
||||
|
||||
List<ILineDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (ILineDataSet iSet : sets) {
|
||||
|
||||
LineDataSet set = (LineDataSet) iSet;
|
||||
if (set.isDrawFilledEnabled())
|
||||
set.setDrawFilled(false);
|
||||
else
|
||||
set.setDrawFilled(true);
|
||||
}
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleCircles: {
|
||||
List<ILineDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (ILineDataSet iSet : sets) {
|
||||
|
||||
LineDataSet set = (LineDataSet) iSet;
|
||||
if (set.isDrawCirclesEnabled())
|
||||
set.setDrawCircles(false);
|
||||
else
|
||||
set.setDrawCircles(true);
|
||||
}
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleCubic: {
|
||||
List<ILineDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (ILineDataSet iSet : sets) {
|
||||
|
||||
LineDataSet set = (LineDataSet) iSet;
|
||||
set.setMode(set.getMode() == LineDataSet.Mode.CUBIC_BEZIER
|
||||
? LineDataSet.Mode.LINEAR
|
||||
: LineDataSet.Mode.CUBIC_BEZIER);
|
||||
}
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleStepped: {
|
||||
List<ILineDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (ILineDataSet iSet : sets) {
|
||||
|
||||
LineDataSet set = (LineDataSet) iSet;
|
||||
set.setMode(set.getMode() == LineDataSet.Mode.STEPPED
|
||||
? LineDataSet.Mode.LINEAR
|
||||
: LineDataSet.Mode.STEPPED);
|
||||
}
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleHorizontalCubic: {
|
||||
List<ILineDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (ILineDataSet iSet : sets) {
|
||||
|
||||
LineDataSet set = (LineDataSet) iSet;
|
||||
set.setMode(set.getMode() == LineDataSet.Mode.HORIZONTAL_BEZIER
|
||||
? LineDataSet.Mode.LINEAR
|
||||
: LineDataSet.Mode.HORIZONTAL_BEZIER);
|
||||
}
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionTogglePinch: {
|
||||
if (chart.isPinchZoomEnabled())
|
||||
chart.setPinchZoom(false);
|
||||
else
|
||||
chart.setPinchZoom(true);
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleAutoScaleMinMax: {
|
||||
chart.setAutoScaleMinMaxEnabled(!chart.isAutoScaleMinMaxEnabled());
|
||||
chart.notifyDataSetChanged();
|
||||
break;
|
||||
}
|
||||
case R.id.animateX: {
|
||||
chart.animateX(2000);
|
||||
break;
|
||||
}
|
||||
case R.id.animateY: {
|
||||
chart.animateY(2000);
|
||||
break;
|
||||
}
|
||||
case R.id.animateXY: {
|
||||
chart.animateXY(2000, 2000);
|
||||
break;
|
||||
}
|
||||
case R.id.actionSave: {
|
||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
|
||||
saveToGallery();
|
||||
} else {
|
||||
requestStoragePermission(chart);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
|
||||
tvX.setText(String.valueOf(seekBarX.getProgress()));
|
||||
tvY.setText(String.valueOf(seekBarY.getProgress()));
|
||||
|
||||
setData(seekBarX.getProgress(), seekBarY.getProgress());
|
||||
|
||||
// redraw
|
||||
chart.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveToGallery() {
|
||||
saveToGallery(chart, "LineChartActivity2");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onValueSelected(Entry e, Highlight h) {
|
||||
Log.i("Entry selected", e.toString());
|
||||
|
||||
chart.centerViewToAnimated(e.getX(), e.getY(), chart.getData().getDataSetByIndex(h.getDataSetIndex())
|
||||
.getAxisDependency(), 500);
|
||||
//chart.zoomAndCenterAnimated(2.5f, 2.5f, e.getX(), e.getY(), chart.getData().getDataSetByIndex(dataSetIndex)
|
||||
// .getAxisDependency(), 1000);
|
||||
//chart.zoomAndCenterAnimated(1.8f, 1.8f, e.getX(), e.getY(), chart.getData().getDataSetByIndex(dataSetIndex)
|
||||
// .getAxisDependency(), 1000);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected() {
|
||||
Log.i("Nothing selected", "Nothing selected.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {}
|
||||
}
|
||||
+156
@@ -0,0 +1,156 @@
|
||||
|
||||
package com.android.stockapp.ui.mpchartexample;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Typeface;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.ui.mpchartexample.notimportant.DemoBase;
|
||||
import com.github.mikephil.charting.charts.LineChart;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.data.LineData;
|
||||
import com.github.mikephil.charting.data.LineDataSet;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
public class LineChartActivityColored extends DemoBase {
|
||||
|
||||
private final LineChart[] charts = new LineChart[4];
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_colored_lines);
|
||||
|
||||
setTitle("LineChartActivityColored");
|
||||
|
||||
charts[0] = findViewById(R.id.chart1);
|
||||
charts[1] = findViewById(R.id.chart2);
|
||||
charts[2] = findViewById(R.id.chart3);
|
||||
charts[3] = findViewById(R.id.chart4);
|
||||
|
||||
Typeface mTf = Typeface.createFromAsset(getAssets(), "OpenSans-Bold.ttf");
|
||||
|
||||
for (int i = 0; i < charts.length; i++) {
|
||||
|
||||
LineData data = getData(36, 100);
|
||||
data.setValueTypeface(mTf);
|
||||
|
||||
// add some transparency to the color with "& 0x90FFFFFF"
|
||||
setupChart(charts[i], data, colors[i % colors.length]);
|
||||
}
|
||||
}
|
||||
|
||||
private final int[] colors = new int[] {
|
||||
Color.rgb(137, 230, 81),
|
||||
Color.rgb(240, 240, 30),
|
||||
Color.rgb(89, 199, 250),
|
||||
Color.rgb(250, 104, 104)
|
||||
};
|
||||
|
||||
private void setupChart(LineChart chart, LineData data, int color) {
|
||||
|
||||
((LineDataSet) data.getDataSetByIndex(0)).setCircleHoleColor(color);
|
||||
|
||||
// no description text
|
||||
chart.getDescription().setEnabled(false);
|
||||
|
||||
// chart.setDrawHorizontalGrid(false);
|
||||
//
|
||||
// enable / disable grid background
|
||||
chart.setDrawGridBackground(false);
|
||||
// chart.getRenderer().getGridPaint().setGridColor(Color.WHITE & 0x70FFFFFF);
|
||||
|
||||
// enable touch gestures
|
||||
chart.setTouchEnabled(true);
|
||||
|
||||
// enable scaling and dragging
|
||||
chart.setDragEnabled(true);
|
||||
chart.setScaleEnabled(true);
|
||||
|
||||
// if disabled, scaling can be done on x- and y-axis separately
|
||||
chart.setPinchZoom(false);
|
||||
|
||||
chart.setBackgroundColor(color);
|
||||
|
||||
// set custom chart offsets (automatic offset calculation is hereby disabled)
|
||||
chart.setViewPortOffsets(10, 0, 10, 0);
|
||||
|
||||
// add data
|
||||
chart.setData(data);
|
||||
|
||||
// get the legend (only possible after setting data)
|
||||
Legend l = chart.getLegend();
|
||||
l.setEnabled(false);
|
||||
|
||||
chart.getAxisLeft().setEnabled(false);
|
||||
chart.getAxisLeft().setSpaceTop(40);
|
||||
chart.getAxisLeft().setSpaceBottom(40);
|
||||
chart.getAxisRight().setEnabled(false);
|
||||
|
||||
chart.getXAxis().setEnabled(false);
|
||||
|
||||
// animate calls invalidate()...
|
||||
chart.animateX(2500);
|
||||
}
|
||||
|
||||
private LineData getData(int count, float range) {
|
||||
|
||||
ArrayList<Entry> values = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
float val = (float) (Math.random() * range) + 3;
|
||||
values.add(new Entry(i, val));
|
||||
}
|
||||
|
||||
// create a dataset and give it a type
|
||||
LineDataSet set1 = new LineDataSet(values, "DataSet 1");
|
||||
// set1.setFillAlpha(110);
|
||||
// set1.setFillColor(Color.RED);
|
||||
|
||||
set1.setLineWidth(1.75f);
|
||||
set1.setCircleRadius(5f);
|
||||
set1.setCircleHoleRadius(2.5f);
|
||||
set1.setColor(Color.WHITE);
|
||||
set1.setCircleColor(Color.WHITE);
|
||||
set1.setHighLightColor(Color.WHITE);
|
||||
set1.setDrawValues(false);
|
||||
|
||||
// create a data object with the data sets
|
||||
return new LineData(set1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.only_github, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.viewGithub: {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/LineChartActivityColored.java"));
|
||||
startActivity(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveToGallery() { /* Intentionally left empty */ }
|
||||
}
|
||||
+318
@@ -0,0 +1,318 @@
|
||||
package com.android.stockapp.ui.mpchartexample;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Color;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.SeekBar.OnSeekBarChangeListener;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.ui.mpchartexample.notimportant.DemoBase;
|
||||
import com.github.mikephil.charting.charts.LineChart;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
import com.github.mikephil.charting.components.YAxis.AxisDependency;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.data.LineData;
|
||||
import com.github.mikephil.charting.data.LineDataSet;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
|
||||
import com.github.mikephil.charting.utils.ColorTemplate;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class LineChartTime extends DemoBase implements OnSeekBarChangeListener {
|
||||
|
||||
private LineChart chart;
|
||||
private SeekBar seekBarX;
|
||||
private TextView tvX;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_linechart_time);
|
||||
|
||||
setTitle("LineChartTime");
|
||||
|
||||
tvX = findViewById(R.id.tvXMax);
|
||||
seekBarX = findViewById(R.id.seekBar1);
|
||||
seekBarX.setOnSeekBarChangeListener(this);
|
||||
|
||||
chart = findViewById(R.id.chart1);
|
||||
|
||||
// no description text
|
||||
chart.getDescription().setEnabled(false);
|
||||
|
||||
// enable touch gestures
|
||||
chart.setTouchEnabled(true);
|
||||
|
||||
chart.setDragDecelerationFrictionCoef(0.9f);
|
||||
|
||||
// enable scaling and dragging
|
||||
chart.setDragEnabled(true);
|
||||
chart.setScaleEnabled(true);
|
||||
chart.setDrawGridBackground(false);
|
||||
chart.setHighlightPerDragEnabled(true);
|
||||
|
||||
// set an alternative background color
|
||||
chart.setBackgroundColor(Color.WHITE);
|
||||
chart.setViewPortOffsets(0f, 0f, 0f, 0f);
|
||||
|
||||
// add data
|
||||
seekBarX.setProgress(100);
|
||||
|
||||
// get the legend (only possible after setting data)
|
||||
Legend l = chart.getLegend();
|
||||
l.setEnabled(false);
|
||||
|
||||
XAxis xAxis = chart.getXAxis();
|
||||
xAxis.setPosition(XAxis.XAxisPosition.TOP_INSIDE);
|
||||
xAxis.setTypeface(tfLight);
|
||||
xAxis.setTextSize(10f);
|
||||
xAxis.setTextColor(Color.WHITE);
|
||||
xAxis.setDrawAxisLine(false);
|
||||
xAxis.setDrawGridLines(true);
|
||||
xAxis.setTextColor(Color.rgb(255, 192, 56));
|
||||
xAxis.setCenterAxisLabels(true);
|
||||
xAxis.setGranularity(1f); // one hour
|
||||
xAxis.setValueFormatter(new ValueFormatter() {
|
||||
|
||||
private final SimpleDateFormat mFormat = new SimpleDateFormat("dd MMM HH:mm", Locale.ENGLISH);
|
||||
|
||||
@Override
|
||||
public String getFormattedValue(float value) {
|
||||
|
||||
long millis = TimeUnit.HOURS.toMillis((long) value);
|
||||
return mFormat.format(new Date(millis));
|
||||
}
|
||||
});
|
||||
|
||||
YAxis leftAxis = chart.getAxisLeft();
|
||||
leftAxis.setPosition(YAxis.YAxisLabelPosition.INSIDE_CHART);
|
||||
leftAxis.setTypeface(tfLight);
|
||||
leftAxis.setTextColor(ColorTemplate.getHoloBlue());
|
||||
leftAxis.setDrawGridLines(true);
|
||||
leftAxis.setGranularityEnabled(true);
|
||||
leftAxis.setAxisMinimum(0f);
|
||||
leftAxis.setAxisMaximum(170f);
|
||||
leftAxis.setYOffset(-9f);
|
||||
leftAxis.setTextColor(Color.rgb(255, 192, 56));
|
||||
|
||||
YAxis rightAxis = chart.getAxisRight();
|
||||
rightAxis.setEnabled(false);
|
||||
}
|
||||
|
||||
private void setData(int count, float range) {
|
||||
|
||||
// now in hours
|
||||
long now = TimeUnit.MILLISECONDS.toHours(System.currentTimeMillis());
|
||||
|
||||
ArrayList<Entry> values = new ArrayList<>();
|
||||
|
||||
// count = hours
|
||||
float to = now + count;
|
||||
|
||||
// increment by 1 hour
|
||||
for (float x = now; x < to; x++) {
|
||||
|
||||
float y = getRandom(range, 50);
|
||||
values.add(new Entry(x, y)); // add one entry per hour
|
||||
}
|
||||
|
||||
// create a dataset and give it a type
|
||||
LineDataSet set1 = new LineDataSet(values, "DataSet 1");
|
||||
set1.setAxisDependency(AxisDependency.LEFT);
|
||||
set1.setColor(ColorTemplate.getHoloBlue());
|
||||
set1.setValueTextColor(ColorTemplate.getHoloBlue());
|
||||
set1.setLineWidth(1.5f);
|
||||
set1.setDrawCircles(false);
|
||||
set1.setDrawValues(false);
|
||||
set1.setFillAlpha(65);
|
||||
set1.setFillColor(ColorTemplate.getHoloBlue());
|
||||
set1.setHighLightColor(Color.rgb(244, 117, 117));
|
||||
set1.setDrawCircleHole(false);
|
||||
|
||||
// create a data object with the data sets
|
||||
LineData data = new LineData(set1);
|
||||
data.setValueTextColor(Color.WHITE);
|
||||
data.setValueTextSize(9f);
|
||||
|
||||
// set data
|
||||
chart.setData(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.line, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.viewGithub: {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/LineChartTime.java"));
|
||||
startActivity(i);
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleValues: {
|
||||
List<ILineDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (ILineDataSet iSet : sets) {
|
||||
|
||||
LineDataSet set = (LineDataSet) iSet;
|
||||
set.setDrawValues(!set.isDrawValuesEnabled());
|
||||
}
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleHighlight: {
|
||||
if (chart.getData() != null) {
|
||||
chart.getData().setHighlightEnabled(!chart.getData().isHighlightEnabled());
|
||||
chart.invalidate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleFilled: {
|
||||
|
||||
List<ILineDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (ILineDataSet iSet : sets) {
|
||||
|
||||
LineDataSet set = (LineDataSet) iSet;
|
||||
if (set.isDrawFilledEnabled())
|
||||
set.setDrawFilled(false);
|
||||
else
|
||||
set.setDrawFilled(true);
|
||||
}
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleCircles: {
|
||||
List<ILineDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (ILineDataSet iSet : sets) {
|
||||
|
||||
LineDataSet set = (LineDataSet) iSet;
|
||||
if (set.isDrawCirclesEnabled())
|
||||
set.setDrawCircles(false);
|
||||
else
|
||||
set.setDrawCircles(true);
|
||||
}
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleCubic: {
|
||||
List<ILineDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (ILineDataSet iSet : sets) {
|
||||
|
||||
LineDataSet set = (LineDataSet) iSet;
|
||||
if (set.getMode() == LineDataSet.Mode.CUBIC_BEZIER)
|
||||
set.setMode(LineDataSet.Mode.LINEAR);
|
||||
else
|
||||
set.setMode(LineDataSet.Mode.CUBIC_BEZIER);
|
||||
}
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleStepped: {
|
||||
List<ILineDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (ILineDataSet iSet : sets) {
|
||||
|
||||
LineDataSet set = (LineDataSet) iSet;
|
||||
if (set.getMode() == LineDataSet.Mode.STEPPED)
|
||||
set.setMode(LineDataSet.Mode.LINEAR);
|
||||
else
|
||||
set.setMode(LineDataSet.Mode.STEPPED);
|
||||
}
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionTogglePinch: {
|
||||
if (chart.isPinchZoomEnabled())
|
||||
chart.setPinchZoom(false);
|
||||
else
|
||||
chart.setPinchZoom(true);
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleAutoScaleMinMax: {
|
||||
chart.setAutoScaleMinMaxEnabled(!chart.isAutoScaleMinMaxEnabled());
|
||||
chart.notifyDataSetChanged();
|
||||
break;
|
||||
}
|
||||
case R.id.animateX: {
|
||||
chart.animateX(2000);
|
||||
break;
|
||||
}
|
||||
case R.id.animateY: {
|
||||
chart.animateY(2000);
|
||||
break;
|
||||
}
|
||||
case R.id.animateXY: {
|
||||
chart.animateXY(2000, 2000);
|
||||
break;
|
||||
}
|
||||
|
||||
case R.id.actionSave: {
|
||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
|
||||
saveToGallery();
|
||||
} else {
|
||||
requestStoragePermission(chart);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
|
||||
tvX.setText(String.valueOf(seekBarX.getProgress()));
|
||||
|
||||
setData(seekBarX.getProgress(), 50);
|
||||
|
||||
// redraw
|
||||
chart.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveToGallery() {
|
||||
saveToGallery(chart, "LineChartTime");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {}
|
||||
}
|
||||
+183
@@ -0,0 +1,183 @@
|
||||
|
||||
package com.android.stockapp.ui.mpchartexample;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ListView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.ui.mpchartexample.notimportant.DemoBase;
|
||||
import com.github.mikephil.charting.charts.BarChart;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.XAxis.XAxisPosition;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
import com.github.mikephil.charting.data.BarData;
|
||||
import com.github.mikephil.charting.data.BarDataSet;
|
||||
import com.github.mikephil.charting.data.BarEntry;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IBarDataSet;
|
||||
import com.github.mikephil.charting.utils.ColorTemplate;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Demonstrates the use of charts inside a ListView. IMPORTANT: provide a
|
||||
* specific height attribute for the chart inside your ListView item
|
||||
*
|
||||
* @author Philipp Jahoda
|
||||
*/
|
||||
public class ListViewBarChartActivity extends DemoBase {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_listview_chart);
|
||||
|
||||
setTitle("ListViewBarChartActivity");
|
||||
|
||||
ListView lv = findViewById(R.id.listView1);
|
||||
|
||||
ArrayList<BarData> list = new ArrayList<>();
|
||||
|
||||
// 20 items
|
||||
for (int i = 0; i < 20; i++) {
|
||||
list.add(generateData(i + 1));
|
||||
}
|
||||
|
||||
ChartDataAdapter cda = new ChartDataAdapter(getApplicationContext(), list);
|
||||
lv.setAdapter(cda);
|
||||
}
|
||||
|
||||
private class ChartDataAdapter extends ArrayAdapter<BarData> {
|
||||
|
||||
ChartDataAdapter(Context context, List<BarData> objects) {
|
||||
super(context, 0, objects);
|
||||
}
|
||||
|
||||
@SuppressLint("InflateParams")
|
||||
@NonNull
|
||||
@Override
|
||||
public View getView(int position, View convertView, @NonNull ViewGroup parent) {
|
||||
|
||||
BarData data = getItem(position);
|
||||
|
||||
ViewHolder holder;
|
||||
|
||||
if (convertView == null) {
|
||||
|
||||
holder = new ViewHolder();
|
||||
|
||||
convertView = LayoutInflater.from(getContext()).inflate(
|
||||
R.layout.list_item_barchart, null);
|
||||
holder.chart = convertView.findViewById(R.id.chart);
|
||||
|
||||
convertView.setTag(holder);
|
||||
|
||||
} else {
|
||||
holder = (ViewHolder) convertView.getTag();
|
||||
}
|
||||
|
||||
// apply styling
|
||||
if (data != null) {
|
||||
data.setValueTypeface(tfLight);
|
||||
data.setValueTextColor(Color.BLACK);
|
||||
}
|
||||
holder.chart.getDescription().setEnabled(false);
|
||||
holder.chart.setDrawGridBackground(false);
|
||||
|
||||
XAxis xAxis = holder.chart.getXAxis();
|
||||
xAxis.setPosition(XAxisPosition.BOTTOM);
|
||||
xAxis.setTypeface(tfLight);
|
||||
xAxis.setDrawGridLines(false);
|
||||
|
||||
YAxis leftAxis = holder.chart.getAxisLeft();
|
||||
leftAxis.setTypeface(tfLight);
|
||||
leftAxis.setLabelCount(5, false);
|
||||
leftAxis.setSpaceTop(15f);
|
||||
|
||||
YAxis rightAxis = holder.chart.getAxisRight();
|
||||
rightAxis.setTypeface(tfLight);
|
||||
rightAxis.setLabelCount(5, false);
|
||||
rightAxis.setSpaceTop(15f);
|
||||
|
||||
// set data
|
||||
holder.chart.setData(data);
|
||||
holder.chart.setFitBars(true);
|
||||
|
||||
// do not forget to refresh the chart
|
||||
// holder.chart.invalidate();
|
||||
holder.chart.animateY(700);
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
private class ViewHolder {
|
||||
|
||||
BarChart chart;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* generates a random ChartData object with just one DataSet
|
||||
*
|
||||
* @return Bar data
|
||||
*/
|
||||
private BarData generateData(int cnt) {
|
||||
|
||||
ArrayList<BarEntry> entries = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < 12; i++) {
|
||||
entries.add(new BarEntry(i, (float) (Math.random() * 70) + 30));
|
||||
}
|
||||
|
||||
BarDataSet d = new BarDataSet(entries, "New DataSet " + cnt);
|
||||
d.setColors(ColorTemplate.VORDIPLOM_COLORS);
|
||||
d.setBarShadowColor(Color.rgb(203, 203, 203));
|
||||
|
||||
ArrayList<IBarDataSet> sets = new ArrayList<>();
|
||||
sets.add(d);
|
||||
|
||||
BarData cd = new BarData(sets);
|
||||
cd.setBarWidth(0.9f);
|
||||
return cd;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.only_github, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.viewGithub: {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/ListViewBarChartActivity.java"));
|
||||
startActivity(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveToGallery() { /* Intentionally left empty */ }
|
||||
}
|
||||
+211
@@ -0,0 +1,211 @@
|
||||
|
||||
package com.android.stockapp.ui.mpchartexample;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ListView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.ui.mpchartexample.listviewitems.BarChartItem;
|
||||
import com.android.stockapp.ui.mpchartexample.listviewitems.ChartItem;
|
||||
import com.android.stockapp.ui.mpchartexample.listviewitems.LineChartItem;
|
||||
import com.android.stockapp.ui.mpchartexample.listviewitems.PieChartItem;
|
||||
import com.android.stockapp.ui.mpchartexample.notimportant.DemoBase;
|
||||
import com.github.mikephil.charting.data.BarData;
|
||||
import com.github.mikephil.charting.data.BarDataSet;
|
||||
import com.github.mikephil.charting.data.BarEntry;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.data.LineData;
|
||||
import com.github.mikephil.charting.data.LineDataSet;
|
||||
import com.github.mikephil.charting.data.PieData;
|
||||
import com.github.mikephil.charting.data.PieDataSet;
|
||||
import com.github.mikephil.charting.data.PieEntry;
|
||||
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
|
||||
import com.github.mikephil.charting.utils.ColorTemplate;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Demonstrates the use of charts inside a ListView. IMPORTANT: provide a
|
||||
* specific height attribute for the chart inside your ListView item
|
||||
*
|
||||
* @author Philipp Jahoda
|
||||
*/
|
||||
public class ListViewMultiChartActivity extends DemoBase {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_listview_chart);
|
||||
|
||||
setTitle("ListViewMultiChartActivity");
|
||||
|
||||
ListView lv = findViewById(R.id.listView1);
|
||||
|
||||
ArrayList<ChartItem> list = new ArrayList<>();
|
||||
|
||||
// 30 items
|
||||
for (int i = 0; i < 30; i++) {
|
||||
|
||||
if(i % 3 == 0) {
|
||||
list.add(new LineChartItem(generateDataLine(i + 1), getApplicationContext()));
|
||||
} else if(i % 3 == 1) {
|
||||
list.add(new BarChartItem(generateDataBar(i + 1), getApplicationContext()));
|
||||
} else if(i % 3 == 2) {
|
||||
list.add(new PieChartItem(generateDataPie(), getApplicationContext()));
|
||||
}
|
||||
}
|
||||
|
||||
ChartDataAdapter cda = new ChartDataAdapter(getApplicationContext(), list);
|
||||
lv.setAdapter(cda);
|
||||
}
|
||||
|
||||
/** adapter that supports 3 different item types */
|
||||
private class ChartDataAdapter extends ArrayAdapter<ChartItem> {
|
||||
|
||||
ChartDataAdapter(Context context, List<ChartItem> objects) {
|
||||
super(context, 0, objects);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public View getView(int position, View convertView, @NonNull ViewGroup parent) {
|
||||
//noinspection ConstantConditions
|
||||
return getItem(position).getView(position, convertView, getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
// return the views type
|
||||
ChartItem ci = getItem(position);
|
||||
return ci != null ? ci.getItemType() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getViewTypeCount() {
|
||||
return 3; // we have 3 different item-types
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* generates a random ChartData object with just one DataSet
|
||||
*
|
||||
* @return Line data
|
||||
*/
|
||||
private LineData generateDataLine(int cnt) {
|
||||
|
||||
ArrayList<Entry> values1 = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < 12; i++) {
|
||||
values1.add(new Entry(i, (int) (Math.random() * 65) + 40));
|
||||
}
|
||||
|
||||
LineDataSet d1 = new LineDataSet(values1, "New DataSet " + cnt + ", (1)");
|
||||
d1.setLineWidth(2.5f);
|
||||
d1.setCircleRadius(4.5f);
|
||||
d1.setHighLightColor(Color.rgb(244, 117, 117));
|
||||
d1.setDrawValues(false);
|
||||
|
||||
ArrayList<Entry> values2 = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < 12; i++) {
|
||||
values2.add(new Entry(i, values1.get(i).getY() - 30));
|
||||
}
|
||||
|
||||
LineDataSet d2 = new LineDataSet(values2, "New DataSet " + cnt + ", (2)");
|
||||
d2.setLineWidth(2.5f);
|
||||
d2.setCircleRadius(4.5f);
|
||||
d2.setHighLightColor(Color.rgb(244, 117, 117));
|
||||
d2.setColor(ColorTemplate.VORDIPLOM_COLORS[0]);
|
||||
d2.setCircleColor(ColorTemplate.VORDIPLOM_COLORS[0]);
|
||||
d2.setDrawValues(false);
|
||||
|
||||
ArrayList<ILineDataSet> sets = new ArrayList<>();
|
||||
sets.add(d1);
|
||||
sets.add(d2);
|
||||
|
||||
return new LineData(sets);
|
||||
}
|
||||
|
||||
/**
|
||||
* generates a random ChartData object with just one DataSet
|
||||
*
|
||||
* @return Bar data
|
||||
*/
|
||||
private BarData generateDataBar(int cnt) {
|
||||
|
||||
ArrayList<BarEntry> entries = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < 12; i++) {
|
||||
entries.add(new BarEntry(i, (int) (Math.random() * 70) + 30));
|
||||
}
|
||||
|
||||
BarDataSet d = new BarDataSet(entries, "New DataSet " + cnt);
|
||||
d.setColors(ColorTemplate.VORDIPLOM_COLORS);
|
||||
d.setHighLightAlpha(255);
|
||||
|
||||
BarData cd = new BarData(d);
|
||||
cd.setBarWidth(0.9f);
|
||||
return cd;
|
||||
}
|
||||
|
||||
/**
|
||||
* generates a random ChartData object with just one DataSet
|
||||
*
|
||||
* @return Pie data
|
||||
*/
|
||||
private PieData generateDataPie() {
|
||||
|
||||
ArrayList<PieEntry> entries = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
entries.add(new PieEntry((float) ((Math.random() * 70) + 30), "Quarter " + (i+1)));
|
||||
}
|
||||
|
||||
PieDataSet d = new PieDataSet(entries, "");
|
||||
|
||||
// space between slices
|
||||
d.setSliceSpace(2f);
|
||||
d.setColors(ColorTemplate.VORDIPLOM_COLORS);
|
||||
|
||||
return new PieData(d);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.only_github, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.viewGithub: {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/ListViewMultiChartActivity.java"));
|
||||
startActivity(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveToGallery() { /* Intentionally left empty */ }
|
||||
}
|
||||
+356
@@ -0,0 +1,356 @@
|
||||
|
||||
package com.android.stockapp.ui.mpchartexample;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.SeekBar.OnSeekBarChangeListener;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.ui.mpchartexample.notimportant.DemoBase;
|
||||
import com.github.mikephil.charting.charts.LineChart;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.data.LineData;
|
||||
import com.github.mikephil.charting.data.LineDataSet;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
|
||||
import com.github.mikephil.charting.listener.ChartTouchListener;
|
||||
import com.github.mikephil.charting.listener.OnChartGestureListener;
|
||||
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
|
||||
import com.github.mikephil.charting.utils.ColorTemplate;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MultiLineChartActivity extends DemoBase implements OnSeekBarChangeListener,
|
||||
OnChartGestureListener, OnChartValueSelectedListener {
|
||||
|
||||
private LineChart chart;
|
||||
private SeekBar seekBarX, seekBarY;
|
||||
private TextView tvX, tvY;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_linechart);
|
||||
|
||||
setTitle("MultiLineChartActivity");
|
||||
|
||||
tvX = findViewById(R.id.tvXMax);
|
||||
tvY = findViewById(R.id.tvYMax);
|
||||
|
||||
seekBarX = findViewById(R.id.seekBar1);
|
||||
seekBarX.setOnSeekBarChangeListener(this);
|
||||
|
||||
seekBarY = findViewById(R.id.seekBar2);
|
||||
seekBarY.setOnSeekBarChangeListener(this);
|
||||
|
||||
chart = findViewById(R.id.chart1);
|
||||
chart.setOnChartValueSelectedListener(this);
|
||||
|
||||
chart.setDrawGridBackground(false);
|
||||
chart.getDescription().setEnabled(false);
|
||||
chart.setDrawBorders(false);
|
||||
|
||||
chart.getAxisLeft().setEnabled(false);
|
||||
chart.getAxisRight().setDrawAxisLine(false);
|
||||
chart.getAxisRight().setDrawGridLines(false);
|
||||
chart.getXAxis().setDrawAxisLine(false);
|
||||
chart.getXAxis().setDrawGridLines(false);
|
||||
|
||||
// enable touch gestures
|
||||
chart.setTouchEnabled(true);
|
||||
|
||||
// enable scaling and dragging
|
||||
chart.setDragEnabled(true);
|
||||
chart.setScaleEnabled(true);
|
||||
|
||||
// if disabled, scaling can be done on x- and y-axis separately
|
||||
chart.setPinchZoom(false);
|
||||
|
||||
seekBarX.setProgress(20);
|
||||
seekBarY.setProgress(100);
|
||||
|
||||
Legend l = chart.getLegend();
|
||||
l.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
|
||||
l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT);
|
||||
l.setOrientation(Legend.LegendOrientation.VERTICAL);
|
||||
l.setDrawInside(false);
|
||||
}
|
||||
|
||||
private final int[] colors = new int[] {
|
||||
ColorTemplate.VORDIPLOM_COLORS[0],
|
||||
ColorTemplate.VORDIPLOM_COLORS[1],
|
||||
ColorTemplate.VORDIPLOM_COLORS[2]
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
|
||||
chart.resetTracking();
|
||||
|
||||
progress = seekBarX.getProgress();
|
||||
|
||||
tvX.setText(String.valueOf(seekBarX.getProgress()));
|
||||
tvY.setText(String.valueOf(seekBarY.getProgress()));
|
||||
|
||||
ArrayList<ILineDataSet> dataSets = new ArrayList<>();
|
||||
|
||||
for (int z = 0; z < 3; z++) {
|
||||
|
||||
ArrayList<Entry> values = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < progress; i++) {
|
||||
double val = (Math.random() * seekBarY.getProgress()) + 3;
|
||||
values.add(new Entry(i, (float) val));
|
||||
}
|
||||
|
||||
LineDataSet d = new LineDataSet(values, "DataSet " + (z + 1));
|
||||
d.setLineWidth(2.5f);
|
||||
d.setCircleRadius(4f);
|
||||
|
||||
int color = colors[z % colors.length];
|
||||
d.setColor(color);
|
||||
d.setCircleColor(color);
|
||||
dataSets.add(d);
|
||||
}
|
||||
|
||||
// make the first DataSet dashed
|
||||
((LineDataSet) dataSets.get(0)).enableDashedLine(10, 10, 0);
|
||||
((LineDataSet) dataSets.get(0)).setColors(ColorTemplate.VORDIPLOM_COLORS);
|
||||
((LineDataSet) dataSets.get(0)).setCircleColors(ColorTemplate.VORDIPLOM_COLORS);
|
||||
|
||||
LineData data = new LineData(dataSets);
|
||||
chart.setData(data);
|
||||
chart.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.line, menu);
|
||||
menu.removeItem(R.id.actionToggleIcons);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.viewGithub: {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/MultiLineChartActivity.java"));
|
||||
startActivity(i);
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleValues: {
|
||||
List<ILineDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (ILineDataSet iSet : sets) {
|
||||
|
||||
LineDataSet set = (LineDataSet) iSet;
|
||||
set.setDrawValues(!set.isDrawValuesEnabled());
|
||||
}
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
/*
|
||||
case R.id.actionToggleIcons: { break; }
|
||||
*/
|
||||
case R.id.actionTogglePinch: {
|
||||
if (chart.isPinchZoomEnabled())
|
||||
chart.setPinchZoom(false);
|
||||
else
|
||||
chart.setPinchZoom(true);
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleAutoScaleMinMax: {
|
||||
chart.setAutoScaleMinMaxEnabled(!chart.isAutoScaleMinMaxEnabled());
|
||||
chart.notifyDataSetChanged();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleHighlight: {
|
||||
if(chart.getData() != null) {
|
||||
chart.getData().setHighlightEnabled(!chart.getData().isHighlightEnabled());
|
||||
chart.invalidate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleFilled: {
|
||||
List<ILineDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (ILineDataSet iSet : sets) {
|
||||
|
||||
LineDataSet set = (LineDataSet) iSet;
|
||||
if (set.isDrawFilledEnabled())
|
||||
set.setDrawFilled(false);
|
||||
else
|
||||
set.setDrawFilled(true);
|
||||
}
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleCircles: {
|
||||
List<ILineDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (ILineDataSet iSet : sets) {
|
||||
|
||||
LineDataSet set = (LineDataSet) iSet;
|
||||
if (set.isDrawCirclesEnabled())
|
||||
set.setDrawCircles(false);
|
||||
else
|
||||
set.setDrawCircles(true);
|
||||
}
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleCubic: {
|
||||
List<ILineDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (ILineDataSet iSet : sets) {
|
||||
|
||||
LineDataSet set = (LineDataSet) iSet;
|
||||
set.setMode(set.getMode() == LineDataSet.Mode.CUBIC_BEZIER
|
||||
? LineDataSet.Mode.LINEAR
|
||||
: LineDataSet.Mode.CUBIC_BEZIER);
|
||||
}
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleStepped: {
|
||||
List<ILineDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (ILineDataSet iSet : sets) {
|
||||
|
||||
LineDataSet set = (LineDataSet) iSet;
|
||||
set.setMode(set.getMode() == LineDataSet.Mode.STEPPED
|
||||
? LineDataSet.Mode.LINEAR
|
||||
: LineDataSet.Mode.STEPPED);
|
||||
}
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleHorizontalCubic: {
|
||||
List<ILineDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (ILineDataSet iSet : sets) {
|
||||
|
||||
LineDataSet set = (LineDataSet) iSet;
|
||||
set.setMode(set.getMode() == LineDataSet.Mode.HORIZONTAL_BEZIER
|
||||
? LineDataSet.Mode.LINEAR
|
||||
: LineDataSet.Mode.HORIZONTAL_BEZIER);
|
||||
}
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionSave: {
|
||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
|
||||
saveToGallery();
|
||||
} else {
|
||||
requestStoragePermission(chart);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case R.id.animateX: {
|
||||
chart.animateX(2000);
|
||||
break;
|
||||
}
|
||||
case R.id.animateY: {
|
||||
chart.animateY(2000);
|
||||
break;
|
||||
}
|
||||
case R.id.animateXY: {
|
||||
chart.animateXY(2000, 2000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveToGallery() {
|
||||
saveToGallery(chart, "MultiLineChartActivity");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChartGestureStart(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {
|
||||
Log.i("Gesture", "START, x: " + me.getX() + ", y: " + me.getY());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChartGestureEnd(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {
|
||||
Log.i("Gesture", "END, lastGesture: " + lastPerformedGesture);
|
||||
|
||||
// un-highlight values after the gesture is finished and no single-tap
|
||||
if(lastPerformedGesture != ChartTouchListener.ChartGesture.SINGLE_TAP)
|
||||
chart.highlightValues(null); // or highlightTouch(null) for callback to onNothingSelected(...)
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChartLongPressed(MotionEvent me) {
|
||||
Log.i("LongPress", "Chart long pressed.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChartDoubleTapped(MotionEvent me) {
|
||||
Log.i("DoubleTap", "Chart double-tapped.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChartSingleTapped(MotionEvent me) {
|
||||
Log.i("SingleTap", "Chart single-tapped.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChartFling(MotionEvent me1, MotionEvent me2, float velocityX, float velocityY) {
|
||||
Log.i("Fling", "Chart fling. VelocityX: " + velocityX + ", VelocityY: " + velocityY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChartScale(MotionEvent me, float scaleX, float scaleY) {
|
||||
Log.i("Scale / Zoom", "ScaleX: " + scaleX + ", ScaleY: " + scaleY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChartTranslate(MotionEvent me, float dX, float dY) {
|
||||
Log.i("Translate / Move", "dX: " + dX + ", dY: " + dY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onValueSelected(Entry e, Highlight h) {
|
||||
Log.i("VAL SELECTED",
|
||||
"Value: " + e.getY() + ", xIndex: " + e.getX()
|
||||
+ ", DataSet index: " + h.getDataSetIndex());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected() {}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {}
|
||||
}
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
|
||||
package com.android.stockapp.ui.mpchartexample;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.SeekBar.OnSeekBarChangeListener;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.ui.mpchartexample.notimportant.DemoBase;
|
||||
import com.github.mikephil.charting.charts.LineChart;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.data.LineData;
|
||||
import com.github.mikephil.charting.data.LineDataSet;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
public class PerformanceLineChart extends DemoBase implements OnSeekBarChangeListener {
|
||||
|
||||
private LineChart chart;
|
||||
private SeekBar seekBarValues;
|
||||
private TextView tvCount;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_performance_linechart);
|
||||
|
||||
setTitle("PerformanceLineChart");
|
||||
|
||||
tvCount = findViewById(R.id.tvValueCount);
|
||||
seekBarValues = findViewById(R.id.seekbarValues);
|
||||
seekBarValues.setOnSeekBarChangeListener(this);
|
||||
|
||||
chart = findViewById(R.id.chart1);
|
||||
chart.setDrawGridBackground(false);
|
||||
|
||||
// no description text
|
||||
chart.getDescription().setEnabled(false);
|
||||
|
||||
// enable touch gestures
|
||||
chart.setTouchEnabled(true);
|
||||
|
||||
// enable scaling and dragging
|
||||
chart.setDragEnabled(true);
|
||||
chart.setScaleEnabled(true);
|
||||
|
||||
// if disabled, scaling can be done on x- and y-axis separately
|
||||
chart.setPinchZoom(false);
|
||||
|
||||
chart.getAxisLeft().setDrawGridLines(false);
|
||||
chart.getAxisRight().setEnabled(false);
|
||||
chart.getXAxis().setDrawGridLines(true);
|
||||
chart.getXAxis().setDrawAxisLine(false);
|
||||
|
||||
seekBarValues.setProgress(9000);
|
||||
|
||||
// don't forget to refresh the drawing
|
||||
chart.invalidate();
|
||||
}
|
||||
|
||||
private void setData(int count, float range) {
|
||||
|
||||
ArrayList<Entry> values = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
float val = (float) (Math.random() * (range + 1)) + 3;
|
||||
values.add(new Entry(i * 0.001f, val));
|
||||
}
|
||||
|
||||
// create a dataset and give it a type
|
||||
LineDataSet set1 = new LineDataSet(values, "DataSet 1");
|
||||
|
||||
set1.setColor(Color.BLACK);
|
||||
set1.setLineWidth(0.5f);
|
||||
set1.setDrawValues(false);
|
||||
set1.setDrawCircles(false);
|
||||
set1.setMode(LineDataSet.Mode.LINEAR);
|
||||
set1.setDrawFilled(false);
|
||||
|
||||
// create a data object with the data sets
|
||||
LineData data = new LineData(set1);
|
||||
|
||||
// set data
|
||||
chart.setData(data);
|
||||
|
||||
// get the legend (only possible after setting data)
|
||||
Legend l = chart.getLegend();
|
||||
l.setEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.only_github, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.viewGithub: {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/PerformanceLineChart.java"));
|
||||
startActivity(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
|
||||
int count = seekBarValues.getProgress() + 1000;
|
||||
tvCount.setText(String.valueOf(count));
|
||||
|
||||
chart.resetTracking();
|
||||
|
||||
setData(count, 500f);
|
||||
|
||||
// redraw
|
||||
chart.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveToGallery() { /* Intentionally left empty */ }
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {}
|
||||
}
|
||||
+328
@@ -0,0 +1,328 @@
|
||||
|
||||
package com.android.stockapp.ui.mpchartexample;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Typeface;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.text.SpannableString;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.text.style.RelativeSizeSpan;
|
||||
import android.text.style.StyleSpan;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.SeekBar.OnSeekBarChangeListener;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.ui.mpchartexample.notimportant.DemoBase;
|
||||
import com.github.mikephil.charting.animation.Easing;
|
||||
import com.github.mikephil.charting.charts.PieChart;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.data.PieData;
|
||||
import com.github.mikephil.charting.data.PieDataSet;
|
||||
import com.github.mikephil.charting.data.PieEntry;
|
||||
import com.github.mikephil.charting.formatter.PercentFormatter;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IDataSet;
|
||||
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
|
||||
import com.github.mikephil.charting.utils.ColorTemplate;
|
||||
import com.github.mikephil.charting.utils.MPPointF;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class PieChartActivity extends DemoBase implements OnSeekBarChangeListener,
|
||||
OnChartValueSelectedListener {
|
||||
|
||||
private PieChart chart;
|
||||
private SeekBar seekBarX, seekBarY;
|
||||
private TextView tvX, tvY;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_piechart);
|
||||
|
||||
setTitle("PieChartActivity");
|
||||
|
||||
tvX = findViewById(R.id.tvXMax);
|
||||
tvY = findViewById(R.id.tvYMax);
|
||||
|
||||
seekBarX = findViewById(R.id.seekBar1);
|
||||
seekBarY = findViewById(R.id.seekBar2);
|
||||
|
||||
seekBarX.setOnSeekBarChangeListener(this);
|
||||
seekBarY.setOnSeekBarChangeListener(this);
|
||||
|
||||
chart = findViewById(R.id.chart1);
|
||||
chart.setUsePercentValues(true);
|
||||
chart.getDescription().setEnabled(false);
|
||||
chart.setExtraOffsets(5, 10, 5, 5);
|
||||
|
||||
chart.setDragDecelerationFrictionCoef(0.95f);
|
||||
|
||||
chart.setCenterTextTypeface(tfLight);
|
||||
chart.setCenterText(generateCenterSpannableText());
|
||||
|
||||
chart.setDrawHoleEnabled(true);
|
||||
chart.setHoleColor(Color.WHITE);
|
||||
|
||||
chart.setTransparentCircleColor(Color.WHITE);
|
||||
chart.setTransparentCircleAlpha(110);
|
||||
|
||||
chart.setHoleRadius(58f);
|
||||
chart.setTransparentCircleRadius(61f);
|
||||
|
||||
chart.setDrawCenterText(true);
|
||||
|
||||
chart.setRotationAngle(0);
|
||||
// enable rotation of the chart by touch
|
||||
chart.setRotationEnabled(true);
|
||||
chart.setHighlightPerTapEnabled(true);
|
||||
|
||||
// chart.setUnit(" €");
|
||||
// chart.setDrawUnitsInChart(true);
|
||||
|
||||
// add a selection listener
|
||||
chart.setOnChartValueSelectedListener(this);
|
||||
|
||||
seekBarX.setProgress(4);
|
||||
seekBarY.setProgress(10);
|
||||
|
||||
chart.animateY(1400, Easing.EaseInOutQuad);
|
||||
// chart.spin(2000, 0, 360);
|
||||
|
||||
Legend l = chart.getLegend();
|
||||
l.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
|
||||
l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT);
|
||||
l.setOrientation(Legend.LegendOrientation.VERTICAL);
|
||||
l.setDrawInside(false);
|
||||
l.setXEntrySpace(7f);
|
||||
l.setYEntrySpace(0f);
|
||||
l.setYOffset(0f);
|
||||
|
||||
// entry label styling
|
||||
chart.setEntryLabelColor(Color.WHITE);
|
||||
chart.setEntryLabelTypeface(tfRegular);
|
||||
chart.setEntryLabelTextSize(12f);
|
||||
}
|
||||
|
||||
private void setData(int count, float range) {
|
||||
ArrayList<PieEntry> entries = new ArrayList<>();
|
||||
|
||||
// NOTE: The order of the entries when being added to the entries array determines their position around the center of
|
||||
// the chart.
|
||||
for (int i = 0; i < count ; i++) {
|
||||
entries.add(new PieEntry((float) ((Math.random() * range) + range / 5),
|
||||
parties[i % parties.length],
|
||||
getResources().getDrawable(R.drawable.star)));
|
||||
}
|
||||
|
||||
PieDataSet dataSet = new PieDataSet(entries, "Election Results");
|
||||
|
||||
dataSet.setDrawIcons(false);
|
||||
|
||||
dataSet.setSliceSpace(3f);
|
||||
dataSet.setIconsOffset(new MPPointF(0, 40));
|
||||
dataSet.setSelectionShift(5f);
|
||||
|
||||
// add a lot of colors
|
||||
|
||||
ArrayList<Integer> colors = new ArrayList<>();
|
||||
|
||||
for (int c : ColorTemplate.VORDIPLOM_COLORS)
|
||||
colors.add(c);
|
||||
|
||||
for (int c : ColorTemplate.JOYFUL_COLORS)
|
||||
colors.add(c);
|
||||
|
||||
for (int c : ColorTemplate.COLORFUL_COLORS)
|
||||
colors.add(c);
|
||||
|
||||
for (int c : ColorTemplate.LIBERTY_COLORS)
|
||||
colors.add(c);
|
||||
|
||||
for (int c : ColorTemplate.PASTEL_COLORS)
|
||||
colors.add(c);
|
||||
|
||||
colors.add(ColorTemplate.getHoloBlue());
|
||||
|
||||
dataSet.setColors(colors);
|
||||
//dataSet.setSelectionShift(0f);
|
||||
|
||||
PieData data = new PieData(dataSet);
|
||||
data.setValueFormatter(new PercentFormatter(chart));
|
||||
data.setValueTextSize(11f);
|
||||
data.setValueTextColor(Color.WHITE);
|
||||
data.setValueTypeface(tfLight);
|
||||
chart.setData(data);
|
||||
|
||||
// undo all highlights
|
||||
chart.highlightValues(null);
|
||||
|
||||
chart.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.pie, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.viewGithub: {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/PieChartActivity.java"));
|
||||
startActivity(i);
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleValues: {
|
||||
for (IDataSet<?> set : chart.getData().getDataSets())
|
||||
set.setDrawValues(!set.isDrawValuesEnabled());
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleIcons: {
|
||||
for (IDataSet<?> set : chart.getData().getDataSets())
|
||||
set.setDrawIcons(!set.isDrawIconsEnabled());
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleHole: {
|
||||
if (chart.isDrawHoleEnabled())
|
||||
chart.setDrawHoleEnabled(false);
|
||||
else
|
||||
chart.setDrawHoleEnabled(true);
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleMinAngles: {
|
||||
if (chart.getMinAngleForSlices() == 0f)
|
||||
chart.setMinAngleForSlices(36f);
|
||||
else
|
||||
chart.setMinAngleForSlices(0f);
|
||||
chart.notifyDataSetChanged();
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleCurvedSlices: {
|
||||
boolean toSet = !chart.isDrawRoundedSlicesEnabled() || !chart.isDrawHoleEnabled();
|
||||
chart.setDrawRoundedSlices(toSet);
|
||||
if (toSet && !chart.isDrawHoleEnabled()) {
|
||||
chart.setDrawHoleEnabled(true);
|
||||
}
|
||||
if (toSet && chart.isDrawSlicesUnderHoleEnabled()) {
|
||||
chart.setDrawSlicesUnderHole(false);
|
||||
}
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionDrawCenter: {
|
||||
if (chart.isDrawCenterTextEnabled())
|
||||
chart.setDrawCenterText(false);
|
||||
else
|
||||
chart.setDrawCenterText(true);
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleXValues: {
|
||||
|
||||
chart.setDrawEntryLabels(!chart.isDrawEntryLabelsEnabled());
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionTogglePercent:
|
||||
chart.setUsePercentValues(!chart.isUsePercentValuesEnabled());
|
||||
chart.invalidate();
|
||||
break;
|
||||
case R.id.animateX: {
|
||||
chart.animateX(1400);
|
||||
break;
|
||||
}
|
||||
case R.id.animateY: {
|
||||
chart.animateY(1400);
|
||||
break;
|
||||
}
|
||||
case R.id.animateXY: {
|
||||
chart.animateXY(1400, 1400);
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleSpin: {
|
||||
chart.spin(1000, chart.getRotationAngle(), chart.getRotationAngle() + 360, Easing.EaseInOutCubic);
|
||||
break;
|
||||
}
|
||||
case R.id.actionSave: {
|
||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
|
||||
saveToGallery();
|
||||
} else {
|
||||
requestStoragePermission(chart);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
|
||||
tvX.setText(String.valueOf(seekBarX.getProgress()));
|
||||
tvY.setText(String.valueOf(seekBarY.getProgress()));
|
||||
|
||||
setData(seekBarX.getProgress(), seekBarY.getProgress());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveToGallery() {
|
||||
saveToGallery(chart, "PieChartActivity");
|
||||
}
|
||||
|
||||
private SpannableString generateCenterSpannableText() {
|
||||
|
||||
SpannableString s = new SpannableString("MPAndroidChart\ndeveloped by Philipp Jahoda");
|
||||
s.setSpan(new RelativeSizeSpan(1.7f), 0, 14, 0);
|
||||
s.setSpan(new StyleSpan(Typeface.NORMAL), 14, s.length() - 15, 0);
|
||||
s.setSpan(new ForegroundColorSpan(Color.GRAY), 14, s.length() - 15, 0);
|
||||
s.setSpan(new RelativeSizeSpan(.8f), 14, s.length() - 15, 0);
|
||||
s.setSpan(new StyleSpan(Typeface.ITALIC), s.length() - 14, s.length(), 0);
|
||||
s.setSpan(new ForegroundColorSpan(ColorTemplate.getHoloBlue()), s.length() - 14, s.length(), 0);
|
||||
return s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onValueSelected(Entry e, Highlight h) {
|
||||
|
||||
if (e == null)
|
||||
return;
|
||||
Log.i("VAL SELECTED",
|
||||
"Value: " + e.getY() + ", index: " + h.getX()
|
||||
+ ", DataSet index: " + h.getDataSetIndex());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected() {
|
||||
Log.i("PieChart", "nothing selected");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {}
|
||||
}
|
||||
+323
@@ -0,0 +1,323 @@
|
||||
|
||||
package com.android.stockapp.ui.mpchartexample;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Typeface;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.text.SpannableString;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.text.style.RelativeSizeSpan;
|
||||
import android.text.style.StyleSpan;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.SeekBar.OnSeekBarChangeListener;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.ui.mpchartexample.notimportant.DemoBase;
|
||||
import com.github.mikephil.charting.animation.Easing;
|
||||
import com.github.mikephil.charting.charts.PieChart;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.data.PieData;
|
||||
import com.github.mikephil.charting.data.PieDataSet;
|
||||
import com.github.mikephil.charting.data.PieEntry;
|
||||
import com.github.mikephil.charting.formatter.PercentFormatter;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IDataSet;
|
||||
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
|
||||
import com.github.mikephil.charting.utils.ColorTemplate;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class PiePolylineChartActivity extends DemoBase implements OnSeekBarChangeListener,
|
||||
OnChartValueSelectedListener {
|
||||
|
||||
private PieChart chart;
|
||||
private SeekBar seekBarX, seekBarY;
|
||||
private TextView tvX, tvY;
|
||||
|
||||
private Typeface tf;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_piechart);
|
||||
|
||||
setTitle("PiePolylineChartActivity");
|
||||
|
||||
tvX = findViewById(R.id.tvXMax);
|
||||
tvY = findViewById(R.id.tvYMax);
|
||||
|
||||
seekBarX = findViewById(R.id.seekBar1);
|
||||
seekBarY = findViewById(R.id.seekBar2);
|
||||
|
||||
seekBarX.setOnSeekBarChangeListener(this);
|
||||
seekBarY.setOnSeekBarChangeListener(this);
|
||||
|
||||
chart = findViewById(R.id.chart1);
|
||||
chart.setUsePercentValues(true);
|
||||
chart.getDescription().setEnabled(false);
|
||||
chart.setExtraOffsets(5, 10, 5, 5);
|
||||
|
||||
chart.setDragDecelerationFrictionCoef(0.95f);
|
||||
|
||||
tf = Typeface.createFromAsset(getAssets(), "OpenSans-Regular.ttf");
|
||||
|
||||
chart.setCenterTextTypeface(Typeface.createFromAsset(getAssets(), "OpenSans-Light.ttf"));
|
||||
chart.setCenterText(generateCenterSpannableText());
|
||||
|
||||
chart.setExtraOffsets(20.f, 0.f, 20.f, 0.f);
|
||||
|
||||
chart.setDrawHoleEnabled(true);
|
||||
chart.setHoleColor(Color.WHITE);
|
||||
|
||||
chart.setTransparentCircleColor(Color.WHITE);
|
||||
chart.setTransparentCircleAlpha(110);
|
||||
|
||||
chart.setHoleRadius(58f);
|
||||
chart.setTransparentCircleRadius(61f);
|
||||
|
||||
chart.setDrawCenterText(true);
|
||||
|
||||
chart.setRotationAngle(0);
|
||||
// enable rotation of the chart by touch
|
||||
chart.setRotationEnabled(true);
|
||||
chart.setHighlightPerTapEnabled(true);
|
||||
|
||||
// chart.setUnit(" €");
|
||||
// chart.setDrawUnitsInChart(true);
|
||||
|
||||
// add a selection listener
|
||||
chart.setOnChartValueSelectedListener(this);
|
||||
|
||||
seekBarX.setProgress(4);
|
||||
seekBarY.setProgress(100);
|
||||
|
||||
chart.animateY(1400, Easing.EaseInOutQuad);
|
||||
// chart.spin(2000, 0, 360);
|
||||
|
||||
Legend l = chart.getLegend();
|
||||
l.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
|
||||
l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT);
|
||||
l.setOrientation(Legend.LegendOrientation.VERTICAL);
|
||||
l.setDrawInside(false);
|
||||
l.setEnabled(false);
|
||||
}
|
||||
|
||||
private void setData(int count, float range) {
|
||||
|
||||
ArrayList<PieEntry> entries = new ArrayList<>();
|
||||
|
||||
// NOTE: The order of the entries when being added to the entries array determines their position around the center of
|
||||
// the chart.
|
||||
for (int i = 0; i < count; i++) {
|
||||
entries.add(new PieEntry((float) (Math.random() * range) + range / 5, parties[i % parties.length]));
|
||||
}
|
||||
|
||||
PieDataSet dataSet = new PieDataSet(entries, "Election Results");
|
||||
dataSet.setSliceSpace(3f);
|
||||
dataSet.setSelectionShift(5f);
|
||||
|
||||
// add a lot of colors
|
||||
|
||||
ArrayList<Integer> colors = new ArrayList<>();
|
||||
|
||||
for (int c : ColorTemplate.VORDIPLOM_COLORS)
|
||||
colors.add(c);
|
||||
|
||||
for (int c : ColorTemplate.JOYFUL_COLORS)
|
||||
colors.add(c);
|
||||
|
||||
for (int c : ColorTemplate.COLORFUL_COLORS)
|
||||
colors.add(c);
|
||||
|
||||
for (int c : ColorTemplate.LIBERTY_COLORS)
|
||||
colors.add(c);
|
||||
|
||||
for (int c : ColorTemplate.PASTEL_COLORS)
|
||||
colors.add(c);
|
||||
|
||||
colors.add(ColorTemplate.getHoloBlue());
|
||||
|
||||
dataSet.setColors(colors);
|
||||
//dataSet.setSelectionShift(0f);
|
||||
|
||||
|
||||
dataSet.setValueLinePart1OffsetPercentage(80.f);
|
||||
dataSet.setValueLinePart1Length(0.2f);
|
||||
dataSet.setValueLinePart2Length(0.4f);
|
||||
//dataSet.setUsingSliceColorAsValueLineColor(true);
|
||||
|
||||
//dataSet.setXValuePosition(PieDataSet.ValuePosition.OUTSIDE_SLICE);
|
||||
dataSet.setYValuePosition(PieDataSet.ValuePosition.OUTSIDE_SLICE);
|
||||
|
||||
PieData data = new PieData(dataSet);
|
||||
data.setValueFormatter(new PercentFormatter());
|
||||
data.setValueTextSize(11f);
|
||||
data.setValueTextColor(Color.BLACK);
|
||||
data.setValueTypeface(tf);
|
||||
chart.setData(data);
|
||||
|
||||
// undo all highlights
|
||||
chart.highlightValues(null);
|
||||
|
||||
chart.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.pie, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.viewGithub: {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/PiePolylineChartActivity.java"));
|
||||
startActivity(i);
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleValues: {
|
||||
for (IDataSet<?> set : chart.getData().getDataSets())
|
||||
set.setDrawValues(!set.isDrawValuesEnabled());
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleHole: {
|
||||
if (chart.isDrawHoleEnabled())
|
||||
chart.setDrawHoleEnabled(false);
|
||||
else
|
||||
chart.setDrawHoleEnabled(true);
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleMinAngles: {
|
||||
if (chart.getMinAngleForSlices() == 0f)
|
||||
chart.setMinAngleForSlices(36f);
|
||||
else
|
||||
chart.setMinAngleForSlices(0f);
|
||||
chart.notifyDataSetChanged();
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleCurvedSlices: {
|
||||
boolean toSet = !chart.isDrawRoundedSlicesEnabled() || !chart.isDrawHoleEnabled();
|
||||
chart.setDrawRoundedSlices(toSet);
|
||||
if (toSet && !chart.isDrawHoleEnabled()) {
|
||||
chart.setDrawHoleEnabled(true);
|
||||
}
|
||||
if (toSet && chart.isDrawSlicesUnderHoleEnabled()) {
|
||||
chart.setDrawSlicesUnderHole(false);
|
||||
}
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionDrawCenter: {
|
||||
if (chart.isDrawCenterTextEnabled())
|
||||
chart.setDrawCenterText(false);
|
||||
else
|
||||
chart.setDrawCenterText(true);
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleXValues: {
|
||||
|
||||
chart.setDrawEntryLabels(!chart.isDrawEntryLabelsEnabled());
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionTogglePercent:
|
||||
chart.setUsePercentValues(!chart.isUsePercentValuesEnabled());
|
||||
chart.invalidate();
|
||||
break;
|
||||
case R.id.animateX: {
|
||||
chart.animateX(1400);
|
||||
break;
|
||||
}
|
||||
case R.id.animateY: {
|
||||
chart.animateY(1400);
|
||||
break;
|
||||
}
|
||||
case R.id.animateXY: {
|
||||
chart.animateXY(1400, 1400);
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleSpin: {
|
||||
chart.spin(1000, chart.getRotationAngle(), chart.getRotationAngle() + 360, Easing.EaseInOutCubic);
|
||||
break;
|
||||
}
|
||||
case R.id.actionSave: {
|
||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
|
||||
saveToGallery();
|
||||
} else {
|
||||
requestStoragePermission(chart);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
|
||||
tvX.setText(String.valueOf(seekBarX.getProgress()));
|
||||
tvY.setText(String.valueOf(seekBarY.getProgress()));
|
||||
|
||||
setData(seekBarX.getProgress(), seekBarY.getProgress());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveToGallery() {
|
||||
saveToGallery(chart, "PiePolylineChartActivity");
|
||||
}
|
||||
|
||||
private SpannableString generateCenterSpannableText() {
|
||||
|
||||
SpannableString s = new SpannableString("MPAndroidChart\ndeveloped by Philipp Jahoda");
|
||||
s.setSpan(new RelativeSizeSpan(1.5f), 0, 14, 0);
|
||||
s.setSpan(new StyleSpan(Typeface.NORMAL), 14, s.length() - 15, 0);
|
||||
s.setSpan(new ForegroundColorSpan(Color.GRAY), 14, s.length() - 15, 0);
|
||||
s.setSpan(new RelativeSizeSpan(.65f), 14, s.length() - 15, 0);
|
||||
s.setSpan(new StyleSpan(Typeface.ITALIC), s.length() - 14, s.length(), 0);
|
||||
s.setSpan(new ForegroundColorSpan(ColorTemplate.getHoloBlue()), s.length() - 14, s.length(), 0);
|
||||
return s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onValueSelected(Entry e, Highlight h) {
|
||||
|
||||
if (e == null)
|
||||
return;
|
||||
Log.i("VAL SELECTED",
|
||||
"Value: " + e.getY() + ", xIndex: " + e.getX()
|
||||
+ ", DataSet index: " + h.getDataSetIndex());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected() {
|
||||
Log.i("PieChart", "nothing selected");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {}
|
||||
}
|
||||
+260
@@ -0,0 +1,260 @@
|
||||
package com.android.stockapp.ui.mpchartexample;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Color;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.ui.mpchartexample.custom.RadarMarkerView;
|
||||
import com.android.stockapp.ui.mpchartexample.notimportant.DemoBase;
|
||||
import com.github.mikephil.charting.animation.Easing;
|
||||
import com.github.mikephil.charting.charts.RadarChart;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.components.MarkerView;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
import com.github.mikephil.charting.data.RadarData;
|
||||
import com.github.mikephil.charting.data.RadarDataSet;
|
||||
import com.github.mikephil.charting.data.RadarEntry;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IDataSet;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IRadarDataSet;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class RadarChartActivity extends DemoBase {
|
||||
|
||||
private RadarChart chart;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_radarchart);
|
||||
|
||||
setTitle("RadarChartActivity");
|
||||
|
||||
chart = findViewById(R.id.chart1);
|
||||
chart.setBackgroundColor(Color.rgb(60, 65, 82));
|
||||
|
||||
chart.getDescription().setEnabled(false);
|
||||
|
||||
chart.setWebLineWidth(1f);
|
||||
chart.setWebColor(Color.LTGRAY);
|
||||
chart.setWebLineWidthInner(1f);
|
||||
chart.setWebColorInner(Color.LTGRAY);
|
||||
chart.setWebAlpha(100);
|
||||
|
||||
// create a custom MarkerView (extend MarkerView) and specify the layout
|
||||
// to use for it
|
||||
MarkerView mv = new RadarMarkerView(this, R.layout.radar_markerview);
|
||||
mv.setChartView(chart); // For bounds control
|
||||
chart.setMarker(mv); // Set the marker to the chart
|
||||
|
||||
setData();
|
||||
|
||||
chart.animateXY(1400, 1400, Easing.EaseInOutQuad);
|
||||
|
||||
XAxis xAxis = chart.getXAxis();
|
||||
xAxis.setTypeface(tfLight);
|
||||
xAxis.setTextSize(9f);
|
||||
xAxis.setYOffset(0f);
|
||||
xAxis.setXOffset(0f);
|
||||
xAxis.setValueFormatter(new ValueFormatter() {
|
||||
|
||||
private final String[] mActivities = new String[]{"Burger", "Steak", "Salad", "Pasta", "Pizza"};
|
||||
|
||||
@Override
|
||||
public String getFormattedValue(float value) {
|
||||
return mActivities[(int) value % mActivities.length];
|
||||
}
|
||||
});
|
||||
xAxis.setTextColor(Color.WHITE);
|
||||
|
||||
YAxis yAxis = chart.getYAxis();
|
||||
yAxis.setTypeface(tfLight);
|
||||
yAxis.setLabelCount(5, false);
|
||||
yAxis.setTextSize(9f);
|
||||
yAxis.setAxisMinimum(0f);
|
||||
yAxis.setAxisMaximum(80f);
|
||||
yAxis.setDrawLabels(false);
|
||||
|
||||
Legend l = chart.getLegend();
|
||||
l.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
|
||||
l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER);
|
||||
l.setOrientation(Legend.LegendOrientation.HORIZONTAL);
|
||||
l.setDrawInside(false);
|
||||
l.setTypeface(tfLight);
|
||||
l.setXEntrySpace(7f);
|
||||
l.setYEntrySpace(5f);
|
||||
l.setTextColor(Color.WHITE);
|
||||
}
|
||||
|
||||
private void setData() {
|
||||
|
||||
float mul = 80;
|
||||
float min = 20;
|
||||
int cnt = 5;
|
||||
|
||||
ArrayList<RadarEntry> entries1 = new ArrayList<>();
|
||||
ArrayList<RadarEntry> entries2 = new ArrayList<>();
|
||||
|
||||
// NOTE: The order of the entries when being added to the entries array determines their position around the center of
|
||||
// the chart.
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
float val1 = (float) (Math.random() * mul) + min;
|
||||
entries1.add(new RadarEntry(val1));
|
||||
|
||||
float val2 = (float) (Math.random() * mul) + min;
|
||||
entries2.add(new RadarEntry(val2));
|
||||
}
|
||||
|
||||
RadarDataSet set1 = new RadarDataSet(entries1, "Last Week");
|
||||
set1.setColor(Color.rgb(103, 110, 129));
|
||||
set1.setFillColor(Color.rgb(103, 110, 129));
|
||||
set1.setDrawFilled(true);
|
||||
set1.setFillAlpha(180);
|
||||
set1.setLineWidth(2f);
|
||||
set1.setDrawHighlightCircleEnabled(true);
|
||||
set1.setDrawHighlightIndicators(false);
|
||||
|
||||
RadarDataSet set2 = new RadarDataSet(entries2, "This Week");
|
||||
set2.setColor(Color.rgb(121, 162, 175));
|
||||
set2.setFillColor(Color.rgb(121, 162, 175));
|
||||
set2.setDrawFilled(true);
|
||||
set2.setFillAlpha(180);
|
||||
set2.setLineWidth(2f);
|
||||
set2.setDrawHighlightCircleEnabled(true);
|
||||
set2.setDrawHighlightIndicators(false);
|
||||
|
||||
ArrayList<IRadarDataSet> sets = new ArrayList<>();
|
||||
sets.add(set1);
|
||||
sets.add(set2);
|
||||
|
||||
RadarData data = new RadarData(sets);
|
||||
data.setValueTypeface(tfLight);
|
||||
data.setValueTextSize(8f);
|
||||
data.setDrawValues(false);
|
||||
data.setValueTextColor(Color.WHITE);
|
||||
|
||||
chart.setData(data);
|
||||
chart.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.radar, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.viewGithub: {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/RadarChartActivity.java"));
|
||||
startActivity(i);
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleValues: {
|
||||
for (IDataSet<?> set : chart.getData().getDataSets())
|
||||
set.setDrawValues(!set.isDrawValuesEnabled());
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleHighlight: {
|
||||
if (chart.getData() != null) {
|
||||
chart.getData().setHighlightEnabled(!chart.getData().isHighlightEnabled());
|
||||
chart.invalidate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleRotate: {
|
||||
if (chart.isRotationEnabled())
|
||||
chart.setRotationEnabled(false);
|
||||
else
|
||||
chart.setRotationEnabled(true);
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleFilled: {
|
||||
|
||||
ArrayList<IRadarDataSet> sets = (ArrayList<IRadarDataSet>) chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (IRadarDataSet set : sets) {
|
||||
if (set.isDrawFilledEnabled())
|
||||
set.setDrawFilled(false);
|
||||
else
|
||||
set.setDrawFilled(true);
|
||||
}
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleHighlightCircle: {
|
||||
|
||||
ArrayList<IRadarDataSet> sets = (ArrayList<IRadarDataSet>) chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (IRadarDataSet set : sets) {
|
||||
set.setDrawHighlightCircleEnabled(!set.isDrawHighlightCircleEnabled());
|
||||
}
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleXLabels: {
|
||||
chart.getXAxis().setEnabled(!chart.getXAxis().isEnabled());
|
||||
chart.notifyDataSetChanged();
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleYLabels: {
|
||||
|
||||
chart.getYAxis().setEnabled(!chart.getYAxis().isEnabled());
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.animateX: {
|
||||
chart.animateX(1400);
|
||||
break;
|
||||
}
|
||||
case R.id.animateY: {
|
||||
chart.animateY(1400);
|
||||
break;
|
||||
}
|
||||
case R.id.animateXY: {
|
||||
chart.animateXY(1400, 1400);
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleSpin: {
|
||||
chart.spin(2000, chart.getRotationAngle(), chart.getRotationAngle() + 360, Easing.EaseInOutCubic);
|
||||
break;
|
||||
}
|
||||
case R.id.actionSave: {
|
||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
|
||||
saveToGallery();
|
||||
} else {
|
||||
requestStoragePermission(chart);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveToGallery() {
|
||||
saveToGallery(chart, "RadarChartActivity");
|
||||
}
|
||||
}
|
||||
+251
@@ -0,0 +1,251 @@
|
||||
|
||||
package com.android.stockapp.ui.mpchartexample;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Color;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.ui.mpchartexample.notimportant.DemoBase;
|
||||
import com.github.mikephil.charting.charts.LineChart;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.components.Legend.LegendForm;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
import com.github.mikephil.charting.components.YAxis.AxisDependency;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.data.LineData;
|
||||
import com.github.mikephil.charting.data.LineDataSet;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
|
||||
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
|
||||
import com.github.mikephil.charting.utils.ColorTemplate;
|
||||
|
||||
public class RealtimeLineChartActivity extends DemoBase implements
|
||||
OnChartValueSelectedListener {
|
||||
|
||||
private LineChart chart;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_realtime_linechart);
|
||||
|
||||
setTitle("RealtimeLineChartActivity");
|
||||
|
||||
chart = findViewById(R.id.chart1);
|
||||
chart.setOnChartValueSelectedListener(this);
|
||||
|
||||
// enable description text
|
||||
chart.getDescription().setEnabled(true);
|
||||
|
||||
// enable touch gestures
|
||||
chart.setTouchEnabled(true);
|
||||
|
||||
// enable scaling and dragging
|
||||
chart.setDragEnabled(true);
|
||||
chart.setScaleEnabled(true);
|
||||
chart.setDrawGridBackground(false);
|
||||
|
||||
// if disabled, scaling can be done on x- and y-axis separately
|
||||
chart.setPinchZoom(true);
|
||||
|
||||
// set an alternative background color
|
||||
chart.setBackgroundColor(Color.LTGRAY);
|
||||
|
||||
LineData data = new LineData();
|
||||
data.setValueTextColor(Color.WHITE);
|
||||
|
||||
// add empty data
|
||||
chart.setData(data);
|
||||
|
||||
// get the legend (only possible after setting data)
|
||||
Legend l = chart.getLegend();
|
||||
|
||||
// modify the legend ...
|
||||
l.setForm(LegendForm.LINE);
|
||||
l.setTypeface(tfLight);
|
||||
l.setTextColor(Color.WHITE);
|
||||
|
||||
XAxis xl = chart.getXAxis();
|
||||
xl.setTypeface(tfLight);
|
||||
xl.setTextColor(Color.WHITE);
|
||||
xl.setDrawGridLines(false);
|
||||
xl.setAvoidFirstLastClipping(true);
|
||||
xl.setEnabled(true);
|
||||
|
||||
YAxis leftAxis = chart.getAxisLeft();
|
||||
leftAxis.setTypeface(tfLight);
|
||||
leftAxis.setTextColor(Color.WHITE);
|
||||
leftAxis.setAxisMaximum(100f);
|
||||
leftAxis.setAxisMinimum(0f);
|
||||
leftAxis.setDrawGridLines(true);
|
||||
|
||||
YAxis rightAxis = chart.getAxisRight();
|
||||
rightAxis.setEnabled(false);
|
||||
|
||||
}
|
||||
|
||||
private void addEntry() {
|
||||
|
||||
LineData data = chart.getData();
|
||||
|
||||
if (data != null) {
|
||||
|
||||
ILineDataSet set = data.getDataSetByIndex(0);
|
||||
// set.addEntry(...); // can be called as well
|
||||
|
||||
if (set == null) {
|
||||
set = createSet();
|
||||
data.addDataSet(set);
|
||||
}
|
||||
|
||||
data.addEntry(new Entry(set.getEntryCount(), (float) (Math.random() * 40) + 30f), 0);
|
||||
data.notifyDataChanged();
|
||||
|
||||
// let the chart know it's data has changed
|
||||
chart.notifyDataSetChanged();
|
||||
|
||||
// limit the number of visible entries
|
||||
chart.setVisibleXRangeMaximum(120);
|
||||
// chart.setVisibleYRange(30, AxisDependency.LEFT);
|
||||
|
||||
// move to the latest entry
|
||||
chart.moveViewToX(data.getEntryCount());
|
||||
|
||||
// this automatically refreshes the chart (calls invalidate())
|
||||
// chart.moveViewTo(data.getXValCount()-7, 55f,
|
||||
// AxisDependency.LEFT);
|
||||
}
|
||||
}
|
||||
|
||||
private LineDataSet createSet() {
|
||||
|
||||
LineDataSet set = new LineDataSet(null, "Dynamic Data");
|
||||
set.setAxisDependency(AxisDependency.LEFT);
|
||||
set.setColor(ColorTemplate.getHoloBlue());
|
||||
set.setCircleColor(Color.WHITE);
|
||||
set.setLineWidth(2f);
|
||||
set.setCircleRadius(4f);
|
||||
set.setFillAlpha(65);
|
||||
set.setFillColor(ColorTemplate.getHoloBlue());
|
||||
set.setHighLightColor(Color.rgb(244, 117, 117));
|
||||
set.setValueTextColor(Color.WHITE);
|
||||
set.setValueTextSize(9f);
|
||||
set.setDrawValues(false);
|
||||
return set;
|
||||
}
|
||||
|
||||
private Thread thread;
|
||||
|
||||
private void feedMultiple() {
|
||||
|
||||
if (thread != null)
|
||||
thread.interrupt();
|
||||
|
||||
final Runnable runnable = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
addEntry();
|
||||
}
|
||||
};
|
||||
|
||||
thread = new Thread(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
|
||||
// Don't generate garbage runnables inside the loop.
|
||||
runOnUiThread(runnable);
|
||||
|
||||
try {
|
||||
Thread.sleep(25);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
thread.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.realtime, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.viewGithub: {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/RealtimeLineChartActivity.java"));
|
||||
startActivity(i);
|
||||
break;
|
||||
}
|
||||
case R.id.actionAdd: {
|
||||
addEntry();
|
||||
break;
|
||||
}
|
||||
case R.id.actionClear: {
|
||||
chart.clearValues();
|
||||
Toast.makeText(this, "Chart cleared!", Toast.LENGTH_SHORT).show();
|
||||
break;
|
||||
}
|
||||
case R.id.actionFeedMultiple: {
|
||||
feedMultiple();
|
||||
break;
|
||||
}
|
||||
case R.id.actionSave: {
|
||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
|
||||
saveToGallery();
|
||||
} else {
|
||||
requestStoragePermission(chart);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveToGallery() {
|
||||
saveToGallery(chart, "RealtimeLineChartActivity");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onValueSelected(Entry e, Highlight h) {
|
||||
Log.i("Entry selected", e.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected() {
|
||||
Log.i("Nothing selected", "Nothing selected.");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
|
||||
if (thread != null) {
|
||||
thread.interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
+249
@@ -0,0 +1,249 @@
|
||||
|
||||
package com.android.stockapp.ui.mpchartexample;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.SeekBar.OnSeekBarChangeListener;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.ui.mpchartexample.custom.CustomScatterShapeRenderer;
|
||||
import com.android.stockapp.ui.mpchartexample.notimportant.DemoBase;
|
||||
import com.github.mikephil.charting.charts.ScatterChart;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.data.ScatterData;
|
||||
import com.github.mikephil.charting.data.ScatterDataSet;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IScatterDataSet;
|
||||
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
|
||||
import com.github.mikephil.charting.utils.ColorTemplate;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ScatterChartActivity extends DemoBase implements OnSeekBarChangeListener,
|
||||
OnChartValueSelectedListener {
|
||||
|
||||
private ScatterChart chart;
|
||||
private SeekBar seekBarX, seekBarY;
|
||||
private TextView tvX, tvY;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_scatterchart);
|
||||
|
||||
setTitle("ScatterChartActivity");
|
||||
|
||||
tvX = findViewById(R.id.tvXMax);
|
||||
tvY = findViewById(R.id.tvYMax);
|
||||
|
||||
seekBarX = findViewById(R.id.seekBar1);
|
||||
seekBarX.setOnSeekBarChangeListener(this);
|
||||
|
||||
seekBarY = findViewById(R.id.seekBar2);
|
||||
seekBarY.setOnSeekBarChangeListener(this);
|
||||
|
||||
chart = findViewById(R.id.chart1);
|
||||
chart.getDescription().setEnabled(false);
|
||||
chart.setOnChartValueSelectedListener(this);
|
||||
|
||||
chart.setDrawGridBackground(false);
|
||||
chart.setTouchEnabled(true);
|
||||
chart.setMaxHighlightDistance(50f);
|
||||
|
||||
// enable scaling and dragging
|
||||
chart.setDragEnabled(true);
|
||||
chart.setScaleEnabled(true);
|
||||
|
||||
chart.setMaxVisibleValueCount(200);
|
||||
chart.setPinchZoom(true);
|
||||
|
||||
seekBarX.setProgress(45);
|
||||
seekBarY.setProgress(100);
|
||||
|
||||
Legend l = chart.getLegend();
|
||||
l.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
|
||||
l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT);
|
||||
l.setOrientation(Legend.LegendOrientation.VERTICAL);
|
||||
l.setDrawInside(false);
|
||||
l.setTypeface(tfLight);
|
||||
l.setXOffset(5f);
|
||||
|
||||
YAxis yl = chart.getAxisLeft();
|
||||
yl.setTypeface(tfLight);
|
||||
yl.setAxisMinimum(0f); // this replaces setStartAtZero(true)
|
||||
|
||||
chart.getAxisRight().setEnabled(false);
|
||||
|
||||
XAxis xl = chart.getXAxis();
|
||||
xl.setTypeface(tfLight);
|
||||
xl.setDrawGridLines(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
|
||||
tvX.setText(String.valueOf(seekBarX.getProgress()));
|
||||
tvY.setText(String.valueOf(seekBarY.getProgress()));
|
||||
|
||||
ArrayList<Entry> values1 = new ArrayList<>();
|
||||
ArrayList<Entry> values2 = new ArrayList<>();
|
||||
ArrayList<Entry> values3 = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < seekBarX.getProgress(); i++) {
|
||||
float val = (float) (Math.random() * seekBarY.getProgress()) + 3;
|
||||
values1.add(new Entry(i, val));
|
||||
}
|
||||
|
||||
for (int i = 0; i < seekBarX.getProgress(); i++) {
|
||||
float val = (float) (Math.random() * seekBarY.getProgress()) + 3;
|
||||
values2.add(new Entry(i+0.33f, val));
|
||||
}
|
||||
|
||||
for (int i = 0; i < seekBarX.getProgress(); i++) {
|
||||
float val = (float) (Math.random() * seekBarY.getProgress()) + 3;
|
||||
values3.add(new Entry(i+0.66f, val));
|
||||
}
|
||||
|
||||
// create a dataset and give it a type
|
||||
ScatterDataSet set1 = new ScatterDataSet(values1, "DS 1");
|
||||
set1.setScatterShape(ScatterChart.ScatterShape.SQUARE);
|
||||
set1.setColor(ColorTemplate.COLORFUL_COLORS[0]);
|
||||
ScatterDataSet set2 = new ScatterDataSet(values2, "DS 2");
|
||||
set2.setScatterShape(ScatterChart.ScatterShape.CIRCLE);
|
||||
set2.setScatterShapeHoleColor(ColorTemplate.COLORFUL_COLORS[3]);
|
||||
set2.setScatterShapeHoleRadius(3f);
|
||||
set2.setColor(ColorTemplate.COLORFUL_COLORS[1]);
|
||||
ScatterDataSet set3 = new ScatterDataSet(values3, "DS 3");
|
||||
set3.setShapeRenderer(new CustomScatterShapeRenderer());
|
||||
set3.setColor(ColorTemplate.COLORFUL_COLORS[2]);
|
||||
|
||||
set1.setScatterShapeSize(8f);
|
||||
set2.setScatterShapeSize(8f);
|
||||
set3.setScatterShapeSize(8f);
|
||||
|
||||
ArrayList<IScatterDataSet> dataSets = new ArrayList<>();
|
||||
dataSets.add(set1); // add the data sets
|
||||
dataSets.add(set2);
|
||||
dataSets.add(set3);
|
||||
|
||||
// create a data object with the data sets
|
||||
ScatterData data = new ScatterData(dataSets);
|
||||
data.setValueTypeface(tfLight);
|
||||
|
||||
chart.setData(data);
|
||||
chart.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.scatter, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.viewGithub: {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/ScatterChartActivity.java"));
|
||||
startActivity(i);
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleValues: {
|
||||
List<IScatterDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (IScatterDataSet iSet : sets) {
|
||||
|
||||
ScatterDataSet set = (ScatterDataSet) iSet;
|
||||
set.setDrawValues(!set.isDrawValuesEnabled());
|
||||
}
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleHighlight: {
|
||||
if(chart.getData() != null) {
|
||||
chart.getData().setHighlightEnabled(!chart.getData().isHighlightEnabled());
|
||||
chart.invalidate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case R.id.actionTogglePinch: {
|
||||
if (chart.isPinchZoomEnabled())
|
||||
chart.setPinchZoom(false);
|
||||
else
|
||||
chart.setPinchZoom(true);
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleAutoScaleMinMax: {
|
||||
chart.setAutoScaleMinMaxEnabled(!chart.isAutoScaleMinMaxEnabled());
|
||||
chart.notifyDataSetChanged();
|
||||
break;
|
||||
}
|
||||
case R.id.animateX: {
|
||||
chart.animateX(3000);
|
||||
break;
|
||||
}
|
||||
case R.id.animateY: {
|
||||
chart.animateY(3000);
|
||||
break;
|
||||
}
|
||||
case R.id.animateXY: {
|
||||
|
||||
chart.animateXY(3000, 3000);
|
||||
break;
|
||||
}
|
||||
case R.id.actionSave: {
|
||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
|
||||
saveToGallery();
|
||||
} else {
|
||||
requestStoragePermission(chart);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveToGallery() {
|
||||
saveToGallery(chart, "ScatterChartActivity");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onValueSelected(Entry e, Highlight h) {
|
||||
Log.i("VAL SELECTED",
|
||||
"Value: " + e.getY() + ", xIndex: " + e.getX()
|
||||
+ ", DataSet index: " + h.getDataSetIndex());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected() {}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {}
|
||||
}
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
|
||||
package com.android.stockapp.ui.mpchartexample;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.ui.mpchartexample.notimportant.DemoBase;
|
||||
import com.github.mikephil.charting.charts.BarChart;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.XAxis.XAxisPosition;
|
||||
import com.github.mikephil.charting.data.BarData;
|
||||
import com.github.mikephil.charting.data.BarDataSet;
|
||||
import com.github.mikephil.charting.data.BarEntry;
|
||||
import com.github.mikephil.charting.utils.ColorTemplate;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
public class ScrollViewActivity extends DemoBase {
|
||||
|
||||
private BarChart chart;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_scrollview);
|
||||
|
||||
setTitle("ScrollViewActivity");
|
||||
|
||||
chart = findViewById(R.id.chart1);
|
||||
|
||||
chart.getDescription().setEnabled(false);
|
||||
|
||||
// scaling can now only be done on x- and y-axis separately
|
||||
chart.setPinchZoom(false);
|
||||
|
||||
chart.setDrawBarShadow(false);
|
||||
chart.setDrawGridBackground(false);
|
||||
|
||||
XAxis xAxis = chart.getXAxis();
|
||||
xAxis.setPosition(XAxisPosition.BOTTOM);
|
||||
xAxis.setDrawGridLines(false);
|
||||
|
||||
chart.getAxisLeft().setDrawGridLines(false);
|
||||
|
||||
chart.getLegend().setEnabled(false);
|
||||
|
||||
setData(10);
|
||||
chart.setFitBars(true);
|
||||
}
|
||||
|
||||
private void setData(int count) {
|
||||
|
||||
ArrayList<BarEntry> values = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
float val = (float) (Math.random() * count) + 15;
|
||||
values.add(new BarEntry(i, (int) val));
|
||||
}
|
||||
|
||||
BarDataSet set = new BarDataSet(values, "Data Set");
|
||||
set.setColors(ColorTemplate.VORDIPLOM_COLORS);
|
||||
set.setDrawValues(false);
|
||||
|
||||
BarData data = new BarData(set);
|
||||
|
||||
chart.setData(data);
|
||||
chart.invalidate();
|
||||
chart.animateY(800);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.only_github, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.viewGithub: {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/ScrollViewActivity.java"));
|
||||
startActivity(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveToGallery() { /* Intentionally left empty */ }
|
||||
}
|
||||
+286
@@ -0,0 +1,286 @@
|
||||
package com.android.stockapp.ui.mpchartexample;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Color;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.SeekBar.OnSeekBarChangeListener;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.ui.mpchartexample.custom.MyValueFormatter;
|
||||
import com.android.stockapp.ui.mpchartexample.notimportant.DemoBase;
|
||||
import com.github.mikephil.charting.charts.BarChart;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.XAxis.XAxisPosition;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
import com.github.mikephil.charting.data.BarData;
|
||||
import com.github.mikephil.charting.data.BarDataSet;
|
||||
import com.github.mikephil.charting.data.BarEntry;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.formatter.StackedValueFormatter;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IBarDataSet;
|
||||
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
|
||||
import com.github.mikephil.charting.utils.ColorTemplate;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class StackedBarActivity extends DemoBase implements OnSeekBarChangeListener, OnChartValueSelectedListener {
|
||||
|
||||
private BarChart chart;
|
||||
private SeekBar seekBarX, seekBarY;
|
||||
private TextView tvX, tvY;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_barchart);
|
||||
|
||||
setTitle("StackedBarActivity");
|
||||
|
||||
tvX = findViewById(R.id.tvXMax);
|
||||
tvY = findViewById(R.id.tvYMax);
|
||||
|
||||
seekBarX = findViewById(R.id.seekBar1);
|
||||
seekBarX.setOnSeekBarChangeListener(this);
|
||||
|
||||
seekBarY = findViewById(R.id.seekBar2);
|
||||
seekBarY.setOnSeekBarChangeListener(this);
|
||||
|
||||
chart = findViewById(R.id.chart1);
|
||||
chart.setOnChartValueSelectedListener(this);
|
||||
|
||||
chart.getDescription().setEnabled(false);
|
||||
|
||||
// if more than 60 entries are displayed in the chart, no values will be
|
||||
// drawn
|
||||
chart.setMaxVisibleValueCount(40);
|
||||
|
||||
// scaling can now only be done on x- and y-axis separately
|
||||
chart.setPinchZoom(false);
|
||||
|
||||
chart.setDrawGridBackground(false);
|
||||
chart.setDrawBarShadow(false);
|
||||
|
||||
chart.setDrawValueAboveBar(false);
|
||||
chart.setHighlightFullBarEnabled(false);
|
||||
|
||||
// change the position of the y-labels
|
||||
YAxis leftAxis = chart.getAxisLeft();
|
||||
leftAxis.setValueFormatter(new MyValueFormatter("K"));
|
||||
leftAxis.setAxisMinimum(0f); // this replaces setStartAtZero(true)
|
||||
chart.getAxisRight().setEnabled(false);
|
||||
|
||||
XAxis xLabels = chart.getXAxis();
|
||||
xLabels.setPosition(XAxisPosition.TOP);
|
||||
|
||||
// chart.setDrawXLabels(false);
|
||||
// chart.setDrawYLabels(false);
|
||||
|
||||
// setting data
|
||||
seekBarX.setProgress(12);
|
||||
seekBarY.setProgress(100);
|
||||
|
||||
Legend l = chart.getLegend();
|
||||
l.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);
|
||||
l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT);
|
||||
l.setOrientation(Legend.LegendOrientation.HORIZONTAL);
|
||||
l.setDrawInside(false);
|
||||
l.setFormSize(8f);
|
||||
l.setFormToTextSpace(4f);
|
||||
l.setXEntrySpace(6f);
|
||||
|
||||
// chart.setDrawLegend(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
|
||||
tvX.setText(String.valueOf(seekBarX.getProgress()));
|
||||
tvY.setText(String.valueOf(seekBarY.getProgress()));
|
||||
|
||||
ArrayList<BarEntry> values = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < seekBarX.getProgress(); i++) {
|
||||
float mul = (seekBarY.getProgress() + 1);
|
||||
float val1 = (float) (Math.random() * mul) + mul / 3;
|
||||
float val2 = (float) (Math.random() * mul) + mul / 3;
|
||||
float val3 = (float) (Math.random() * mul) + mul / 3;
|
||||
|
||||
values.add(new BarEntry(
|
||||
i,
|
||||
new float[]{val1, val2, val3},
|
||||
getResources().getDrawable(R.drawable.star)));
|
||||
}
|
||||
|
||||
BarDataSet set1;
|
||||
|
||||
if (chart.getData() != null &&
|
||||
chart.getData().getDataSetCount() > 0) {
|
||||
set1 = (BarDataSet) chart.getData().getDataSetByIndex(0);
|
||||
set1.setValues(values);
|
||||
chart.getData().notifyDataChanged();
|
||||
chart.notifyDataSetChanged();
|
||||
} else {
|
||||
set1 = new BarDataSet(values, "Statistics Vienna 2014");
|
||||
set1.setDrawIcons(false);
|
||||
set1.setColors(getColors());
|
||||
set1.setStackLabels(new String[]{"Births", "Divorces", "Marriages"});
|
||||
|
||||
ArrayList<IBarDataSet> dataSets = new ArrayList<>();
|
||||
dataSets.add(set1);
|
||||
|
||||
BarData data = new BarData(dataSets);
|
||||
data.setValueFormatter(new StackedValueFormatter(false, "", 1));
|
||||
data.setValueTextColor(Color.WHITE);
|
||||
|
||||
chart.setData(data);
|
||||
}
|
||||
|
||||
chart.setFitBars(true);
|
||||
chart.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.bar, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.viewGithub: {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/StackedBarActivity.java"));
|
||||
startActivity(i);
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleValues: {
|
||||
List<IBarDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (IBarDataSet iSet : sets) {
|
||||
|
||||
BarDataSet set = (BarDataSet) iSet;
|
||||
set.setDrawValues(!set.isDrawValuesEnabled());
|
||||
}
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleIcons: {
|
||||
List<IBarDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (IBarDataSet iSet : sets) {
|
||||
|
||||
BarDataSet set = (BarDataSet) iSet;
|
||||
set.setDrawIcons(!set.isDrawIconsEnabled());
|
||||
}
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleHighlight: {
|
||||
if (chart.getData() != null) {
|
||||
chart.getData().setHighlightEnabled(!chart.getData().isHighlightEnabled());
|
||||
chart.invalidate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case R.id.actionTogglePinch: {
|
||||
if (chart.isPinchZoomEnabled())
|
||||
chart.setPinchZoom(false);
|
||||
else
|
||||
chart.setPinchZoom(true);
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleAutoScaleMinMax: {
|
||||
chart.setAutoScaleMinMaxEnabled(!chart.isAutoScaleMinMaxEnabled());
|
||||
chart.notifyDataSetChanged();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleBarBorders: {
|
||||
for (IBarDataSet set : chart.getData().getDataSets())
|
||||
((BarDataSet) set).setBarBorderWidth(set.getBarBorderWidth() == 1.f ? 0.f : 1.f);
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.animateX: {
|
||||
chart.animateX(2000);
|
||||
break;
|
||||
}
|
||||
case R.id.animateY: {
|
||||
chart.animateY(2000);
|
||||
break;
|
||||
}
|
||||
case R.id.animateXY: {
|
||||
|
||||
chart.animateXY(2000, 2000);
|
||||
break;
|
||||
}
|
||||
case R.id.actionSave: {
|
||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
|
||||
saveToGallery();
|
||||
} else {
|
||||
requestStoragePermission(chart);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveToGallery() {
|
||||
saveToGallery(chart, "StackedBarActivity");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {}
|
||||
|
||||
@Override
|
||||
public void onValueSelected(Entry e, Highlight h) {
|
||||
|
||||
BarEntry entry = (BarEntry) e;
|
||||
|
||||
if (entry.getYVals() != null)
|
||||
Log.i("VAL SELECTED", "Value: " + entry.getYVals()[h.getStackIndex()]);
|
||||
else
|
||||
Log.i("VAL SELECTED", "Value: " + entry.getY());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected() {}
|
||||
|
||||
private int[] getColors() {
|
||||
|
||||
// have as many colors as stack-values per entry
|
||||
int[] colors = new int[3];
|
||||
|
||||
System.arraycopy(ColorTemplate.MATERIAL_COLORS, 0, colors, 0, 3);
|
||||
|
||||
return colors;
|
||||
}
|
||||
}
|
||||
+256
@@ -0,0 +1,256 @@
|
||||
package com.android.stockapp.ui.mpchartexample;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Color;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.ui.mpchartexample.notimportant.DemoBase;
|
||||
import com.github.mikephil.charting.charts.HorizontalBarChart;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.XAxis.XAxisPosition;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
import com.github.mikephil.charting.data.BarData;
|
||||
import com.github.mikephil.charting.data.BarDataSet;
|
||||
import com.github.mikephil.charting.data.BarEntry;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IBarDataSet;
|
||||
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class StackedBarActivityNegative extends DemoBase implements
|
||||
OnChartValueSelectedListener {
|
||||
|
||||
private HorizontalBarChart chart;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_age_distribution);
|
||||
|
||||
setTitle("StackedBarActivityNegative");
|
||||
|
||||
chart = findViewById(R.id.chart1);
|
||||
chart.setOnChartValueSelectedListener(this);
|
||||
chart.setDrawGridBackground(false);
|
||||
chart.getDescription().setEnabled(false);
|
||||
|
||||
// scaling can now only be done on x- and y-axis separately
|
||||
chart.setPinchZoom(false);
|
||||
|
||||
chart.setDrawBarShadow(false);
|
||||
chart.setDrawValueAboveBar(true);
|
||||
chart.setHighlightFullBarEnabled(false);
|
||||
|
||||
chart.getAxisLeft().setEnabled(false);
|
||||
chart.getAxisRight().setAxisMaximum(25f);
|
||||
chart.getAxisRight().setAxisMinimum(-25f);
|
||||
chart.getAxisRight().setDrawGridLines(false);
|
||||
chart.getAxisRight().setDrawZeroLine(true);
|
||||
chart.getAxisRight().setLabelCount(7, false);
|
||||
chart.getAxisRight().setValueFormatter(new CustomFormatter());
|
||||
chart.getAxisRight().setTextSize(9f);
|
||||
|
||||
XAxis xAxis = chart.getXAxis();
|
||||
xAxis.setPosition(XAxisPosition.BOTH_SIDED);
|
||||
xAxis.setDrawGridLines(false);
|
||||
xAxis.setDrawAxisLine(false);
|
||||
xAxis.setTextSize(9f);
|
||||
xAxis.setAxisMinimum(0f);
|
||||
xAxis.setAxisMaximum(110f);
|
||||
xAxis.setCenterAxisLabels(true);
|
||||
xAxis.setLabelCount(12);
|
||||
xAxis.setGranularity(10f);
|
||||
xAxis.setValueFormatter(new ValueFormatter() {
|
||||
|
||||
private final DecimalFormat format = new DecimalFormat("###");
|
||||
|
||||
@Override
|
||||
public String getFormattedValue(float value) {
|
||||
return format.format(value) + "-" + format.format(value + 10);
|
||||
}
|
||||
});
|
||||
|
||||
Legend l = chart.getLegend();
|
||||
l.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);
|
||||
l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT);
|
||||
l.setOrientation(Legend.LegendOrientation.HORIZONTAL);
|
||||
l.setDrawInside(false);
|
||||
l.setFormSize(8f);
|
||||
l.setFormToTextSpace(4f);
|
||||
l.setXEntrySpace(6f);
|
||||
|
||||
// IMPORTANT: When using negative values in stacked bars, always make sure the negative values are in the array first
|
||||
ArrayList<BarEntry> values = new ArrayList<>();
|
||||
values.add(new BarEntry(5, new float[]{ -10, 10 }));
|
||||
values.add(new BarEntry(15, new float[]{ -12, 13 }));
|
||||
values.add(new BarEntry(25, new float[]{ -15, 15 }));
|
||||
values.add(new BarEntry(35, new float[]{ -17, 17 }));
|
||||
values.add(new BarEntry(45, new float[]{ -19, 20 }));
|
||||
values.add(new BarEntry(45, new float[]{ -19, 20 }, getResources().getDrawable(R.drawable.star)));
|
||||
values.add(new BarEntry(55, new float[]{ -19, 19 }));
|
||||
values.add(new BarEntry(65, new float[]{ -16, 16 }));
|
||||
values.add(new BarEntry(75, new float[]{ -13, 14 }));
|
||||
values.add(new BarEntry(85, new float[]{ -10, 11 }));
|
||||
values.add(new BarEntry(95, new float[]{ -5, 6 }));
|
||||
values.add(new BarEntry(105, new float[]{ -1, 2 }));
|
||||
|
||||
BarDataSet set = new BarDataSet(values, "Age Distribution");
|
||||
set.setDrawIcons(false);
|
||||
set.setValueFormatter(new CustomFormatter());
|
||||
set.setValueTextSize(7f);
|
||||
set.setAxisDependency(YAxis.AxisDependency.RIGHT);
|
||||
set.setColors(Color.rgb(67,67,72), Color.rgb(124,181,236));
|
||||
set.setStackLabels(new String[]{
|
||||
"Men", "Women"
|
||||
});
|
||||
|
||||
BarData data = new BarData(set);
|
||||
data.setBarWidth(8.5f);
|
||||
chart.setData(data);
|
||||
chart.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.bar, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.viewGithub: {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/StackedBarActivityNegative.java"));
|
||||
startActivity(i);
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleValues: {
|
||||
List<IBarDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (IBarDataSet iSet : sets) {
|
||||
|
||||
BarDataSet set = (BarDataSet) iSet;
|
||||
set.setDrawValues(!set.isDrawValuesEnabled());
|
||||
}
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleIcons: {
|
||||
List<IBarDataSet> sets = chart.getData()
|
||||
.getDataSets();
|
||||
|
||||
for (IBarDataSet iSet : sets) {
|
||||
|
||||
BarDataSet set = (BarDataSet) iSet;
|
||||
set.setDrawIcons(!set.isDrawIconsEnabled());
|
||||
}
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleHighlight: {
|
||||
if(chart.getData() != null) {
|
||||
chart.getData().setHighlightEnabled(!chart.getData().isHighlightEnabled());
|
||||
chart.invalidate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case R.id.actionTogglePinch: {
|
||||
if (chart.isPinchZoomEnabled())
|
||||
chart.setPinchZoom(false);
|
||||
else
|
||||
chart.setPinchZoom(true);
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleAutoScaleMinMax: {
|
||||
chart.setAutoScaleMinMaxEnabled(!chart.isAutoScaleMinMaxEnabled());
|
||||
chart.notifyDataSetChanged();
|
||||
break;
|
||||
}
|
||||
case R.id.actionToggleBarBorders: {
|
||||
for (IBarDataSet set : chart.getData().getDataSets())
|
||||
((BarDataSet)set).setBarBorderWidth(set.getBarBorderWidth() == 1.f ? 0.f : 1.f);
|
||||
|
||||
chart.invalidate();
|
||||
break;
|
||||
}
|
||||
case R.id.animateX: {
|
||||
chart.animateX(3000);
|
||||
break;
|
||||
}
|
||||
case R.id.animateY: {
|
||||
chart.animateY(3000);
|
||||
break;
|
||||
}
|
||||
case R.id.animateXY: {
|
||||
|
||||
chart.animateXY(3000, 3000);
|
||||
break;
|
||||
}
|
||||
case R.id.actionSave: {
|
||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
|
||||
saveToGallery();
|
||||
} else {
|
||||
requestStoragePermission(chart);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveToGallery() {
|
||||
saveToGallery(chart, "StackedBarActivityNegative");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onValueSelected(Entry e, Highlight h) {
|
||||
BarEntry entry = (BarEntry) e;
|
||||
Log.i("VAL SELECTED",
|
||||
"Value: " + Math.abs(entry.getYVals()[h.getStackIndex()]));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected() {
|
||||
Log.i("NOTING SELECTED", "");
|
||||
}
|
||||
|
||||
private class CustomFormatter extends ValueFormatter {
|
||||
|
||||
private final DecimalFormat mFormat;
|
||||
|
||||
CustomFormatter() {
|
||||
mFormat = new DecimalFormat("###");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormattedValue(float value) {
|
||||
return mFormat.format(Math.abs(value)) + "m";
|
||||
}
|
||||
}
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package com.android.stockapp.ui.mpchartexample.custom;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
|
||||
import com.github.mikephil.charting.interfaces.datasets.IScatterDataSet;
|
||||
import com.github.mikephil.charting.renderer.scatter.IShapeRenderer;
|
||||
import com.github.mikephil.charting.utils.ViewPortHandler;
|
||||
|
||||
/**
|
||||
* Custom shape renderer that draws a single line.
|
||||
* Created by philipp on 26/06/16.
|
||||
*/
|
||||
public class CustomScatterShapeRenderer implements IShapeRenderer
|
||||
{
|
||||
|
||||
@Override
|
||||
public void renderShape(Canvas c, IScatterDataSet dataSet, ViewPortHandler viewPortHandler,
|
||||
float posX, float posY, Paint renderPaint) {
|
||||
|
||||
final float shapeHalf = dataSet.getScatterShapeSize() / 2f;
|
||||
|
||||
c.drawLine(
|
||||
posX - shapeHalf,
|
||||
posY - shapeHalf,
|
||||
posX + shapeHalf,
|
||||
posY + shapeHalf,
|
||||
renderPaint);
|
||||
}
|
||||
}
|
||||
+138
@@ -0,0 +1,138 @@
|
||||
package com.android.stockapp.ui.mpchartexample.custom;
|
||||
|
||||
import com.github.mikephil.charting.charts.BarLineChartBase;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
|
||||
/**
|
||||
* Created by philipp on 02/06/16.
|
||||
*/
|
||||
public class DayAxisValueFormatter extends ValueFormatter
|
||||
{
|
||||
|
||||
private final String[] mMonths = new String[]{
|
||||
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
||||
};
|
||||
|
||||
private final BarLineChartBase<?> chart;
|
||||
|
||||
public DayAxisValueFormatter(BarLineChartBase<?> chart) {
|
||||
this.chart = chart;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormattedValue(float value) {
|
||||
|
||||
int days = (int) value;
|
||||
|
||||
int year = determineYear(days);
|
||||
|
||||
int month = determineMonth(days);
|
||||
String monthName = mMonths[month % mMonths.length];
|
||||
String yearName = String.valueOf(year);
|
||||
|
||||
if (chart.getVisibleXRange() > 30 * 6) {
|
||||
|
||||
return monthName + " " + yearName;
|
||||
} else {
|
||||
|
||||
int dayOfMonth = determineDayOfMonth(days, month + 12 * (year - 2016));
|
||||
|
||||
String appendix = "th";
|
||||
|
||||
switch (dayOfMonth) {
|
||||
case 1:
|
||||
appendix = "st";
|
||||
break;
|
||||
case 2:
|
||||
appendix = "nd";
|
||||
break;
|
||||
case 3:
|
||||
appendix = "rd";
|
||||
break;
|
||||
case 21:
|
||||
appendix = "st";
|
||||
break;
|
||||
case 22:
|
||||
appendix = "nd";
|
||||
break;
|
||||
case 23:
|
||||
appendix = "rd";
|
||||
break;
|
||||
case 31:
|
||||
appendix = "st";
|
||||
break;
|
||||
}
|
||||
|
||||
return dayOfMonth == 0 ? "" : dayOfMonth + appendix + " " + monthName;
|
||||
}
|
||||
}
|
||||
|
||||
private int getDaysForMonth(int month, int year) {
|
||||
|
||||
// month is 0-based
|
||||
|
||||
if (month == 1) {
|
||||
boolean is29Feb = false;
|
||||
|
||||
if (year < 1582)
|
||||
is29Feb = (year < 1 ? year + 1 : year) % 4 == 0;
|
||||
else if (year > 1582)
|
||||
is29Feb = year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
|
||||
|
||||
return is29Feb ? 29 : 28;
|
||||
}
|
||||
|
||||
if (month == 3 || month == 5 || month == 8 || month == 10)
|
||||
return 30;
|
||||
else
|
||||
return 31;
|
||||
}
|
||||
|
||||
private int determineMonth(int dayOfYear) {
|
||||
|
||||
int month = -1;
|
||||
int days = 0;
|
||||
|
||||
while (days < dayOfYear) {
|
||||
month = month + 1;
|
||||
|
||||
if (month >= 12)
|
||||
month = 0;
|
||||
|
||||
int year = determineYear(days);
|
||||
days += getDaysForMonth(month, year);
|
||||
}
|
||||
|
||||
return Math.max(month, 0);
|
||||
}
|
||||
|
||||
private int determineDayOfMonth(int days, int month) {
|
||||
|
||||
int count = 0;
|
||||
int daysForMonths = 0;
|
||||
|
||||
while (count < month) {
|
||||
|
||||
int year = determineYear(daysForMonths);
|
||||
daysForMonths += getDaysForMonth(count % 12, year);
|
||||
count++;
|
||||
}
|
||||
|
||||
return days - daysForMonths;
|
||||
}
|
||||
|
||||
private int determineYear(int days) {
|
||||
|
||||
if (days <= 366)
|
||||
return 2016;
|
||||
else if (days <= 730)
|
||||
return 2017;
|
||||
else if (days <= 1094)
|
||||
return 2018;
|
||||
else if (days <= 1458)
|
||||
return 2019;
|
||||
else
|
||||
return 2020;
|
||||
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
package com.android.stockapp.ui.mpchartexample.custom;
|
||||
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
import com.github.mikephil.charting.utils.ViewPortHandler;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
/**
|
||||
* Created by Philipp Jahoda on 14/09/15.
|
||||
*
|
||||
* @deprecated The {@link MyAxisValueFormatter} does exactly the same thing and is more functional.
|
||||
*/
|
||||
@Deprecated
|
||||
public class MyCustomXAxisValueFormatter extends ValueFormatter
|
||||
{
|
||||
|
||||
private final DecimalFormat mFormat;
|
||||
private final ViewPortHandler mViewPortHandler;
|
||||
|
||||
public MyCustomXAxisValueFormatter(ViewPortHandler viewPortHandler) {
|
||||
mViewPortHandler = viewPortHandler;
|
||||
// maybe do something here or provide parameters in constructor
|
||||
mFormat = new DecimalFormat("###,###,###,##0.0");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormattedValue(float value) {
|
||||
|
||||
//Log.i("TRANS", "x: " + viewPortHandler.getTransX() + ", y: " + viewPortHandler.getTransY());
|
||||
|
||||
// e.g. adjust the x-axis values depending on scale / zoom level
|
||||
final float xScale = mViewPortHandler.getScaleX();
|
||||
if (xScale > 5)
|
||||
return "4";
|
||||
else if (xScale > 3)
|
||||
return "3";
|
||||
else if (xScale > 1)
|
||||
return "2";
|
||||
else
|
||||
return mFormat.format(value);
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package com.android.stockapp.ui.mpchartexample.custom;
|
||||
|
||||
import com.github.mikephil.charting.formatter.IFillFormatter;
|
||||
import com.github.mikephil.charting.interfaces.dataprovider.LineDataProvider;
|
||||
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
|
||||
|
||||
/**
|
||||
* Created by Philipp Jahoda on 12/09/15.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class MyFillFormatter implements IFillFormatter
|
||||
{
|
||||
|
||||
private float fillPos;
|
||||
|
||||
public MyFillFormatter(float fillPos) {
|
||||
this.fillPos = fillPos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFillLinePosition(ILineDataSet dataSet, LineDataProvider dataProvider) {
|
||||
// your logic could be here
|
||||
return fillPos;
|
||||
}
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
|
||||
package com.android.stockapp.ui.mpchartexample.custom;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.github.mikephil.charting.components.MarkerView;
|
||||
import com.github.mikephil.charting.data.CandleEntry;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.utils.MPPointF;
|
||||
import com.github.mikephil.charting.utils.Utils;
|
||||
|
||||
/**
|
||||
* Custom implementation of the MarkerView.
|
||||
*
|
||||
* @author Philipp Jahoda
|
||||
*/
|
||||
@SuppressLint("ViewConstructor")
|
||||
public class MyMarkerView extends MarkerView {
|
||||
|
||||
private final TextView tvContent;
|
||||
|
||||
public MyMarkerView(Context context, int layoutResource) {
|
||||
super(context, layoutResource);
|
||||
|
||||
tvContent = findViewById(R.id.tvContent);
|
||||
}
|
||||
|
||||
// runs every time the MarkerView is redrawn, can be used to update the
|
||||
// content (user-interface)
|
||||
@Override
|
||||
public void refreshContent(Entry e, Highlight highlight) {
|
||||
|
||||
if (e instanceof CandleEntry) {
|
||||
|
||||
CandleEntry ce = (CandleEntry) e;
|
||||
|
||||
tvContent.setText(Utils.formatNumber(ce.getHigh(), 0, true));
|
||||
} else {
|
||||
|
||||
tvContent.setText(Utils.formatNumber(e.getY(), 0, true));
|
||||
}
|
||||
|
||||
super.refreshContent(e, highlight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MPPointF getOffset() {
|
||||
return new MPPointF(-(getWidth() / 2), -getHeight());
|
||||
}
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package com.android.stockapp.ui.mpchartexample.custom;
|
||||
|
||||
import com.github.mikephil.charting.components.AxisBase;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
public class MyValueFormatter extends ValueFormatter
|
||||
{
|
||||
|
||||
private final DecimalFormat mFormat;
|
||||
private String suffix;
|
||||
|
||||
public MyValueFormatter(String suffix) {
|
||||
mFormat = new DecimalFormat("###,###,###,##0.0");
|
||||
this.suffix = suffix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormattedValue(float value) {
|
||||
return mFormat.format(value) + suffix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAxisLabel(float value, AxisBase axis) {
|
||||
if (axis instanceof XAxis) {
|
||||
return mFormat.format(value);
|
||||
} else if (value > 0) {
|
||||
return mFormat.format(value) + suffix;
|
||||
} else {
|
||||
return mFormat.format(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
|
||||
package com.android.stockapp.ui.mpchartexample.custom;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.Typeface;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.github.mikephil.charting.components.MarkerView;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.utils.MPPointF;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
/**
|
||||
* Custom implementation of the MarkerView.
|
||||
*
|
||||
* @author Philipp Jahoda
|
||||
*/
|
||||
@SuppressLint("ViewConstructor")
|
||||
public class RadarMarkerView extends MarkerView {
|
||||
|
||||
private final TextView tvContent;
|
||||
private final DecimalFormat format = new DecimalFormat("##0");
|
||||
|
||||
public RadarMarkerView(Context context, int layoutResource) {
|
||||
super(context, layoutResource);
|
||||
|
||||
tvContent = findViewById(R.id.tvContent);
|
||||
tvContent.setTypeface(Typeface.createFromAsset(context.getAssets(), "OpenSans-Light.ttf"));
|
||||
}
|
||||
|
||||
// runs every time the MarkerView is redrawn, can be used to update the
|
||||
// content (user-interface)
|
||||
@Override
|
||||
public void refreshContent(Entry e, Highlight highlight) {
|
||||
tvContent.setText(String.format("%s %%", format.format(e.getY())));
|
||||
|
||||
super.refreshContent(e, highlight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MPPointF getOffset() {
|
||||
return new MPPointF(-(getWidth() / 2), -getHeight() - 10);
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
|
||||
package com.android.stockapp.ui.mpchartexample.custom;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.github.mikephil.charting.components.MarkerView;
|
||||
import com.github.mikephil.charting.data.BarEntry;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.utils.MPPointF;
|
||||
import com.github.mikephil.charting.utils.Utils;
|
||||
|
||||
/**
|
||||
* Custom implementation of the MarkerView.
|
||||
*
|
||||
* @author Philipp Jahoda
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
@SuppressLint("ViewConstructor")
|
||||
public class StackedBarsMarkerView extends MarkerView {
|
||||
|
||||
private TextView tvContent;
|
||||
|
||||
public StackedBarsMarkerView(Context context, int layoutResource) {
|
||||
super(context, layoutResource);
|
||||
|
||||
tvContent = findViewById(R.id.tvContent);
|
||||
}
|
||||
|
||||
// runs every time the MarkerView is redrawn, can be used to update the
|
||||
// content (user-interface)
|
||||
@Override
|
||||
public void refreshContent(Entry e, Highlight highlight) {
|
||||
|
||||
if (e instanceof BarEntry) {
|
||||
|
||||
BarEntry be = (BarEntry) e;
|
||||
|
||||
if(be.getYVals() != null) {
|
||||
|
||||
// draw the stack value
|
||||
tvContent.setText(Utils.formatNumber(be.getYVals()[highlight.getStackIndex()], 0, true));
|
||||
} else {
|
||||
tvContent.setText(Utils.formatNumber(be.getY(), 0, true));
|
||||
}
|
||||
} else {
|
||||
|
||||
tvContent.setText(Utils.formatNumber(e.getY(), 0, true));
|
||||
}
|
||||
|
||||
super.refreshContent(e, highlight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MPPointF getOffset() {
|
||||
return new MPPointF(-(getWidth() / 2), -getHeight());
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
package com.android.stockapp.ui.mpchartexample.custom;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.github.mikephil.charting.components.MarkerView;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.utils.MPPointF;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
/**
|
||||
* Custom implementation of the MarkerView.
|
||||
*
|
||||
* @author Philipp Jahoda
|
||||
*/
|
||||
@SuppressLint("ViewConstructor")
|
||||
public class XYMarkerView extends MarkerView {
|
||||
|
||||
private final TextView tvContent;
|
||||
private final ValueFormatter xAxisValueFormatter;
|
||||
|
||||
private final DecimalFormat format;
|
||||
|
||||
public XYMarkerView(Context context, ValueFormatter xAxisValueFormatter) {
|
||||
super(context, R.layout.custom_marker_view);
|
||||
|
||||
this.xAxisValueFormatter = xAxisValueFormatter;
|
||||
tvContent = findViewById(R.id.tvContent);
|
||||
format = new DecimalFormat("###.0");
|
||||
}
|
||||
|
||||
// runs every time the MarkerView is redrawn, can be used to update the
|
||||
// content (user-interface)
|
||||
@Override
|
||||
public void refreshContent(Entry e, Highlight highlight) {
|
||||
|
||||
tvContent.setText(String.format("x: %s, y: %s", xAxisValueFormatter.getFormattedValue(e.getX()), format.format(e.getY())));
|
||||
|
||||
super.refreshContent(e, highlight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MPPointF getOffset() {
|
||||
return new MPPointF(-(getWidth() / 2), -getHeight());
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package com.android.stockapp.ui.mpchartexample.custom;
|
||||
|
||||
import com.github.mikephil.charting.components.AxisBase;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
|
||||
/**
|
||||
* Created by Philipp Jahoda on 14/09/15.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class YearXAxisFormatter extends ValueFormatter
|
||||
{
|
||||
|
||||
private final String[] mMonths = new String[]{
|
||||
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec"
|
||||
};
|
||||
|
||||
public YearXAxisFormatter() {
|
||||
// take parameters to change behavior of formatter
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAxisLabel(float value, AxisBase axis) {
|
||||
|
||||
float percent = value / axis.mAxisRange;
|
||||
return mMonths[(int) (mMonths.length * percent)];
|
||||
}
|
||||
}
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
package com.android.stockapp.ui.mpchartexample.fragments;
|
||||
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.ui.mpchartexample.custom.MyMarkerView;
|
||||
import com.github.mikephil.charting.charts.BarChart;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
import com.github.mikephil.charting.listener.ChartTouchListener;
|
||||
import com.github.mikephil.charting.listener.OnChartGestureListener;
|
||||
|
||||
|
||||
public class BarChartFrag extends SimpleFragment implements OnChartGestureListener {
|
||||
|
||||
@NonNull
|
||||
public static Fragment newInstance() {
|
||||
return new BarChartFrag();
|
||||
}
|
||||
|
||||
private BarChart chart;
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View v = inflater.inflate(R.layout.frag_simple_bar, container, false);
|
||||
|
||||
// create a new chart object
|
||||
chart = new BarChart(getActivity());
|
||||
chart.getDescription().setEnabled(false);
|
||||
chart.setOnChartGestureListener(this);
|
||||
|
||||
MyMarkerView mv = new MyMarkerView(getActivity(), R.layout.custom_marker_view);
|
||||
mv.setChartView(chart); // For bounds control
|
||||
chart.setMarker(mv);
|
||||
|
||||
chart.setDrawGridBackground(false);
|
||||
chart.setDrawBarShadow(false);
|
||||
|
||||
Typeface tf = Typeface.createFromAsset(context.getAssets(), "OpenSans-Light.ttf");
|
||||
|
||||
chart.setData(generateBarData(1, 20000, 12));
|
||||
|
||||
Legend l = chart.getLegend();
|
||||
l.setTypeface(tf);
|
||||
|
||||
YAxis leftAxis = chart.getAxisLeft();
|
||||
leftAxis.setTypeface(tf);
|
||||
leftAxis.setAxisMinimum(0f); // this replaces setStartAtZero(true)
|
||||
|
||||
chart.getAxisRight().setEnabled(false);
|
||||
|
||||
XAxis xAxis = chart.getXAxis();
|
||||
xAxis.setEnabled(false);
|
||||
|
||||
// programmatically add the chart
|
||||
FrameLayout parent = v.findViewById(R.id.parentLayout);
|
||||
parent.addView(chart);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChartGestureStart(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {
|
||||
Log.i("Gesture", "START");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChartGestureEnd(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {
|
||||
Log.i("Gesture", "END");
|
||||
chart.highlightValues(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChartLongPressed(MotionEvent me) {
|
||||
Log.i("LongPress", "Chart long pressed.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChartDoubleTapped(MotionEvent me) {
|
||||
Log.i("DoubleTap", "Chart double-tapped.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChartSingleTapped(MotionEvent me) {
|
||||
Log.i("SingleTap", "Chart single-tapped.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChartFling(MotionEvent me1, MotionEvent me2, float velocityX, float velocityY) {
|
||||
Log.i("Fling", "Chart fling. VelocityX: " + velocityX + ", VelocityY: " + velocityY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChartScale(MotionEvent me, float scaleX, float scaleY) {
|
||||
Log.i("Scale / Zoom", "ScaleX: " + scaleX + ", ScaleY: " + scaleY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChartTranslate(MotionEvent me, float dX, float dY) {
|
||||
Log.i("Translate / Move", "dX: " + dX + ", dY: " + dY);
|
||||
}
|
||||
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package com.android.stockapp.ui.mpchartexample.fragments;
|
||||
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.github.mikephil.charting.charts.LineChart;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
|
||||
|
||||
public class ComplexityFragment extends SimpleFragment {
|
||||
|
||||
@NonNull
|
||||
public static Fragment newInstance() {
|
||||
return new ComplexityFragment();
|
||||
}
|
||||
|
||||
@SuppressWarnings("FieldCanBeLocal")
|
||||
private LineChart chart;
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View v = inflater.inflate(R.layout.frag_simple_line, container, false);
|
||||
|
||||
chart = v.findViewById(R.id.lineChart1);
|
||||
|
||||
chart.getDescription().setEnabled(false);
|
||||
|
||||
chart.setDrawGridBackground(false);
|
||||
|
||||
chart.setData(getComplexity());
|
||||
chart.animateX(3000);
|
||||
|
||||
Typeface tf = Typeface.createFromAsset(context.getAssets(), "OpenSans-Light.ttf");
|
||||
|
||||
Legend l = chart.getLegend();
|
||||
l.setTypeface(tf);
|
||||
|
||||
YAxis leftAxis = chart.getAxisLeft();
|
||||
leftAxis.setTypeface(tf);
|
||||
|
||||
chart.getAxisRight().setEnabled(false);
|
||||
|
||||
XAxis xAxis = chart.getXAxis();
|
||||
xAxis.setEnabled(false);
|
||||
|
||||
return v;
|
||||
}
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
package com.android.stockapp.ui.mpchartexample.fragments;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
import android.text.SpannableString;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.text.style.RelativeSizeSpan;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.github.mikephil.charting.charts.PieChart;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
|
||||
|
||||
public class PieChartFrag extends SimpleFragment {
|
||||
|
||||
@NonNull
|
||||
public static Fragment newInstance() {
|
||||
return new PieChartFrag();
|
||||
}
|
||||
|
||||
@SuppressWarnings("FieldCanBeLocal")
|
||||
private PieChart chart;
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View v = inflater.inflate(R.layout.frag_simple_pie, container, false);
|
||||
|
||||
chart = v.findViewById(R.id.pieChart1);
|
||||
chart.getDescription().setEnabled(false);
|
||||
|
||||
Typeface tf = Typeface.createFromAsset(context.getAssets(), "OpenSans-Light.ttf");
|
||||
|
||||
chart.setCenterTextTypeface(tf);
|
||||
chart.setCenterText(generateCenterText());
|
||||
chart.setCenterTextSize(10f);
|
||||
chart.setCenterTextTypeface(tf);
|
||||
|
||||
// radius of the center hole in percent of maximum radius
|
||||
chart.setHoleRadius(45f);
|
||||
chart.setTransparentCircleRadius(50f);
|
||||
|
||||
Legend l = chart.getLegend();
|
||||
l.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
|
||||
l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT);
|
||||
l.setOrientation(Legend.LegendOrientation.VERTICAL);
|
||||
l.setDrawInside(false);
|
||||
|
||||
chart.setData(generatePieData());
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
private SpannableString generateCenterText() {
|
||||
SpannableString s = new SpannableString("Revenues\nQuarters 2015");
|
||||
s.setSpan(new RelativeSizeSpan(2f), 0, 8, 0);
|
||||
s.setSpan(new ForegroundColorSpan(Color.GRAY), 8, s.length(), 0);
|
||||
return s;
|
||||
}
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
package com.android.stockapp.ui.mpchartexample.fragments;
|
||||
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.ui.mpchartexample.custom.MyMarkerView;
|
||||
import com.github.mikephil.charting.charts.ScatterChart;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.XAxis.XAxisPosition;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
|
||||
|
||||
public class ScatterChartFrag extends SimpleFragment {
|
||||
|
||||
@NonNull
|
||||
public static Fragment newInstance() {
|
||||
return new ScatterChartFrag();
|
||||
}
|
||||
|
||||
@SuppressWarnings("FieldCanBeLocal")
|
||||
private ScatterChart chart;
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View v = inflater.inflate(R.layout.frag_simple_scatter, container, false);
|
||||
|
||||
chart = v.findViewById(R.id.scatterChart1);
|
||||
chart.getDescription().setEnabled(false);
|
||||
|
||||
Typeface tf = Typeface.createFromAsset(context.getAssets(), "OpenSans-Light.ttf");
|
||||
|
||||
MyMarkerView mv = new MyMarkerView(getActivity(), R.layout.custom_marker_view);
|
||||
mv.setChartView(chart); // For bounds control
|
||||
chart.setMarker(mv);
|
||||
|
||||
chart.setDrawGridBackground(false);
|
||||
chart.setData(generateScatterData(6, 10000, 200));
|
||||
|
||||
XAxis xAxis = chart.getXAxis();
|
||||
xAxis.setEnabled(true);
|
||||
xAxis.setPosition(XAxisPosition.BOTTOM);
|
||||
|
||||
YAxis leftAxis = chart.getAxisLeft();
|
||||
leftAxis.setTypeface(tf);
|
||||
|
||||
YAxis rightAxis = chart.getAxisRight();
|
||||
rightAxis.setTypeface(tf);
|
||||
rightAxis.setDrawGridLines(false);
|
||||
|
||||
Legend l = chart.getLegend();
|
||||
l.setWordWrapEnabled(true);
|
||||
l.setTypeface(tf);
|
||||
l.setFormSize(14f);
|
||||
l.setTextSize(9f);
|
||||
|
||||
// increase the space between legend & bottom and legend & content
|
||||
l.setYOffset(13f);
|
||||
chart.setExtraBottomOffset(16f);
|
||||
|
||||
return v;
|
||||
}
|
||||
}
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
|
||||
package com.android.stockapp.ui.mpchartexample.fragments;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.DialogInterface.OnClickListener;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentPagerAdapter;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.ui.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
|
||||
/**
|
||||
* Demonstrates how to keep your charts straight forward, simple and beautiful with the MPAndroidChart library.
|
||||
*
|
||||
* @author Philipp Jahoda
|
||||
*/
|
||||
public class SimpleChartDemo extends DemoBase {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_awesomedesign);
|
||||
|
||||
setTitle("SimpleChartDemo");
|
||||
|
||||
ViewPager pager = findViewById(R.id.pager);
|
||||
pager.setOffscreenPageLimit(3);
|
||||
|
||||
PageAdapter a = new PageAdapter(getSupportFragmentManager());
|
||||
pager.setAdapter(a);
|
||||
|
||||
|
||||
AlertDialog.Builder b = new AlertDialog.Builder(this);
|
||||
b.setTitle("This is a ViewPager.");
|
||||
b.setMessage("Swipe left and right for more awesome design examples!");
|
||||
b.setPositiveButton("OK", new OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
b.show();
|
||||
}
|
||||
|
||||
private class PageAdapter extends FragmentPagerAdapter {
|
||||
|
||||
PageAdapter(FragmentManager fm) {
|
||||
super(fm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fragment getItem(int pos) {
|
||||
Fragment f = null;
|
||||
|
||||
switch(pos) {
|
||||
case 0:
|
||||
f = SineCosineFragment.newInstance();
|
||||
break;
|
||||
case 1:
|
||||
f = ComplexityFragment.newInstance();
|
||||
break;
|
||||
case 2:
|
||||
f = BarChartFrag.newInstance();
|
||||
break;
|
||||
case 3:
|
||||
f = ScatterChartFrag.newInstance();
|
||||
break;
|
||||
case 4:
|
||||
f = PieChartFrag.newInstance();
|
||||
break;
|
||||
}
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.only_github, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.viewGithub: {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/fragments/SimpleChartDemo.java"));
|
||||
startActivity(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveToGallery() { /* Intentionally left empty */ }
|
||||
}
|
||||
+200
@@ -0,0 +1,200 @@
|
||||
package com.android.stockapp.ui.mpchartexample.fragments;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.github.mikephil.charting.charts.ScatterChart;
|
||||
import com.github.mikephil.charting.data.BarData;
|
||||
import com.github.mikephil.charting.data.BarDataSet;
|
||||
import com.github.mikephil.charting.data.BarEntry;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.data.LineData;
|
||||
import com.github.mikephil.charting.data.LineDataSet;
|
||||
import com.github.mikephil.charting.data.PieData;
|
||||
import com.github.mikephil.charting.data.PieDataSet;
|
||||
import com.github.mikephil.charting.data.PieEntry;
|
||||
import com.github.mikephil.charting.data.ScatterData;
|
||||
import com.github.mikephil.charting.data.ScatterDataSet;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IBarDataSet;
|
||||
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IScatterDataSet;
|
||||
import com.github.mikephil.charting.utils.ColorTemplate;
|
||||
import com.github.mikephil.charting.utils.FileUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@SuppressWarnings({"SameParameterValue", "WeakerAccess"})
|
||||
public abstract class SimpleFragment extends Fragment {
|
||||
|
||||
private Typeface tf;
|
||||
protected Context context;
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public SimpleFragment() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
tf = Typeface.createFromAsset(context.getAssets(), "OpenSans-Regular.ttf");
|
||||
return super.onCreateView(inflater, container, savedInstanceState);
|
||||
}
|
||||
|
||||
protected BarData generateBarData(int dataSets, float range, int count) {
|
||||
|
||||
ArrayList<IBarDataSet> sets = new ArrayList<>();
|
||||
|
||||
for(int i = 0; i < dataSets; i++) {
|
||||
|
||||
ArrayList<BarEntry> entries = new ArrayList<>();
|
||||
|
||||
for(int j = 0; j < count; j++) {
|
||||
entries.add(new BarEntry(j, (float) (Math.random() * range) + range / 4));
|
||||
}
|
||||
|
||||
BarDataSet ds = new BarDataSet(entries, getLabel(i));
|
||||
ds.setColors(ColorTemplate.VORDIPLOM_COLORS);
|
||||
sets.add(ds);
|
||||
}
|
||||
|
||||
BarData d = new BarData(sets);
|
||||
d.setValueTypeface(tf);
|
||||
return d;
|
||||
}
|
||||
|
||||
protected ScatterData generateScatterData(int dataSets, float range, int count) {
|
||||
|
||||
ArrayList<IScatterDataSet> sets = new ArrayList<>();
|
||||
|
||||
ScatterChart.ScatterShape[] shapes = ScatterChart.ScatterShape.getAllDefaultShapes();
|
||||
|
||||
for(int i = 0; i < dataSets; i++) {
|
||||
|
||||
ArrayList<Entry> entries = new ArrayList<>();
|
||||
|
||||
for(int j = 0; j < count; j++) {
|
||||
entries.add(new Entry(j, (float) (Math.random() * range) + range / 4));
|
||||
}
|
||||
|
||||
ScatterDataSet ds = new ScatterDataSet(entries, getLabel(i));
|
||||
ds.setScatterShapeSize(12f);
|
||||
ds.setScatterShape(shapes[i % shapes.length]);
|
||||
ds.setColors(ColorTemplate.COLORFUL_COLORS);
|
||||
ds.setScatterShapeSize(9f);
|
||||
sets.add(ds);
|
||||
}
|
||||
|
||||
ScatterData d = new ScatterData(sets);
|
||||
d.setValueTypeface(tf);
|
||||
return d;
|
||||
}
|
||||
|
||||
/**
|
||||
* generates less data (1 DataSet, 4 values)
|
||||
* @return PieData
|
||||
*/
|
||||
protected PieData generatePieData() {
|
||||
|
||||
int count = 4;
|
||||
|
||||
ArrayList<PieEntry> entries1 = new ArrayList<>();
|
||||
|
||||
for(int i = 0; i < count; i++) {
|
||||
entries1.add(new PieEntry((float) ((Math.random() * 60) + 40), "Quarter " + (i+1)));
|
||||
}
|
||||
|
||||
PieDataSet ds1 = new PieDataSet(entries1, "Quarterly Revenues 2015");
|
||||
ds1.setColors(ColorTemplate.VORDIPLOM_COLORS);
|
||||
ds1.setSliceSpace(2f);
|
||||
ds1.setValueTextColor(Color.WHITE);
|
||||
ds1.setValueTextSize(12f);
|
||||
|
||||
PieData d = new PieData(ds1);
|
||||
d.setValueTypeface(tf);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
protected LineData generateLineData() {
|
||||
|
||||
ArrayList<ILineDataSet> sets = new ArrayList<>();
|
||||
LineDataSet ds1 = new LineDataSet(FileUtils.loadEntriesFromAssets(context.getAssets(), "sine.txt"), "Sine function");
|
||||
LineDataSet ds2 = new LineDataSet(FileUtils.loadEntriesFromAssets(context.getAssets(), "cosine.txt"), "Cosine function");
|
||||
|
||||
ds1.setLineWidth(2f);
|
||||
ds2.setLineWidth(2f);
|
||||
|
||||
ds1.setDrawCircles(false);
|
||||
ds2.setDrawCircles(false);
|
||||
|
||||
ds1.setColor(ColorTemplate.VORDIPLOM_COLORS[0]);
|
||||
ds2.setColor(ColorTemplate.VORDIPLOM_COLORS[1]);
|
||||
|
||||
// load DataSets from files in assets folder
|
||||
sets.add(ds1);
|
||||
sets.add(ds2);
|
||||
|
||||
LineData d = new LineData(sets);
|
||||
d.setValueTypeface(tf);
|
||||
return d;
|
||||
}
|
||||
|
||||
protected LineData getComplexity() {
|
||||
|
||||
ArrayList<ILineDataSet> sets = new ArrayList<>();
|
||||
|
||||
LineDataSet ds1 = new LineDataSet(FileUtils.loadEntriesFromAssets(context.getAssets(), "n.txt"), "O(n)");
|
||||
LineDataSet ds2 = new LineDataSet(FileUtils.loadEntriesFromAssets(context.getAssets(), "nlogn.txt"), "O(nlogn)");
|
||||
LineDataSet ds3 = new LineDataSet(FileUtils.loadEntriesFromAssets(context.getAssets(), "square.txt"), "O(n\u00B2)");
|
||||
LineDataSet ds4 = new LineDataSet(FileUtils.loadEntriesFromAssets(context.getAssets(), "three.txt"), "O(n\u00B3)");
|
||||
|
||||
ds1.setColor(ColorTemplate.VORDIPLOM_COLORS[0]);
|
||||
ds2.setColor(ColorTemplate.VORDIPLOM_COLORS[1]);
|
||||
ds3.setColor(ColorTemplate.VORDIPLOM_COLORS[2]);
|
||||
ds4.setColor(ColorTemplate.VORDIPLOM_COLORS[3]);
|
||||
|
||||
ds1.setCircleColor(ColorTemplate.VORDIPLOM_COLORS[0]);
|
||||
ds2.setCircleColor(ColorTemplate.VORDIPLOM_COLORS[1]);
|
||||
ds3.setCircleColor(ColorTemplate.VORDIPLOM_COLORS[2]);
|
||||
ds4.setCircleColor(ColorTemplate.VORDIPLOM_COLORS[3]);
|
||||
|
||||
ds1.setLineWidth(2.5f);
|
||||
ds1.setCircleRadius(3f);
|
||||
ds2.setLineWidth(2.5f);
|
||||
ds2.setCircleRadius(3f);
|
||||
ds3.setLineWidth(2.5f);
|
||||
ds3.setCircleRadius(3f);
|
||||
ds4.setLineWidth(2.5f);
|
||||
ds4.setCircleRadius(3f);
|
||||
|
||||
|
||||
// load DataSets from files in assets folder
|
||||
sets.add(ds1);
|
||||
sets.add(ds2);
|
||||
sets.add(ds3);
|
||||
sets.add(ds4);
|
||||
|
||||
LineData d = new LineData(sets);
|
||||
d.setValueTypeface(tf);
|
||||
return d;
|
||||
}
|
||||
|
||||
private final String[] mLabels = new String[] { "Company A", "Company B", "Company C", "Company D", "Company E", "Company F" };
|
||||
|
||||
private String getLabel(int i) {
|
||||
return mLabels[i];
|
||||
}
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
package com.android.stockapp.ui.mpchartexample.fragments;
|
||||
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.github.mikephil.charting.charts.LineChart;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
|
||||
|
||||
public class SineCosineFragment extends SimpleFragment {
|
||||
|
||||
@NonNull
|
||||
public static Fragment newInstance() {
|
||||
return new SineCosineFragment();
|
||||
}
|
||||
|
||||
@SuppressWarnings("FieldCanBeLocal")
|
||||
private LineChart chart;
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View v = inflater.inflate(R.layout.frag_simple_line, container, false);
|
||||
|
||||
chart = v.findViewById(R.id.lineChart1);
|
||||
|
||||
chart.getDescription().setEnabled(false);
|
||||
|
||||
chart.setDrawGridBackground(false);
|
||||
|
||||
chart.setData(generateLineData());
|
||||
chart.animateX(3000);
|
||||
|
||||
Typeface tf = Typeface.createFromAsset(context.getAssets(), "OpenSans-Light.ttf");
|
||||
|
||||
Legend l = chart.getLegend();
|
||||
l.setTypeface(tf);
|
||||
|
||||
YAxis leftAxis = chart.getAxisLeft();
|
||||
leftAxis.setTypeface(tf);
|
||||
leftAxis.setAxisMaximum(1.2f);
|
||||
leftAxis.setAxisMinimum(-1.2f);
|
||||
|
||||
chart.getAxisRight().setEnabled(false);
|
||||
|
||||
XAxis xAxis = chart.getXAxis();
|
||||
xAxis.setEnabled(false);
|
||||
|
||||
return v;
|
||||
}
|
||||
}
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
package com.android.stockapp.ui.mpchartexample.listviewitems;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.Typeface;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.github.mikephil.charting.charts.BarChart;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.XAxis.XAxisPosition;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
import com.github.mikephil.charting.data.BarData;
|
||||
import com.github.mikephil.charting.data.ChartData;
|
||||
|
||||
public class BarChartItem extends ChartItem {
|
||||
|
||||
private final Typeface mTf;
|
||||
|
||||
public BarChartItem(ChartData<?> cd, Context c) {
|
||||
super(cd);
|
||||
|
||||
mTf = Typeface.createFromAsset(c.getAssets(), "OpenSans-Regular.ttf");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemType() {
|
||||
return TYPE_BARCHART;
|
||||
}
|
||||
|
||||
@SuppressLint("InflateParams")
|
||||
@Override
|
||||
public View getView(int position, View convertView, Context c) {
|
||||
|
||||
ViewHolder holder;
|
||||
|
||||
if (convertView == null) {
|
||||
|
||||
holder = new ViewHolder();
|
||||
|
||||
convertView = LayoutInflater.from(c).inflate(
|
||||
R.layout.list_item_barchart, null);
|
||||
holder.chart = convertView.findViewById(R.id.chart);
|
||||
|
||||
convertView.setTag(holder);
|
||||
|
||||
} else {
|
||||
holder = (ViewHolder) convertView.getTag();
|
||||
}
|
||||
|
||||
// apply styling
|
||||
holder.chart.getDescription().setEnabled(false);
|
||||
holder.chart.setDrawGridBackground(false);
|
||||
holder.chart.setDrawBarShadow(false);
|
||||
|
||||
XAxis xAxis = holder.chart.getXAxis();
|
||||
xAxis.setPosition(XAxisPosition.BOTTOM);
|
||||
xAxis.setTypeface(mTf);
|
||||
xAxis.setDrawGridLines(false);
|
||||
xAxis.setDrawAxisLine(true);
|
||||
|
||||
YAxis leftAxis = holder.chart.getAxisLeft();
|
||||
leftAxis.setTypeface(mTf);
|
||||
leftAxis.setLabelCount(5, false);
|
||||
leftAxis.setSpaceTop(20f);
|
||||
leftAxis.setAxisMinimum(0f); // this replaces setStartAtZero(true)
|
||||
|
||||
YAxis rightAxis = holder.chart.getAxisRight();
|
||||
rightAxis.setTypeface(mTf);
|
||||
rightAxis.setLabelCount(5, false);
|
||||
rightAxis.setSpaceTop(20f);
|
||||
rightAxis.setAxisMinimum(0f); // this replaces setStartAtZero(true)
|
||||
|
||||
mChartData.setValueTypeface(mTf);
|
||||
|
||||
// set data
|
||||
holder.chart.setData((BarData) mChartData);
|
||||
holder.chart.setFitBars(true);
|
||||
|
||||
// do not forget to refresh the chart
|
||||
// holder.chart.invalidate();
|
||||
holder.chart.animateY(700);
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
private static class ViewHolder {
|
||||
BarChart chart;
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package com.android.stockapp.ui.mpchartexample.listviewitems;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
|
||||
import com.github.mikephil.charting.data.ChartData;
|
||||
|
||||
/**
|
||||
* Base class of the Chart ListView items
|
||||
* @author philipp
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public abstract class ChartItem {
|
||||
|
||||
static final int TYPE_BARCHART = 0;
|
||||
static final int TYPE_LINECHART = 1;
|
||||
static final int TYPE_PIECHART = 2;
|
||||
|
||||
ChartData<?> mChartData;
|
||||
|
||||
ChartItem(ChartData<?> cd) {
|
||||
this.mChartData = cd;
|
||||
}
|
||||
|
||||
public abstract int getItemType();
|
||||
|
||||
public abstract View getView(int position, View convertView, Context c);
|
||||
}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
|
||||
package com.android.stockapp.ui.mpchartexample.listviewitems;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.Typeface;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.github.mikephil.charting.charts.LineChart;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.XAxis.XAxisPosition;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
import com.github.mikephil.charting.data.ChartData;
|
||||
import com.github.mikephil.charting.data.LineData;
|
||||
|
||||
public class LineChartItem extends ChartItem {
|
||||
|
||||
private final Typeface mTf;
|
||||
|
||||
public LineChartItem(ChartData<?> cd, Context c) {
|
||||
super(cd);
|
||||
|
||||
mTf = Typeface.createFromAsset(c.getAssets(), "OpenSans-Regular.ttf");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemType() {
|
||||
return TYPE_LINECHART;
|
||||
}
|
||||
|
||||
@SuppressLint("InflateParams")
|
||||
@Override
|
||||
public View getView(int position, View convertView, Context c) {
|
||||
|
||||
ViewHolder holder;
|
||||
|
||||
if (convertView == null) {
|
||||
|
||||
holder = new ViewHolder();
|
||||
|
||||
convertView = LayoutInflater.from(c).inflate(
|
||||
R.layout.list_item_linechart, null);
|
||||
holder.chart = convertView.findViewById(R.id.chart);
|
||||
|
||||
convertView.setTag(holder);
|
||||
|
||||
} else {
|
||||
holder = (ViewHolder) convertView.getTag();
|
||||
}
|
||||
|
||||
// apply styling
|
||||
// holder.chart.setValueTypeface(mTf);
|
||||
holder.chart.getDescription().setEnabled(false);
|
||||
holder.chart.setDrawGridBackground(false);
|
||||
|
||||
XAxis xAxis = holder.chart.getXAxis();
|
||||
xAxis.setPosition(XAxisPosition.BOTTOM);
|
||||
xAxis.setTypeface(mTf);
|
||||
xAxis.setDrawGridLines(false);
|
||||
xAxis.setDrawAxisLine(true);
|
||||
|
||||
YAxis leftAxis = holder.chart.getAxisLeft();
|
||||
leftAxis.setTypeface(mTf);
|
||||
leftAxis.setLabelCount(5, false);
|
||||
leftAxis.setAxisMinimum(0f); // this replaces setStartAtZero(true)
|
||||
|
||||
YAxis rightAxis = holder.chart.getAxisRight();
|
||||
rightAxis.setTypeface(mTf);
|
||||
rightAxis.setLabelCount(5, false);
|
||||
rightAxis.setDrawGridLines(false);
|
||||
rightAxis.setAxisMinimum(0f); // this replaces setStartAtZero(true)
|
||||
|
||||
// set data
|
||||
holder.chart.setData((LineData) mChartData);
|
||||
|
||||
// do not forget to refresh the chart
|
||||
// holder.chart.invalidate();
|
||||
holder.chart.animateX(750);
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
private static class ViewHolder {
|
||||
LineChart chart;
|
||||
}
|
||||
}
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
|
||||
package com.android.stockapp.ui.mpchartexample.listviewitems;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Typeface;
|
||||
import android.text.SpannableString;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.text.style.RelativeSizeSpan;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.github.mikephil.charting.charts.PieChart;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.data.ChartData;
|
||||
import com.github.mikephil.charting.data.PieData;
|
||||
import com.github.mikephil.charting.formatter.PercentFormatter;
|
||||
import com.github.mikephil.charting.utils.ColorTemplate;
|
||||
|
||||
public class PieChartItem extends ChartItem {
|
||||
|
||||
private final Typeface mTf;
|
||||
private final SpannableString mCenterText;
|
||||
|
||||
public PieChartItem(ChartData<?> cd, Context c) {
|
||||
super(cd);
|
||||
|
||||
mTf = Typeface.createFromAsset(c.getAssets(), "OpenSans-Regular.ttf");
|
||||
mCenterText = generateCenterText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemType() {
|
||||
return TYPE_PIECHART;
|
||||
}
|
||||
|
||||
@SuppressLint("InflateParams")
|
||||
@Override
|
||||
public View getView(int position, View convertView, Context c) {
|
||||
|
||||
ViewHolder holder;
|
||||
|
||||
if (convertView == null) {
|
||||
|
||||
holder = new ViewHolder();
|
||||
|
||||
convertView = LayoutInflater.from(c).inflate(
|
||||
R.layout.list_item_piechart, null);
|
||||
holder.chart = convertView.findViewById(R.id.chart);
|
||||
|
||||
convertView.setTag(holder);
|
||||
|
||||
} else {
|
||||
holder = (ViewHolder) convertView.getTag();
|
||||
}
|
||||
|
||||
// apply styling
|
||||
holder.chart.getDescription().setEnabled(false);
|
||||
holder.chart.setHoleRadius(52f);
|
||||
holder.chart.setTransparentCircleRadius(57f);
|
||||
holder.chart.setCenterText(mCenterText);
|
||||
holder.chart.setCenterTextTypeface(mTf);
|
||||
holder.chart.setCenterTextSize(9f);
|
||||
holder.chart.setUsePercentValues(true);
|
||||
holder.chart.setExtraOffsets(5, 10, 50, 10);
|
||||
|
||||
mChartData.setValueFormatter(new PercentFormatter());
|
||||
mChartData.setValueTypeface(mTf);
|
||||
mChartData.setValueTextSize(11f);
|
||||
mChartData.setValueTextColor(Color.WHITE);
|
||||
// set data
|
||||
holder.chart.setData((PieData) mChartData);
|
||||
|
||||
Legend l = holder.chart.getLegend();
|
||||
l.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
|
||||
l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT);
|
||||
l.setOrientation(Legend.LegendOrientation.VERTICAL);
|
||||
l.setDrawInside(false);
|
||||
l.setYEntrySpace(0f);
|
||||
l.setYOffset(0f);
|
||||
|
||||
// do not forget to refresh the chart
|
||||
// holder.chart.invalidate();
|
||||
holder.chart.animateY(900);
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
private SpannableString generateCenterText() {
|
||||
SpannableString s = new SpannableString("MPAndroidChart\ncreated by\nPhilipp Jahoda");
|
||||
s.setSpan(new RelativeSizeSpan(1.6f), 0, 14, 0);
|
||||
s.setSpan(new ForegroundColorSpan(ColorTemplate.VORDIPLOM_COLORS[0]), 0, 14, 0);
|
||||
s.setSpan(new RelativeSizeSpan(.9f), 14, 25, 0);
|
||||
s.setSpan(new ForegroundColorSpan(Color.GRAY), 14, 25, 0);
|
||||
s.setSpan(new RelativeSizeSpan(1.4f), 25, s.length(), 0);
|
||||
s.setSpan(new ForegroundColorSpan(ColorTemplate.getHoloBlue()), 25, s.length(), 0);
|
||||
return s;
|
||||
}
|
||||
|
||||
private static class ViewHolder {
|
||||
PieChart chart;
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package com.android.stockapp.ui.mpchartexample.notimportant;
|
||||
|
||||
/**
|
||||
* Created by Philipp Jahoda on 07/12/15.
|
||||
*/
|
||||
class ContentItem {
|
||||
|
||||
final String name;
|
||||
final String desc;
|
||||
boolean isSection = false;
|
||||
|
||||
ContentItem(String n) {
|
||||
name = n;
|
||||
desc = "";
|
||||
isSection = true;
|
||||
}
|
||||
|
||||
ContentItem(String n, String d) {
|
||||
name = n;
|
||||
desc = d;
|
||||
}
|
||||
}
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
|
||||
package com.android.stockapp.ui.mpchartexample.notimportant;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.github.mikephil.charting.charts.Chart;
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
|
||||
/**
|
||||
* Base class of all Activities of the Demo Application.
|
||||
*
|
||||
* @author Philipp Jahoda
|
||||
*/
|
||||
public abstract class DemoBase extends AppCompatActivity implements ActivityCompat.OnRequestPermissionsResultCallback {
|
||||
|
||||
protected final String[] months = new String[] {
|
||||
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec"
|
||||
};
|
||||
|
||||
protected final String[] parties = new String[] {
|
||||
"Party A", "Party B", "Party C", "Party D", "Party E", "Party F", "Party G", "Party H",
|
||||
"Party I", "Party J", "Party K", "Party L", "Party M", "Party N", "Party O", "Party P",
|
||||
"Party Q", "Party R", "Party S", "Party T", "Party U", "Party V", "Party W", "Party X",
|
||||
"Party Y", "Party Z"
|
||||
};
|
||||
|
||||
private static final int PERMISSION_STORAGE = 0;
|
||||
|
||||
protected Typeface tfRegular;
|
||||
protected Typeface tfLight;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
tfRegular = Typeface.createFromAsset(getAssets(), "OpenSans-Regular.ttf");
|
||||
tfLight = Typeface.createFromAsset(getAssets(), "OpenSans-Light.ttf");
|
||||
}
|
||||
|
||||
protected float getRandom(float range, float start) {
|
||||
return (float) (Math.random() * range) + start;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
super.onBackPressed();
|
||||
overridePendingTransition(R.anim.move_left_in_activity, R.anim.move_right_out_activity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
if (requestCode == PERMISSION_STORAGE) {
|
||||
if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
saveToGallery();
|
||||
} else {
|
||||
Toast.makeText(getApplicationContext(), "Saving FAILED!", Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void requestStoragePermission(View view) {
|
||||
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
|
||||
Snackbar.make(view, "Write permission is required to save image to gallery", Snackbar.LENGTH_INDEFINITE)
|
||||
.setAction(android.R.string.ok, new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
ActivityCompat.requestPermissions(DemoBase.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_STORAGE);
|
||||
}
|
||||
}).show();
|
||||
} else {
|
||||
Toast.makeText(getApplicationContext(), "Permission Required!", Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
ActivityCompat.requestPermissions(DemoBase.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_STORAGE);
|
||||
}
|
||||
}
|
||||
|
||||
protected void saveToGallery(Chart chart, String name) {
|
||||
if (chart.saveToGallery(name + "_" + System.currentTimeMillis(), 70))
|
||||
Toast.makeText(getApplicationContext(), "Saving SUCCESSFUL!",
|
||||
Toast.LENGTH_SHORT).show();
|
||||
else
|
||||
Toast.makeText(getApplicationContext(), "Saving FAILED!", Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
}
|
||||
|
||||
protected abstract void saveToGallery();
|
||||
}
|
||||
+275
@@ -0,0 +1,275 @@
|
||||
|
||||
package com.android.stockapp.ui.mpchartexample.notimportant;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
import android.widget.ListView;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.android.stockapp.R;
|
||||
import com.android.stockapp.ui.mpchartexample.AnotherBarActivity;
|
||||
import com.android.stockapp.ui.mpchartexample.BarChartActivity;
|
||||
import com.android.stockapp.ui.mpchartexample.BarChartActivityMultiDataset;
|
||||
import com.android.stockapp.ui.mpchartexample.BarChartActivitySinus;
|
||||
import com.android.stockapp.ui.mpchartexample.BarChartPositiveNegative;
|
||||
import com.android.stockapp.ui.mpchartexample.BubbleChartActivity;
|
||||
import com.android.stockapp.ui.mpchartexample.CandleStickChartActivity;
|
||||
import com.android.stockapp.ui.mpchartexample.CombinedChartActivity;
|
||||
import com.android.stockapp.ui.mpchartexample.CubicLineChartActivity;
|
||||
import com.android.stockapp.ui.mpchartexample.DynamicalAddingActivity;
|
||||
import com.android.stockapp.ui.mpchartexample.FilledLineActivity;
|
||||
import com.android.stockapp.ui.mpchartexample.HalfPieChartActivity;
|
||||
import com.android.stockapp.ui.mpchartexample.HorizontalBarChartActivity;
|
||||
import com.android.stockapp.ui.mpchartexample.InvertedLineChartActivity;
|
||||
import com.android.stockapp.ui.mpchartexample.LineChartActivity1;
|
||||
import com.android.stockapp.ui.mpchartexample.LineChartActivity2;
|
||||
import com.android.stockapp.ui.mpchartexample.LineChartActivityColored;
|
||||
import com.android.stockapp.ui.mpchartexample.LineChartTime;
|
||||
import com.android.stockapp.ui.mpchartexample.ListViewBarChartActivity;
|
||||
import com.android.stockapp.ui.mpchartexample.ListViewMultiChartActivity;
|
||||
import com.android.stockapp.ui.mpchartexample.MultiLineChartActivity;
|
||||
import com.android.stockapp.ui.mpchartexample.PerformanceLineChart;
|
||||
import com.android.stockapp.ui.mpchartexample.PieChartActivity;
|
||||
import com.android.stockapp.ui.mpchartexample.PiePolylineChartActivity;
|
||||
import com.android.stockapp.ui.mpchartexample.RadarChartActivity;
|
||||
import com.android.stockapp.ui.mpchartexample.RealtimeLineChartActivity;
|
||||
import com.android.stockapp.ui.mpchartexample.ScatterChartActivity;
|
||||
import com.android.stockapp.ui.mpchartexample.ScrollViewActivity;
|
||||
import com.android.stockapp.ui.mpchartexample.StackedBarActivity;
|
||||
import com.android.stockapp.ui.mpchartexample.StackedBarActivityNegative;
|
||||
import com.android.stockapp.ui.mpchartexample.fragments.SimpleChartDemo;
|
||||
import com.github.mikephil.charting.utils.Utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class MPMainActivity extends AppCompatActivity implements OnItemClickListener {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_mpmain);
|
||||
|
||||
setTitle("MPAndroidChart Example");
|
||||
|
||||
// initialize the utilities
|
||||
Utils.init(this);
|
||||
|
||||
ArrayList<ContentItem> objects = new ArrayList<>();
|
||||
|
||||
////
|
||||
objects.add(0, new ContentItem("Line Charts"));
|
||||
|
||||
objects.add(1, new ContentItem("Basic", "Simple line chart."));
|
||||
objects.add(2, new ContentItem("Multiple", "Show multiple data sets."));
|
||||
objects.add(3, new ContentItem("Dual Axis", "Line chart with dual y-axes."));
|
||||
objects.add(4, new ContentItem("Inverted Axis", "Inverted y-axis."));
|
||||
objects.add(5, new ContentItem("Cubic", "Line chart with a cubic line shape."));
|
||||
objects.add(6, new ContentItem("Colorful", "Colorful line chart."));
|
||||
objects.add(7, new ContentItem("Performance", "Render 30.000 data points smoothly."));
|
||||
objects.add(8, new ContentItem("Filled", "Colored area between two lines."));
|
||||
|
||||
////
|
||||
objects.add(9, new ContentItem("Bar Charts"));
|
||||
|
||||
objects.add(10, new ContentItem("Basic", "Simple bar chart."));
|
||||
objects.add(11, new ContentItem("Basic 2", "Variation of the simple bar chart."));
|
||||
objects.add(12, new ContentItem("Multiple", "Show multiple data sets."));
|
||||
objects.add(13, new ContentItem("Horizontal", "Render bar chart horizontally."));
|
||||
objects.add(14, new ContentItem("Stacked", "Stacked bar chart."));
|
||||
objects.add(15, new ContentItem("Negative", "Positive and negative values with unique colors."));
|
||||
objects.add(16, new ContentItem("Stacked 2", "Stacked bar chart with negative values."));
|
||||
objects.add(17, new ContentItem("Sine", "Sine function in bar chart format."));
|
||||
|
||||
////
|
||||
objects.add(18, new ContentItem("Pie Charts"));
|
||||
|
||||
objects.add(19, new ContentItem("Basic", "Simple pie chart."));
|
||||
objects.add(20, new ContentItem("Value Lines", "Stylish lines drawn outward from slices."));
|
||||
objects.add(21, new ContentItem("Half Pie", "180° (half) pie chart."));
|
||||
|
||||
////
|
||||
objects.add(22, new ContentItem("Other Charts"));
|
||||
|
||||
objects.add(23, new ContentItem("Combined Chart", "Bar and line chart together."));
|
||||
objects.add(24, new ContentItem("Scatter Plot", "Simple scatter plot."));
|
||||
objects.add(25, new ContentItem("Bubble Chart", "Simple bubble chart."));
|
||||
objects.add(26, new ContentItem("Candlestick", "Simple financial chart."));
|
||||
objects.add(27, new ContentItem("Radar Chart", "Simple web chart."));
|
||||
|
||||
////
|
||||
objects.add(28, new ContentItem("Scrolling Charts"));
|
||||
|
||||
objects.add(29, new ContentItem("Multiple", "Various types of charts as fragments."));
|
||||
objects.add(30, new ContentItem("View Pager", "Swipe through different charts."));
|
||||
objects.add(31, new ContentItem("Tall Bar Chart", "Bars bigger than your screen!"));
|
||||
objects.add(32, new ContentItem("Many Bar Charts", "More bars than your screen can handle!"));
|
||||
|
||||
////
|
||||
objects.add(33, new ContentItem("Even More Line Charts"));
|
||||
|
||||
objects.add(34, new ContentItem("Dynamic", "Build a line chart by adding points and sets."));
|
||||
objects.add(35, new ContentItem("Realtime", "Add data points in realtime."));
|
||||
objects.add(36, new ContentItem("Hourly", "Uses the current time to add a data point for each hour."));
|
||||
//objects.add(37, new ContentItem("Realm.io Examples", "See more examples that use Realm.io mobile database."));
|
||||
|
||||
MyAdapter adapter = new MyAdapter(this, objects);
|
||||
|
||||
ListView lv = findViewById(R.id.listView1);
|
||||
lv.setAdapter(adapter);
|
||||
|
||||
lv.setOnItemClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> av, View v, int pos, long arg3) {
|
||||
|
||||
Intent i = null;
|
||||
|
||||
switch (pos) {
|
||||
case 1:
|
||||
i = new Intent(this, LineChartActivity1.class);
|
||||
break;
|
||||
case 2:
|
||||
i = new Intent(this, MultiLineChartActivity.class);
|
||||
break;
|
||||
case 3:
|
||||
i = new Intent(this, LineChartActivity2.class);
|
||||
break;
|
||||
case 4:
|
||||
i = new Intent(this, InvertedLineChartActivity.class);
|
||||
break;
|
||||
case 5:
|
||||
i = new Intent(this, CubicLineChartActivity.class);
|
||||
break;
|
||||
case 6:
|
||||
i = new Intent(this, LineChartActivityColored.class);
|
||||
break;
|
||||
case 7:
|
||||
i = new Intent(this, PerformanceLineChart.class);
|
||||
break;
|
||||
case 8:
|
||||
i = new Intent(this, FilledLineActivity.class);
|
||||
break;
|
||||
case 10:
|
||||
i = new Intent(this, BarChartActivity.class);
|
||||
break;
|
||||
case 11:
|
||||
i = new Intent(this, AnotherBarActivity.class);
|
||||
break;
|
||||
case 12:
|
||||
i = new Intent(this, BarChartActivityMultiDataset.class);
|
||||
break;
|
||||
case 13:
|
||||
i = new Intent(this, HorizontalBarChartActivity.class);
|
||||
break;
|
||||
case 14:
|
||||
i = new Intent(this, StackedBarActivity.class);
|
||||
break;
|
||||
case 15:
|
||||
i = new Intent(this, BarChartPositiveNegative.class);
|
||||
break;
|
||||
case 16:
|
||||
i = new Intent(this, StackedBarActivityNegative.class);
|
||||
break;
|
||||
case 17:
|
||||
i = new Intent(this, BarChartActivitySinus.class);
|
||||
break;
|
||||
case 19:
|
||||
i = new Intent(this, PieChartActivity.class);
|
||||
break;
|
||||
case 20:
|
||||
i = new Intent(this, PiePolylineChartActivity.class);
|
||||
break;
|
||||
case 21:
|
||||
i = new Intent(this, HalfPieChartActivity.class);
|
||||
break;
|
||||
case 23:
|
||||
i = new Intent(this, CombinedChartActivity.class);
|
||||
break;
|
||||
case 24:
|
||||
i = new Intent(this, ScatterChartActivity.class);
|
||||
break;
|
||||
case 25:
|
||||
i = new Intent(this, BubbleChartActivity.class);
|
||||
break;
|
||||
case 26:
|
||||
i = new Intent(this, CandleStickChartActivity.class);
|
||||
break;
|
||||
case 27:
|
||||
i = new Intent(this, RadarChartActivity.class);
|
||||
break;
|
||||
case 29:
|
||||
i = new Intent(this, ListViewMultiChartActivity.class);
|
||||
break;
|
||||
case 30:
|
||||
i = new Intent(this, SimpleChartDemo.class);
|
||||
break;
|
||||
case 31:
|
||||
i = new Intent(this, ScrollViewActivity.class);
|
||||
break;
|
||||
case 32:
|
||||
i = new Intent(this, ListViewBarChartActivity.class);
|
||||
break;
|
||||
case 34:
|
||||
i = new Intent(this, DynamicalAddingActivity.class);
|
||||
break;
|
||||
case 35:
|
||||
i = new Intent(this, RealtimeLineChartActivity.class);
|
||||
break;
|
||||
case 36:
|
||||
i = new Intent(this, LineChartTime.class);
|
||||
break;
|
||||
/*case 37:
|
||||
i = new Intent(this, RealmMainActivity.class);
|
||||
break;*/
|
||||
}
|
||||
|
||||
if (i != null) startActivity(i);
|
||||
|
||||
overridePendingTransition(R.anim.move_right_in_activity, R.anim.move_left_out_activity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.main, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
Intent i;
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.viewGithub:
|
||||
i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart"));
|
||||
startActivity(i);
|
||||
break;
|
||||
case R.id.report:
|
||||
i = new Intent(Intent.ACTION_SENDTO, Uri.fromParts(
|
||||
"mailto", "philjay.librarysup@gmail.com", null));
|
||||
i.putExtra(Intent.EXTRA_SUBJECT, "MPAndroidChart Issue");
|
||||
i.putExtra(Intent.EXTRA_TEXT, "Your error report here...");
|
||||
startActivity(Intent.createChooser(i, "Report Problem"));
|
||||
break;
|
||||
case R.id.website:
|
||||
i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse("http://at.linkedin.com/in/philippjahoda"));
|
||||
startActivity(i);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
package com.android.stockapp.ui.mpchartexample.notimportant;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.Typeface;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
|
||||
import com.android.stockapp.R;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Philipp Jahoda on 07/12/15.
|
||||
*/
|
||||
class MyAdapter extends ArrayAdapter<ContentItem> {
|
||||
|
||||
private final Typeface mTypeFaceLight;
|
||||
private final Typeface mTypeFaceRegular;
|
||||
|
||||
MyAdapter(Context context, List<ContentItem> objects) {
|
||||
super(context, 0, objects);
|
||||
|
||||
mTypeFaceLight = Typeface.createFromAsset(context.getAssets(), "OpenSans-Light.ttf");
|
||||
mTypeFaceRegular = Typeface.createFromAsset(context.getAssets(), "OpenSans-Regular.ttf");
|
||||
}
|
||||
|
||||
@SuppressLint("InflateParams")
|
||||
@NonNull
|
||||
@Override
|
||||
public View getView(int position, View convertView, @NonNull ViewGroup parent) {
|
||||
|
||||
ContentItem c = getItem(position);
|
||||
|
||||
ViewHolder holder;
|
||||
|
||||
holder = new ViewHolder();
|
||||
|
||||
if (c != null && c.isSection) {
|
||||
convertView = LayoutInflater.from(getContext()).inflate(R.layout.list_item_section, null);
|
||||
} else {
|
||||
convertView = LayoutInflater.from(getContext()).inflate(R.layout.list_item, null);
|
||||
}
|
||||
|
||||
holder.tvName = convertView.findViewById(R.id.tvName);
|
||||
holder.tvDesc = convertView.findViewById(R.id.tvDesc);
|
||||
|
||||
convertView.setTag(holder);
|
||||
|
||||
if (c != null && c.isSection)
|
||||
holder.tvName.setTypeface(mTypeFaceRegular);
|
||||
else
|
||||
holder.tvName.setTypeface(mTypeFaceLight);
|
||||
holder.tvDesc.setTypeface(mTypeFaceLight);
|
||||
|
||||
holder.tvName.setText(c != null ? c.name : null);
|
||||
holder.tvDesc.setText(c != null ? c.desc : null);
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
private class ViewHolder {
|
||||
|
||||
TextView tvName, tvDesc;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<translate
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:duration="300"
|
||||
android:fromXDelta="-100%p"
|
||||
android:toXDelta="0%p">
|
||||
</translate>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<translate
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:duration="300"
|
||||
android:fromXDelta="0%p"
|
||||
android:toXDelta="-100%p">
|
||||
</translate>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<translate
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:duration="300"
|
||||
android:fromXDelta="100%p"
|
||||
android:toXDelta="0%p">
|
||||
</translate>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<translate
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:duration="300"
|
||||
android:fromXDelta="0%p"
|
||||
android:toXDelta="100%p">
|
||||
</translate>
|
||||
@@ -0,0 +1,34 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportHeight="108"
|
||||
android:viewportWidth="108">
|
||||
<path
|
||||
android:fillType="evenOdd"
|
||||
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
|
||||
android:strokeColor="#00000000"
|
||||
android:strokeWidth="1">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:endX="78.5885"
|
||||
android:endY="90.9159"
|
||||
android:startX="48.7653"
|
||||
android:startY="61.0927"
|
||||
android:type="linear">
|
||||
<item
|
||||
android:color="#44000000"
|
||||
android:offset="0.0" />
|
||||
<item
|
||||
android:color="#00000000"
|
||||
android:offset="1.0" />
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="nonZero"
|
||||
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
|
||||
android:strokeColor="#00000000"
|
||||
android:strokeWidth="1" />
|
||||
</vector>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<gradient
|
||||
android:angle="90"
|
||||
android:startColor="#00ff0000"
|
||||
android:endColor="#ffff0000" />
|
||||
</shape>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user