This commit is contained in:
coco
2026-07-03 15:56:07 +08:00
commit caef23209c
5767 changed files with 1004268 additions and 0 deletions
+1
View File
@@ -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'
}
+21
View File
@@ -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
@@ -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>
@@ -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
@@ -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);
}
}
}
@@ -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);
}
}
File diff suppressed because one or more lines are too long
@@ -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
}
@@ -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;
}
}
@@ -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();
}
}
@@ -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;
}
}
}
@@ -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);
}
}
@@ -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);
}
}
@@ -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();
}
}
@@ -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;//日K1;周K7;月K30
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();
}
}
@@ -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();
}
}
@@ -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) {}
}
@@ -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() { }
}
@@ -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.");
}
}
@@ -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) {}
}
@@ -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 */ }
}
@@ -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) {}
}
@@ -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) {}
}
@@ -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 */ }
}
@@ -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) {}
}
@@ -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());
}
}
@@ -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");
}
}
@@ -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 */ }
}
@@ -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 */ }
}
@@ -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() {}
}
@@ -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) {}
}
@@ -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.");
}
}
@@ -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) {}
}
@@ -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 */ }
}
@@ -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) {}
}
@@ -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 */ }
}
@@ -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 */ }
}
@@ -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) {}
}
@@ -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) {}
}
@@ -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) {}
}
@@ -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) {}
}
@@ -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");
}
}
@@ -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();
}
}
}
@@ -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) {}
}
@@ -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 */ }
}
@@ -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;
}
}
@@ -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";
}
}
}
@@ -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);
}
}
@@ -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;
}
}
@@ -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);
}
}
@@ -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;
}
}
@@ -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());
}
}
@@ -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);
}
}
}
@@ -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);
}
}
@@ -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());
}
}
@@ -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());
}
}
@@ -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)];
}
}
@@ -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);
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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 */ }
}
@@ -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];
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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);
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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();
}
@@ -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;
}
}
@@ -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