的
@@ -0,0 +1,2 @@
|
||||
/build
|
||||
/release
|
||||
@@ -0,0 +1,26 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 28
|
||||
defaultConfig {
|
||||
applicationId "com.xxmassdeveloper.mpchartexample"
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 28
|
||||
versionCode 57
|
||||
versionName '3.1.0'
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "androidx.appcompat:appcompat:1.0.2"
|
||||
implementation 'com.google.android.material:material:1.0.0'
|
||||
implementation project(':MPChartLib')
|
||||
}
|
||||
@@ -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,57 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.xxmassdeveloper.mpchartexample">
|
||||
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
|
||||
<application
|
||||
android:allowBackup="false"
|
||||
android:hardwareAccelerated="true"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity
|
||||
android:name="com.xxmassdeveloper.mpchartexample.notimportant.MainActivity"
|
||||
android:label="@string/app_name" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name="LineChartActivity1" />
|
||||
<activity android:name="LineChartActivity2" />
|
||||
<activity android:name="LineChartTime" />
|
||||
<activity android:name="BarChartActivity" />
|
||||
<activity android:name="HorizontalBarChartActivity" />
|
||||
<activity android:name="HorizontalBarNegativeChartActivity" />
|
||||
<activity android:name="PieChartActivity" />
|
||||
<activity android:name="PiePolylineChartActivity" />
|
||||
<activity android:name="MultiLineChartActivity" />
|
||||
<activity android:name="BarChartActivityMultiDataset" />
|
||||
<activity android:name="DrawChartActivity" />
|
||||
<activity android:name="ScatterChartActivity" />
|
||||
<activity android:name="BubbleChartActivity" />
|
||||
<activity android:name=".fragments.SimpleChartDemo" />
|
||||
<activity android:name="ListViewBarChartActivity" />
|
||||
<activity android:name="ListViewMultiChartActivity" />
|
||||
<activity android:name="StackedBarActivity" />
|
||||
<activity android:name="AnotherBarActivity" />
|
||||
<activity android:name="InvertedLineChartActivity" />
|
||||
<activity android:name="CandleStickChartActivity" />
|
||||
<activity android:name="CubicLineChartActivity" />
|
||||
<activity android:name="RadarChartActivity" />
|
||||
<activity android:name="LineChartActivityColored" />
|
||||
<activity android:name="DynamicalAddingActivity" />
|
||||
<activity android:name="RealtimeLineChartActivity" />
|
||||
<activity android:name="CombinedChartActivity" />
|
||||
<activity android:name="PerformanceLineChart" />
|
||||
<activity android:name="BarChartActivitySinus" />
|
||||
<activity android:name="ScrollViewActivity" />
|
||||
<activity android:name="StackedBarActivityNegative" />
|
||||
<activity android:name="BarChartPositiveNegative" />
|
||||
<activity android:name="FilledLineActivity" />
|
||||
<activity android:name="HalfPieChartActivity" />
|
||||
</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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
After Width: | Height: | Size: 4.0 KiB |
@@ -0,0 +1,214 @@
|
||||
|
||||
package com.xxmassdeveloper.mpchartexample;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import androidx.core.content.ContextCompat;
|
||||
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.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 com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
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,327 @@
|
||||
|
||||
package com.xxmassdeveloper.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 androidx.core.content.ContextCompat;
|
||||
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 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.IAxisValueFormatter;
|
||||
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.utils.Fill;
|
||||
import com.github.mikephil.charting.utils.MPPointF;
|
||||
import com.xxmassdeveloper.mpchartexample.custom.DayAxisValueFormatter;
|
||||
import com.xxmassdeveloper.mpchartexample.custom.MyAxisValueFormatter;
|
||||
import com.xxmassdeveloper.mpchartexample.custom.XYMarkerView;
|
||||
import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
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);
|
||||
|
||||
IAxisValueFormatter 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);
|
||||
|
||||
IAxisValueFormatter custom = new MyAxisValueFormatter();
|
||||
|
||||
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);
|
||||
|
||||
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<Fill> gradientFills = new ArrayList<>();
|
||||
gradientFills.add(new Fill(startColor1, endColor1));
|
||||
gradientFills.add(new Fill(startColor2, endColor2));
|
||||
gradientFills.add(new Fill(startColor3, endColor3));
|
||||
gradientFills.add(new Fill(startColor4, endColor4));
|
||||
gradientFills.add(new Fill(startColor5, endColor5));
|
||||
|
||||
set1.setFills(gradientFills);
|
||||
|
||||
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.xxmassdeveloper.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 androidx.core.content.ContextCompat;
|
||||
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 com.github.mikephil.charting.charts.BarChart;
|
||||
import com.github.mikephil.charting.components.AxisBase;
|
||||
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.IAxisValueFormatter;
|
||||
import com.github.mikephil.charting.formatter.LargeValueFormatter;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IBarDataSet;
|
||||
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
|
||||
import com.xxmassdeveloper.mpchartexample.custom.MyMarkerView;
|
||||
import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
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 IAxisValueFormatter() {
|
||||
@Override
|
||||
public String getFormattedValue(float value, AxisBase axis) {
|
||||
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,239 @@
|
||||
|
||||
package com.xxmassdeveloper.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 androidx.core.content.ContextCompat;
|
||||
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.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 com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
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,200 @@
|
||||
|
||||
package com.xxmassdeveloper.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.github.mikephil.charting.charts.BarChart;
|
||||
import com.github.mikephil.charting.components.AxisBase;
|
||||
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.IAxisValueFormatter;
|
||||
import com.github.mikephil.charting.formatter.IValueFormatter;
|
||||
import com.github.mikephil.charting.utils.ViewPortHandler;
|
||||
import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
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 IAxisValueFormatter() {
|
||||
@Override
|
||||
public String getFormattedValue(float value, AxisBase axis) {
|
||||
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 ValueFormatter());
|
||||
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 ValueFormatter implements IValueFormatter
|
||||
{
|
||||
|
||||
private final DecimalFormat mFormat;
|
||||
|
||||
ValueFormatter() {
|
||||
mFormat = new DecimalFormat("######.0");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
|
||||
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,248 @@
|
||||
|
||||
package com.xxmassdeveloper.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 androidx.core.content.ContextCompat;
|
||||
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 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 com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
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,238 @@
|
||||
|
||||
package com.xxmassdeveloper.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 androidx.core.content.ContextCompat;
|
||||
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.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 com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
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,282 @@
|
||||
|
||||
package com.xxmassdeveloper.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.github.mikephil.charting.charts.CombinedChart;
|
||||
import com.github.mikephil.charting.charts.CombinedChart.DrawOrder;
|
||||
import com.github.mikephil.charting.components.AxisBase;
|
||||
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.IAxisValueFormatter;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IDataSet;
|
||||
import com.github.mikephil.charting.utils.ColorTemplate;
|
||||
import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
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 IAxisValueFormatter() {
|
||||
@Override
|
||||
public String getFormattedValue(float value, AxisBase axis) {
|
||||
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,320 @@
|
||||
|
||||
package com.xxmassdeveloper.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 androidx.core.content.ContextCompat;
|
||||
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.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 com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
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,184 @@
|
||||
// TODO: Finish and add to main activity list
|
||||
package com.xxmassdeveloper.mpchartexample;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Bundle;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
|
||||
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 com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
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,242 @@
|
||||
|
||||
package com.xxmassdeveloper.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 androidx.core.content.ContextCompat;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Toast;
|
||||
|
||||
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 com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
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,189 @@
|
||||
|
||||
package com.xxmassdeveloper.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.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 com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
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,168 @@
|
||||
|
||||
package com.xxmassdeveloper.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.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 com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
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,291 @@
|
||||
|
||||
package com.xxmassdeveloper.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 androidx.core.content.ContextCompat;
|
||||
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 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 com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
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,292 @@
|
||||
|
||||
package com.xxmassdeveloper.mpchartexample;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
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 android.widget.Toast;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
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 com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class HorizontalBarNegativeChartActivity 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.setInverted(true);
|
||||
|
||||
YAxis yr = chart.getAxisRight();
|
||||
yr.setTypeface(tfLight);
|
||||
yr.setDrawAxisLine(true);
|
||||
yr.setDrawGridLines(false);
|
||||
// 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 - range / 2);
|
||||
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,283 @@
|
||||
|
||||
package com.xxmassdeveloper.mpchartexample;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import androidx.core.content.ContextCompat;
|
||||
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 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 com.xxmassdeveloper.mpchartexample.custom.MyMarkerView;
|
||||
import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
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,454 @@
|
||||
|
||||
package com.xxmassdeveloper.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 androidx.core.content.ContextCompat;
|
||||
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 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 com.xxmassdeveloper.mpchartexample.custom.MyMarkerView;
|
||||
import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
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,409 @@
|
||||
|
||||
package com.xxmassdeveloper.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 androidx.core.content.ContextCompat;
|
||||
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 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 com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
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,155 @@
|
||||
|
||||
package com.xxmassdeveloper.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.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.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
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.xxmassdeveloper.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 androidx.core.content.ContextCompat;
|
||||
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.github.mikephil.charting.charts.LineChart;
|
||||
import com.github.mikephil.charting.components.AxisBase;
|
||||
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.IAxisValueFormatter;
|
||||
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
|
||||
import com.github.mikephil.charting.utils.ColorTemplate;
|
||||
import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
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 IAxisValueFormatter() {
|
||||
|
||||
private final SimpleDateFormat mFormat = new SimpleDateFormat("dd MMM HH:mm", Locale.ENGLISH);
|
||||
|
||||
@Override
|
||||
public String getFormattedValue(float value, AxisBase axis) {
|
||||
|
||||
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,181 @@
|
||||
|
||||
package com.xxmassdeveloper.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 androidx.annotation.NonNull;
|
||||
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 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 com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
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,209 @@
|
||||
|
||||
package com.xxmassdeveloper.mpchartexample;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
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 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 com.xxmassdeveloper.mpchartexample.listviewitems.BarChartItem;
|
||||
import com.xxmassdeveloper.mpchartexample.listviewitems.ChartItem;
|
||||
import com.xxmassdeveloper.mpchartexample.listviewitems.LineChartItem;
|
||||
import com.xxmassdeveloper.mpchartexample.listviewitems.PieChartItem;
|
||||
import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
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,354 @@
|
||||
|
||||
package com.xxmassdeveloper.mpchartexample;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import androidx.core.content.ContextCompat;
|
||||
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 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 com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
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,144 @@
|
||||
|
||||
package com.xxmassdeveloper.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.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.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
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,326 @@
|
||||
|
||||
package com.xxmassdeveloper.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 androidx.core.content.ContextCompat;
|
||||
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 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 com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
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());
|
||||
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,320 @@
|
||||
|
||||
package com.xxmassdeveloper.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 androidx.core.content.ContextCompat;
|
||||
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 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.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
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.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.xxmassdeveloper.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 androidx.core.content.ContextCompat;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.github.mikephil.charting.animation.Easing;
|
||||
import com.github.mikephil.charting.charts.RadarChart;
|
||||
import com.github.mikephil.charting.components.AxisBase;
|
||||
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.IAxisValueFormatter;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IDataSet;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IRadarDataSet;
|
||||
import com.xxmassdeveloper.mpchartexample.custom.RadarMarkerView;
|
||||
import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
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 IAxisValueFormatter() {
|
||||
|
||||
private final String[] mActivities = new String[]{"Burger", "Steak", "Salad", "Pasta", "Pizza"};
|
||||
|
||||
@Override
|
||||
public String getFormattedValue(float value, AxisBase axis) {
|
||||
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,249 @@
|
||||
|
||||
package com.xxmassdeveloper.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 androidx.core.content.ContextCompat;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Toast;
|
||||
|
||||
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 com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
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,247 @@
|
||||
|
||||
package com.xxmassdeveloper.mpchartexample;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import androidx.core.content.ContextCompat;
|
||||
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 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 com.xxmassdeveloper.mpchartexample.custom.CustomScatterShapeRenderer;
|
||||
import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
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,101 @@
|
||||
|
||||
package com.xxmassdeveloper.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.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 com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
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,284 @@
|
||||
package com.xxmassdeveloper.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 androidx.core.content.ContextCompat;
|
||||
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 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.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 com.xxmassdeveloper.mpchartexample.custom.MyAxisValueFormatter;
|
||||
import com.xxmassdeveloper.mpchartexample.custom.MyValueFormatter;
|
||||
import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
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 MyAxisValueFormatter());
|
||||
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 MyValueFormatter());
|
||||
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,265 @@
|
||||
|
||||
package com.xxmassdeveloper.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 androidx.core.content.ContextCompat;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.github.mikephil.charting.charts.HorizontalBarChart;
|
||||
import com.github.mikephil.charting.components.AxisBase;
|
||||
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.IValueFormatter;
|
||||
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
|
||||
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.ViewPortHandler;
|
||||
import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
|
||||
|
||||
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 IAxisValueFormatter() {
|
||||
|
||||
private final DecimalFormat format = new DecimalFormat("###");
|
||||
|
||||
@Override
|
||||
public String getFormattedValue(float value, AxisBase axis) {
|
||||
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 implements IValueFormatter, IAxisValueFormatter {
|
||||
|
||||
private final DecimalFormat mFormat;
|
||||
|
||||
CustomFormatter() {
|
||||
mFormat = new DecimalFormat("###");
|
||||
}
|
||||
|
||||
// data
|
||||
@Override
|
||||
public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
|
||||
return mFormat.format(Math.abs(value)) + "m";
|
||||
}
|
||||
|
||||
// YAxis
|
||||
@Override
|
||||
public String getFormattedValue(float value, AxisBase axis) {
|
||||
return mFormat.format(Math.abs(value)) + "m";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.xxmassdeveloper.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,139 @@
|
||||
package com.xxmassdeveloper.mpchartexample.custom;
|
||||
|
||||
import com.github.mikephil.charting.charts.BarLineChartBase;
|
||||
import com.github.mikephil.charting.components.AxisBase;
|
||||
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
|
||||
|
||||
/**
|
||||
* Created by philipp on 02/06/16.
|
||||
*/
|
||||
public class DayAxisValueFormatter implements IAxisValueFormatter
|
||||
{
|
||||
|
||||
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, AxisBase axis) {
|
||||
|
||||
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,21 @@
|
||||
package com.xxmassdeveloper.mpchartexample.custom;
|
||||
|
||||
import com.github.mikephil.charting.components.AxisBase;
|
||||
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
public class MyAxisValueFormatter implements IAxisValueFormatter
|
||||
{
|
||||
|
||||
private final DecimalFormat mFormat;
|
||||
|
||||
public MyAxisValueFormatter() {
|
||||
mFormat = new DecimalFormat("###,###,###,##0.0");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormattedValue(float value, AxisBase axis) {
|
||||
return mFormat.format(value) + " $";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.xxmassdeveloper.mpchartexample.custom;
|
||||
|
||||
import com.github.mikephil.charting.components.AxisBase;
|
||||
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
|
||||
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 implements IAxisValueFormatter
|
||||
{
|
||||
|
||||
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, AxisBase axis) {
|
||||
|
||||
//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.xxmassdeveloper.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.xxmassdeveloper.mpchartexample.custom;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.widget.TextView;
|
||||
|
||||
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;
|
||||
import com.xxmassdeveloper.mpchartexample.R;
|
||||
|
||||
/**
|
||||
* 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,22 @@
|
||||
package com.xxmassdeveloper.mpchartexample.custom;
|
||||
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.formatter.IValueFormatter;
|
||||
import com.github.mikephil.charting.utils.ViewPortHandler;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
public class MyValueFormatter implements IValueFormatter
|
||||
{
|
||||
|
||||
private final DecimalFormat mFormat;
|
||||
|
||||
public MyValueFormatter() {
|
||||
mFormat = new DecimalFormat("###,###,###,##0.0");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
|
||||
return mFormat.format(value) + " $";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
|
||||
package com.xxmassdeveloper.mpchartexample.custom;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.Typeface;
|
||||
import android.widget.TextView;
|
||||
|
||||
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 com.xxmassdeveloper.mpchartexample.R;
|
||||
|
||||
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.xxmassdeveloper.mpchartexample.custom;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.widget.TextView;
|
||||
|
||||
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;
|
||||
import com.xxmassdeveloper.mpchartexample.R;
|
||||
|
||||
/**
|
||||
* 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,52 @@
|
||||
|
||||
package com.xxmassdeveloper.mpchartexample.custom;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.github.mikephil.charting.components.MarkerView;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.utils.MPPointF;
|
||||
import com.xxmassdeveloper.mpchartexample.R;
|
||||
|
||||
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 IAxisValueFormatter xAxisValueFormatter;
|
||||
|
||||
private final DecimalFormat format;
|
||||
|
||||
public XYMarkerView(Context context, IAxisValueFormatter 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(), null), format.format(e.getY())));
|
||||
|
||||
super.refreshContent(e, highlight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MPPointF getOffset() {
|
||||
return new MPPointF(-(getWidth() / 2), -getHeight());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.xxmassdeveloper.mpchartexample.custom;
|
||||
|
||||
import com.github.mikephil.charting.components.AxisBase;
|
||||
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
|
||||
|
||||
/**
|
||||
* Created by Philipp Jahoda on 14/09/15.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class YearXAxisFormatter implements IAxisValueFormatter
|
||||
{
|
||||
|
||||
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 getFormattedValue(float value, AxisBase axis) {
|
||||
|
||||
float percent = value / axis.mAxisRange;
|
||||
return mMonths[(int) (mMonths.length * percent)];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
package com.xxmassdeveloper.mpchartexample.fragments;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
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 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;
|
||||
import com.xxmassdeveloper.mpchartexample.R;
|
||||
import com.xxmassdeveloper.mpchartexample.custom.MyMarkerView;
|
||||
|
||||
|
||||
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,55 @@
|
||||
package com.xxmassdeveloper.mpchartexample.fragments;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
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.xxmassdeveloper.mpchartexample.R;
|
||||
|
||||
|
||||
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,64 @@
|
||||
package com.xxmassdeveloper.mpchartexample.fragments;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
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 com.github.mikephil.charting.charts.PieChart;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.xxmassdeveloper.mpchartexample.R;
|
||||
|
||||
|
||||
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,69 @@
|
||||
package com.xxmassdeveloper.mpchartexample.fragments;
|
||||
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
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;
|
||||
import com.xxmassdeveloper.mpchartexample.R;
|
||||
import com.xxmassdeveloper.mpchartexample.custom.MyMarkerView;
|
||||
|
||||
|
||||
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,117 @@
|
||||
|
||||
package com.xxmassdeveloper.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 androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentPagerAdapter;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.xxmassdeveloper.mpchartexample.R;
|
||||
import com.xxmassdeveloper.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,199 @@
|
||||
package com.xxmassdeveloper.mpchartexample.fragments;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
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,57 @@
|
||||
package com.xxmassdeveloper.mpchartexample.fragments;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
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.xxmassdeveloper.mpchartexample.R;
|
||||
|
||||
|
||||
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.xxmassdeveloper.mpchartexample.listviewitems;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.Typeface;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
|
||||
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;
|
||||
import com.xxmassdeveloper.mpchartexample.R;
|
||||
|
||||
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.xxmassdeveloper.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.xxmassdeveloper.mpchartexample.listviewitems;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.Typeface;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
|
||||
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;
|
||||
import com.xxmassdeveloper.mpchartexample.R;
|
||||
|
||||
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.xxmassdeveloper.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.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;
|
||||
import com.xxmassdeveloper.mpchartexample.R;
|
||||
|
||||
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.xxmassdeveloper.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.xxmassdeveloper.mpchartexample.notimportant;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.github.mikephil.charting.charts.Chart;
|
||||
import com.xxmassdeveloper.mpchartexample.R;
|
||||
|
||||
/**
|
||||
* 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,280 @@
|
||||
|
||||
package com.xxmassdeveloper.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 com.github.mikephil.charting.utils.Utils;
|
||||
import com.xxmassdeveloper.mpchartexample.AnotherBarActivity;
|
||||
import com.xxmassdeveloper.mpchartexample.BarChartActivity;
|
||||
import com.xxmassdeveloper.mpchartexample.BarChartActivityMultiDataset;
|
||||
import com.xxmassdeveloper.mpchartexample.BarChartActivitySinus;
|
||||
import com.xxmassdeveloper.mpchartexample.BarChartPositiveNegative;
|
||||
import com.xxmassdeveloper.mpchartexample.BubbleChartActivity;
|
||||
import com.xxmassdeveloper.mpchartexample.CandleStickChartActivity;
|
||||
import com.xxmassdeveloper.mpchartexample.CombinedChartActivity;
|
||||
import com.xxmassdeveloper.mpchartexample.CubicLineChartActivity;
|
||||
import com.xxmassdeveloper.mpchartexample.DynamicalAddingActivity;
|
||||
import com.xxmassdeveloper.mpchartexample.FilledLineActivity;
|
||||
import com.xxmassdeveloper.mpchartexample.HalfPieChartActivity;
|
||||
import com.xxmassdeveloper.mpchartexample.HorizontalBarChartActivity;
|
||||
import com.xxmassdeveloper.mpchartexample.HorizontalBarNegativeChartActivity;
|
||||
import com.xxmassdeveloper.mpchartexample.InvertedLineChartActivity;
|
||||
import com.xxmassdeveloper.mpchartexample.LineChartActivity1;
|
||||
import com.xxmassdeveloper.mpchartexample.LineChartActivity2;
|
||||
import com.xxmassdeveloper.mpchartexample.LineChartActivityColored;
|
||||
import com.xxmassdeveloper.mpchartexample.LineChartTime;
|
||||
import com.xxmassdeveloper.mpchartexample.ListViewBarChartActivity;
|
||||
import com.xxmassdeveloper.mpchartexample.ListViewMultiChartActivity;
|
||||
import com.xxmassdeveloper.mpchartexample.MultiLineChartActivity;
|
||||
import com.xxmassdeveloper.mpchartexample.PerformanceLineChart;
|
||||
import com.xxmassdeveloper.mpchartexample.PieChartActivity;
|
||||
import com.xxmassdeveloper.mpchartexample.PiePolylineChartActivity;
|
||||
import com.xxmassdeveloper.mpchartexample.R;
|
||||
import com.xxmassdeveloper.mpchartexample.RadarChartActivity;
|
||||
import com.xxmassdeveloper.mpchartexample.RealtimeLineChartActivity;
|
||||
import com.xxmassdeveloper.mpchartexample.ScatterChartActivity;
|
||||
import com.xxmassdeveloper.mpchartexample.ScrollViewActivity;
|
||||
import com.xxmassdeveloper.mpchartexample.StackedBarActivity;
|
||||
import com.xxmassdeveloper.mpchartexample.StackedBarActivityNegative;
|
||||
import com.xxmassdeveloper.mpchartexample.fragments.SimpleChartDemo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
public class MainActivity 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_main);
|
||||
|
||||
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("Negative Horizontal", "demonstrates how to create a HorizontalBarChart with positive and negative values."));
|
||||
objects.add(17, new ContentItem("Stacked 2", "Stacked bar chart with negative values."));
|
||||
objects.add(18, new ContentItem("Sine", "Sine function in bar chart format."));
|
||||
|
||||
////
|
||||
objects.add(19, new ContentItem("Pie Charts"));
|
||||
|
||||
objects.add(20, new ContentItem("Basic", "Simple pie chart."));
|
||||
objects.add(21, new ContentItem("Value Lines", "Stylish lines drawn outward from slices."));
|
||||
objects.add(22, new ContentItem("Half Pie", "180° (half) pie chart."));
|
||||
|
||||
////
|
||||
objects.add(23, new ContentItem("Other Charts"));
|
||||
|
||||
objects.add(24, new ContentItem("Combined Chart", "Bar and line chart together."));
|
||||
objects.add(25, new ContentItem("Scatter Plot", "Simple scatter plot."));
|
||||
objects.add(26, new ContentItem("Bubble Chart", "Simple bubble chart."));
|
||||
objects.add(27, new ContentItem("Candlestick", "Simple financial chart."));
|
||||
objects.add(28, new ContentItem("Radar Chart", "Simple web chart."));
|
||||
|
||||
////
|
||||
objects.add(29, new ContentItem("Scrolling Charts"));
|
||||
|
||||
objects.add(30, new ContentItem("Multiple", "Various types of charts as fragments."));
|
||||
objects.add(31, new ContentItem("View Pager", "Swipe through different charts."));
|
||||
objects.add(32, new ContentItem("Tall Bar Chart", "Bars bigger than your screen!"));
|
||||
objects.add(33, new ContentItem("Many Bar Charts", "More bars than your screen can handle!"));
|
||||
|
||||
////
|
||||
objects.add(34, new ContentItem("Even More Line Charts"));
|
||||
|
||||
objects.add(35, new ContentItem("Dynamic", "Build a line chart by adding points and sets."));
|
||||
objects.add(36, new ContentItem("Realtime", "Add data points in realtime."));
|
||||
objects.add(37, new ContentItem("Hourly", "Uses the current time to add a data point for each hour."));
|
||||
//objects.add(38, 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, HorizontalBarNegativeChartActivity.class);
|
||||
break;
|
||||
case 17:
|
||||
i = new Intent(this, StackedBarActivityNegative.class);
|
||||
break;
|
||||
case 18:
|
||||
i = new Intent(this, BarChartActivitySinus.class);
|
||||
break;
|
||||
case 20:
|
||||
i = new Intent(this, PieChartActivity.class);
|
||||
break;
|
||||
case 21:
|
||||
i = new Intent(this, PiePolylineChartActivity.class);
|
||||
break;
|
||||
case 22:
|
||||
i = new Intent(this, HalfPieChartActivity.class);
|
||||
break;
|
||||
case 24:
|
||||
i = new Intent(this, CombinedChartActivity.class);
|
||||
break;
|
||||
case 25:
|
||||
i = new Intent(this, ScatterChartActivity.class);
|
||||
break;
|
||||
case 26:
|
||||
i = new Intent(this, BubbleChartActivity.class);
|
||||
break;
|
||||
case 27:
|
||||
i = new Intent(this, CandleStickChartActivity.class);
|
||||
break;
|
||||
case 28:
|
||||
i = new Intent(this, RadarChartActivity.class);
|
||||
break;
|
||||
case 30:
|
||||
i = new Intent(this, ListViewMultiChartActivity.class);
|
||||
break;
|
||||
case 31:
|
||||
i = new Intent(this, SimpleChartDemo.class);
|
||||
break;
|
||||
case 32:
|
||||
i = new Intent(this, ScrollViewActivity.class);
|
||||
break;
|
||||
case 33:
|
||||
i = new Intent(this, ListViewBarChartActivity.class);
|
||||
break;
|
||||
case 35:
|
||||
i = new Intent(this, DynamicalAddingActivity.class);
|
||||
break;
|
||||
case 36:
|
||||
i = new Intent(this, RealtimeLineChartActivity.class);
|
||||
break;
|
||||
case 37:
|
||||
i = new Intent(this, LineChartTime.class);
|
||||
break;
|
||||
/*case 38:
|
||||
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,71 @@
|
||||
package com.xxmassdeveloper.mpchartexample.notimportant;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.Typeface;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.xxmassdeveloper.mpchartexample.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>
|
||||
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 9.5 KiB |
|
After Width: | Height: | Size: 7.9 KiB |
|
After Width: | Height: | Size: 15 KiB |
@@ -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>
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.github.mikephil.charting.charts.HorizontalBarChart
|
||||
android:id="@+id/chart1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@android:color/white" />
|
||||
|
||||
</RelativeLayout>
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.viewpager.widget.ViewPager
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/pager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</RelativeLayout>
|
||||
@@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.github.mikephil.charting.charts.BarChart
|
||||
android:id="@+id/chart1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_above="@+id/seekBar1" />
|
||||
|
||||
<SeekBar
|
||||
android:id="@+id/seekBar2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_margin="8dp"
|
||||
android:layout_toLeftOf="@+id/tvYMax"
|
||||
android:layout_marginRight="5dp"
|
||||
android:max="200"
|
||||
android:paddingBottom="12dp" />
|
||||
|
||||
<SeekBar
|
||||
android:id="@+id/seekBar1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_above="@+id/seekBar2"
|
||||
android:layout_margin="8dp"
|
||||
android:layout_marginBottom="35dp"
|
||||
android:layout_toLeftOf="@+id/tvXMax"
|
||||
android:layout_marginRight="5dp"
|
||||
android:max="1500"
|
||||
android:paddingBottom="12dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvXMax"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignBottom="@+id/seekBar1"
|
||||
android:layout_alignParentRight="true"
|
||||
android:text="@string/dash"
|
||||
android:layout_marginBottom="15dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:gravity="right"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvYMax"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignBottom="@+id/seekBar2"
|
||||
android:layout_alignParentRight="true"
|
||||
android:text="@string/dash"
|
||||
android:layout_marginBottom="15dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:gravity="right"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
</RelativeLayout>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.github.mikephil.charting.charts.BarChart
|
||||
android:id="@+id/chart1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</RelativeLayout>
|
||||
@@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.github.mikephil.charting.charts.BarChart
|
||||
android:id="@+id/chart1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_above="@+id/seekbarValues" />
|
||||
|
||||
<SeekBar
|
||||
android:id="@+id/seekbarValues"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_margin="8dp"
|
||||
android:layout_marginBottom="35dp"
|
||||
android:layout_toLeftOf="@+id/tvValueCount"
|
||||
android:layout_marginRight="5dp"
|
||||
android:max="8000"
|
||||
android:paddingBottom="12dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvValueCount"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignBottom="@+id/seekbarValues"
|
||||
android:layout_alignParentRight="true"
|
||||
android:text="@string/dash"
|
||||
android:layout_marginBottom="15dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:gravity="right"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
</RelativeLayout>
|
||||