This commit is contained in:
coco
2026-07-03 15:56:07 +08:00
commit caef23209c
5767 changed files with 1004268 additions and 0 deletions
+2
View File
@@ -0,0 +1,2 @@
[*.{kt,kts}]
disabled_rules=import-ordering
+43
View File
@@ -0,0 +1,43 @@
# Windows thumbnail db
Thumbs.db
# OSX files
.DS_Store
# built application files
*.apk
*.ap_
# files for the dex VM
*.dex
# Java class files
*.class
# generated files
bin/
gen/
build/
# Local configuration file (sdk path, etc)
local.properties
# Eclipse project files
.classpath
.project
# Android Studio
.idea
.gradle
/*/local.properties
/*/out
/*/*/build
build
/*/*/production
*.iml
*.iws
*.ipr
*~
*.swp
/kick
+16
View File
@@ -0,0 +1,16 @@
release-bintray: # Make sure to update the release version before releasing
./gradlew clean build bintrayUpload
release-play: # Make sure to update the release version before releasing
./gradlew publishReleaseApk
check:
./gradlew lint
./gradlew detekt
test:
./gradlew test
stop:
./gradlew --stop
+96
View File
@@ -0,0 +1,96 @@
# williamchart ![phone][2]![watch][3]
[![Kotlin Version](https://img.shields.io/badge/kotlin-1.4.10-blue.svg)](https://kotlinlang.org)
[![API](https://img.shields.io/badge/API-16%2B-brightgreen.svg?style=flat)](https://android-arsenal.com/api?level=16)
[![CodeFactor](https://www.codefactor.io/repository/github/diogobernardino/williamchart/badge)](https://www.codefactor.io/repository/github/diogobernardino/williamchart)
Williamchart is an Android Library to rapidly implement attractive and insightful charts in android applications.
Note: WilliamChart v3 has been completely re-written from scratch in Kotlin and does not guarantee any API/features compatibility with previous versions. Android development has been evolving quickly, and much has changed since I first started developing williamchart (e.g patterns, testing, tools), so I decided it was time to rewrite it with all these new tools in mind. I intend to keep it as light and modular as possible.
![screenshot][4]
### Gradle
``` groovy
// Charts
implementation 'com.diogobernardino:williamchart:3.10.1'
// Tooltips
implementation 'com.diogobernardino.williamchart:tooltip-slider:3.10.1'
implementation 'com.diogobernardino.williamchart:tooltip-points:3.10.1'
```
If you find this library useful and decide to use it in your projects please drop me a line [@dfbernardino][1], I will be happy to know about it.
### Usage
#### All charts
```xml
<com.db.williamchart.view.chart_view
...
app:chart_labelsColor="color"
app:chart_labelsSize="dimension"
app:chart_labelsFont="font"
/>
```
#### Line Chart
```xml
<com.db.williamchart.view.LinechartView
...
app:chart_lineColor="color"
app:chart_lineThickness="dimension"
app:chart_smoothLine=[ "true" | "false" ]
app:chart_pointDrawable="drawable"
/>
```
#### Bar Chart
```xml
<com.db.williamchart.view.BarChartView|HorizontalBarChartView
...
app:chart_spacing="dimension"
app:chart_barsColor="color"
app:chart_barsBackgroundColor="color"
app:chart_barsRadius="dimension"
/>
```
#### Donut Chart
```xml
<com.db.williamchart.view.DonutChartView
...
app:chart_donutThickness="dimension"
app:chart_donutBackgroundColor="color"
app:chart_donutRoundCorners="boolean"
app:chart_donutTotal="float"
/>
```
License
-------
Copyright 2019 Diogo Bernardino
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
[1]: https://twitter.com/dfbernardino
[2]: ./art/phone.png
[3]: ./art/watch.png
[4]: ./art/demo_screenshot.png
+1
View File
@@ -0,0 +1 @@
theme: jekyll-theme-minimal
Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 351 B

+40
View File
@@ -0,0 +1,40 @@
buildscript {
ext {
williamchartVersion = "3.10.1"
targetSdkVersion = 30
minSdkVersion = 16
kotlinVersion = "1.4.10"
}
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.10"
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4'
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
}
}
plugins {
id "io.gitlab.arturbosch.detekt" version "1.0.0"
id "com.vanniktech.android.junit.jacoco" version "0.15.0"
}
allprojects {
repositories {
google()
jcenter()
}
apply from: "$rootDir/ktlint.gradle"
apply from: "$rootDir/detekt.gradle"
apply from: "$rootDir/jacoco.gradle"
}
task clean(type: Delete) {
delete rootProject.buildDir
}
+550
View File
@@ -0,0 +1,550 @@
build:
maxIssues: 10
weights:
# complexity: 2
# LongParameterList: 1
# style: 1
# comments: 1
processors:
active: true
exclude:
# - 'DetektProgressListener'
# - 'FunctionCountProcessor'
# - 'PropertyCountProcessor'
# - 'ClassCountProcessor'
# - 'PackageCountProcessor'
# - 'KtFileCountProcessor'
console-reports:
active: true
exclude:
# - 'ProjectStatisticsReport'
# - 'ComplexityReport'
# - 'NotificationReport'
# - 'FindingsReport'
# - 'BuildFailureReport'
comments:
active: true
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
CommentOverPrivateFunction:
active: false
CommentOverPrivateProperty:
active: false
EndOfSentenceFormat:
active: false
endOfSentenceFormat: ([.?!][ \t\n\r\f<])|([.?!:]$)
UndocumentedPublicClass:
active: false
searchInNestedClass: true
searchInInnerClass: true
searchInInnerObject: true
searchInInnerInterface: true
UndocumentedPublicFunction:
active: false
complexity:
active: true
ComplexCondition:
active: true
threshold: 4
ComplexInterface:
active: false
threshold: 10
includeStaticDeclarations: false
ComplexMethod:
active: true
threshold: 10
ignoreSingleWhenExpression: false
ignoreSimpleWhenEntries: false
LabeledExpression:
active: false
ignoredLabels: ""
LargeClass:
active: true
threshold: 600
LongMethod:
active: true
threshold: 60
LongParameterList:
active: true
threshold: 6
ignoreDefaultParameters: false
MethodOverloading:
active: false
threshold: 6
NestedBlockDepth:
active: true
threshold: 4
StringLiteralDuplication:
active: false
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
threshold: 3
ignoreAnnotation: true
excludeStringsWithLessThan5Characters: true
ignoreStringsRegex: '$^'
TooManyFunctions:
active: true
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
thresholdInFiles: 11
thresholdInClasses: 11
thresholdInInterfaces: 11
thresholdInObjects: 11
thresholdInEnums: 11
ignoreDeprecated: false
ignorePrivate: false
ignoreOverridden: false
empty-blocks:
active: true
EmptyCatchBlock:
active: true
allowedExceptionNameRegex: "^(_|(ignore|expected).*)"
EmptyClassBlock:
active: true
EmptyDefaultConstructor:
active: true
EmptyDoWhileBlock:
active: true
EmptyElseBlock:
active: true
EmptyFinallyBlock:
active: true
EmptyForBlock:
active: true
EmptyFunctionBlock:
active: false
ignoreOverriddenFunctions: false
EmptyIfBlock:
active: true
EmptyInitBlock:
active: true
EmptyKtFile:
active: true
EmptySecondaryConstructor:
active: true
EmptyWhenBlock:
active: true
EmptyWhileBlock:
active: true
exceptions:
active: true
ExceptionRaisedInUnexpectedLocation:
active: false
methodNames: 'toString,hashCode,equals,finalize'
InstanceOfCheckForException:
active: false
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
NotImplementedDeclaration:
active: false
PrintStackTrace:
active: false
RethrowCaughtException:
active: false
ReturnFromFinally:
active: false
SwallowedException:
active: false
ignoredExceptionTypes: 'InterruptedException,NumberFormatException,ParseException,MalformedURLException'
allowedExceptionNameRegex: "^(_|(ignore|expected).*)"
ThrowingExceptionFromFinally:
active: false
ThrowingExceptionInMain:
active: false
ThrowingExceptionsWithoutMessageOrCause:
active: false
exceptions: 'IllegalArgumentException,IllegalStateException,IOException'
ThrowingNewInstanceOfSameException:
active: false
TooGenericExceptionCaught:
active: true
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
exceptionNames:
- ArrayIndexOutOfBoundsException
- Error
- Exception
- IllegalMonitorStateException
- NullPointerException
- IndexOutOfBoundsException
- RuntimeException
- Throwable
allowedExceptionNameRegex: "^(_|(ignore|expected).*)"
TooGenericExceptionThrown:
active: true
exceptionNames:
- Error
- Exception
- Throwable
- RuntimeException
formatting:
active: true
android: false
autoCorrect: true
AnnotationOnSeparateLine:
active: false
autoCorrect: true
ChainWrapping:
active: true
autoCorrect: true
CommentSpacing:
active: true
autoCorrect: true
Filename:
active: true
FinalNewline:
active: true
autoCorrect: true
ImportOrdering:
active: false
autoCorrect: true
Indentation:
active: false
autoCorrect: true
indentSize: 4
continuationIndentSize: 4
MaximumLineLength:
active: true
maxLineLength: 120
ModifierOrdering:
active: true
autoCorrect: true
MultiLineIfElse:
active: true
autoCorrect: true
NoBlankLineBeforeRbrace:
active: true
autoCorrect: true
NoConsecutiveBlankLines:
active: true
autoCorrect: true
NoEmptyClassBody:
active: true
autoCorrect: true
NoLineBreakAfterElse:
active: true
autoCorrect: true
NoLineBreakBeforeAssignment:
active: true
autoCorrect: true
NoMultipleSpaces:
active: true
autoCorrect: true
NoSemicolons:
active: true
autoCorrect: true
NoTrailingSpaces:
active: true
autoCorrect: true
NoUnitReturn:
active: true
autoCorrect: true
NoUnusedImports:
active: true
autoCorrect: true
NoWildcardImports:
active: true
PackageName:
active: true
autoCorrect: true
ParameterListWrapping:
active: true
autoCorrect: true
indentSize: 4
SpacingAroundColon:
active: true
autoCorrect: true
SpacingAroundComma:
active: true
autoCorrect: true
SpacingAroundCurly:
active: true
autoCorrect: true
SpacingAroundDot:
active: true
autoCorrect: true
SpacingAroundKeyword:
active: true
autoCorrect: true
SpacingAroundOperators:
active: true
autoCorrect: true
SpacingAroundParens:
active: true
autoCorrect: true
SpacingAroundRangeOperator:
active: true
autoCorrect: true
StringTemplate:
active: true
autoCorrect: true
naming:
active: true
ClassNaming:
active: true
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
classPattern: '[A-Z$][a-zA-Z0-9$]*'
ConstructorParameterNaming:
active: true
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
parameterPattern: '[a-z][A-Za-z0-9]*'
privateParameterPattern: '[a-z][A-Za-z0-9]*'
excludeClassPattern: '$^'
EnumNaming:
active: true
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
enumEntryPattern: '^[A-Z][_a-zA-Z0-9]*'
ForbiddenClassName:
active: false
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
forbiddenName: ''
FunctionMaxLength:
active: false
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
maximumFunctionNameLength: 30
FunctionMinLength:
active: false
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
minimumFunctionNameLength: 3
FunctionNaming:
active: true
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
functionPattern: '^([a-z$][a-zA-Z$0-9]*)|(`.*`)$'
excludeClassPattern: '$^'
ignoreOverridden: true
FunctionParameterNaming:
active: true
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
parameterPattern: '[a-z][A-Za-z0-9]*'
excludeClassPattern: '$^'
ignoreOverriddenFunctions: true
InvalidPackageDeclaration:
active: false
rootPackage: ''
MatchingDeclarationName:
active: true
MemberNameEqualsClassName:
active: false
ignoreOverriddenFunction: true
ObjectPropertyNaming:
active: true
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
constantPattern: '[A-Za-z][_A-Za-z0-9]*'
propertyPattern: '[A-Za-z][_A-Za-z0-9]*'
privatePropertyPattern: '(_)?[A-Za-z][_A-Za-z0-9]*'
PackageNaming:
active: true
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
packagePattern: '^[a-z]+(\.[a-z][A-Za-z0-9]*)*$'
TopLevelPropertyNaming:
active: true
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
constantPattern: '[A-Z][_A-Z0-9]*'
propertyPattern: '[A-Za-z][_A-Za-z0-9]*'
privatePropertyPattern: '_?[A-Za-z][_A-Za-z0-9]*'
VariableMaxLength:
active: false
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
maximumVariableNameLength: 64
VariableMinLength:
active: false
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
minimumVariableNameLength: 1
VariableNaming:
active: true
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
variablePattern: '[a-z][A-Za-z0-9]*'
privateVariablePattern: '(_)?[a-z][A-Za-z0-9]*'
excludeClassPattern: '$^'
ignoreOverridden: true
performance:
active: true
ArrayPrimitive:
active: false
ForEachOnRange:
active: true
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
SpreadOperator:
active: true
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
UnnecessaryTemporaryInstantiation:
active: true
potential-bugs:
active: true
DuplicateCaseInWhenExpression:
active: true
EqualsAlwaysReturnsTrueOrFalse:
active: false
EqualsWithHashCodeExist:
active: true
ExplicitGarbageCollectionCall:
active: true
InvalidRange:
active: false
IteratorHasNextCallsNextMethod:
active: false
IteratorNotThrowingNoSuchElementException:
active: false
LateinitUsage:
active: false
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
excludeAnnotatedProperties: ""
ignoreOnClassesPattern: ""
MissingWhenCase:
active: false
RedundantElseInWhen:
active: false
UnconditionalJumpStatementInLoop:
active: false
UnreachableCode:
active: true
UnsafeCallOnNullableType:
active: false
UnsafeCast:
active: false
UselessPostfixExpression:
active: false
WrongEqualsTypeParameter:
active: false
style:
active: true
CollapsibleIfStatements:
active: false
DataClassContainsFunctions:
active: false
conversionFunctionPrefix: 'to'
DataClassShouldBeImmutable:
active: false
EqualsNullCall:
active: false
EqualsOnSignatureLine:
active: false
ExplicitItLambdaParameter:
active: false
ExpressionBodySyntax:
active: false
includeLineWrapping: false
ForbiddenComment:
active: true
values: 'TODO:,FIXME:,STOPSHIP:'
ForbiddenImport:
active: false
imports: ''
ForbiddenVoid:
active: false
ignoreOverridden: false
ignoreUsageInGenerics: false
FunctionOnlyReturningConstant:
active: false
ignoreOverridableFunction: true
excludedFunctions: 'describeContents'
LibraryCodeMustSpecifyReturnType:
active: false
LoopWithTooManyJumpStatements:
active: false
maxJumpCount: 1
MagicNumber:
active: true
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
ignoreNumbers: '-1,0,1,2'
ignoreHashCodeFunction: true
ignorePropertyDeclaration: false
ignoreConstantDeclaration: true
ignoreCompanionObjectPropertyDeclaration: true
ignoreAnnotation: false
ignoreNamedArgument: true
ignoreEnums: false
ignoreRanges: false
MandatoryBracesIfStatements:
active: false
MaxLineLength:
active: true
maxLineLength: 120
excludePackageStatements: true
excludeImportStatements: true
excludeCommentStatements: false
MayBeConst:
active: false
ModifierOrder:
active: true
NestedClassesVisibility:
active: false
NewLineAtEndOfFile:
active: true
NoTabs:
active: false
OptionalAbstractKeyword:
active: true
OptionalUnit:
active: false
OptionalWhenBraces:
active: false
PreferToOverPairSyntax:
active: false
ProtectedMemberInFinalClass:
active: false
RedundantVisibilityModifierRule:
active: false
ReturnCount:
active: true
max: 2
excludedFunctions: "equals"
excludeLabeled: false
excludeReturnFromLambda: true
SafeCast:
active: true
SerialVersionUIDInSerializableClass:
active: false
SpacingBetweenPackageAndImports:
active: false
ThrowsCount:
active: true
max: 2
TrailingWhitespace:
active: false
UnderscoresInNumericLiterals:
active: false
acceptableDecimalLength: 5
UnnecessaryAbstractClass:
active: false
excludeAnnotatedClasses: "dagger.Module"
UnnecessaryApply:
active: false
UnnecessaryInheritance:
active: false
UnnecessaryLet:
active: false
UnnecessaryParentheses:
active: false
UntilInsteadOfRangeTo:
active: false
UnusedImports:
active: false
UnusedPrivateClass:
active: false
UnusedPrivateMember:
active: false
allowedNames: "(_|ignored|expected|serialVersionUID)"
UseCheckOrError:
active: false
UseDataClass:
active: false
excludeAnnotatedClasses: ""
UseRequire:
active: false
UselessCallOnNotNull:
active: false
UtilityClassWithPublicConstructor:
active: false
VarCouldBeVal:
active: false
WildcardImport:
active: true
excludes: "**/test/**,**/androidTest/**,**/*.Test.kt,**/*.Spec.kt,**/*.Spek.kt"
excludeImports: 'java.util.*,kotlinx.android.synthetic.*'
+6
View File
@@ -0,0 +1,6 @@
apply plugin: "io.gitlab.arturbosch.detekt"
detekt {
toolVersion = "1.0.0"
config = files("${rootDir}/default-detekt-config.yml")
}
+83
View File
@@ -0,0 +1,83 @@
[![Kotlin Version](https://img.shields.io/badge/kotlin-1.3.50-blue.svg)](https://kotlinlang.org)
[![API](https://img.shields.io/badge/API-16%2B-brightgreen.svg?style=flat)](https://android-arsenal.com/api?level=16)
[![CodeFactor](https://www.codefactor.io/repository/github/diogobernardino/williamchart/badge)](https://www.codefactor.io/repository/github/diogobernardino/williamchart)
Williamchart is an Android Library to rapidly implement attractive and insightful charts in android applications.
### Gradle
``` groovy
implementation 'com.diogobernardino:williamchart:3.2.0'
```
If you find this library useful and decide to use it in your projects please drop me a line [@dfbernardino][1], I will be happy to know about it.
### Usage
#### All charts
```xml
<com.db.williamchart.view.chart_view
...
app:chart_labelsColor="color"
app:chart_labelsSize="dimension"
app:chart_labelsFont="font"
/>
```
#### Line Chart
```xml
<com.db.williamchart.view.LinechartView
...
app:chart_lineColor="color"
app:chart_lineThickness="dimension"
app:chart_smoothLine=[ "true" | "false" ]
app:chart_pointDrawable="drawable"
/>
```
#### Bar Chart
```xml
<com.db.williamchart.view.BarChartView|HorizontalBarChartView
...
app:chart_spacing="dimension"
app:chart_barsColor="color"
app:chart_barsBackgroundColor="color"
app:chart_barsRadius="dimension"
/>
```
#### Donut Chart
```xml
<com.db.williamchart.view.DonutChartView
...
app:chart_donutThickness="dimension"
app:chart_donutColor="color"
app:chart_donutBackgroundColor="color"
app:chart_donutRoundCorners="boolean"
app:chart_donutTotal="float"
/>
```
License
-------
Copyright 2019 Diogo Bernardino
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
[1]: https://twitter.com/dfbernardino
+1
View File
@@ -0,0 +1 @@
theme: jekyll-theme-minimal
+15
View File
@@ -0,0 +1,15 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
android.enableJetifier=true
android.useAndroidX=true
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
Binary file not shown.
+6
View File
@@ -0,0 +1,6 @@
#Thu Jul 25 22:06:29 CST 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
+172
View File
@@ -0,0 +1,172 @@
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"
+84
View File
@@ -0,0 +1,84 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
+7
View File
@@ -0,0 +1,7 @@
junitJacoco {
jacocoVersion = '0.8.2' // type String
ignoreProjects = [] // type String array
excludes // type String List
includeNoLocationClasses = false // type boolean
includeInstrumentationCoverageInMergedReport = false // type boolean
}
+21
View File
@@ -0,0 +1,21 @@
configurations {
ktlint
}
dependencies {
ktlint 'com.pinterest:ktlint:0.35.0'
}
task ktlint(type: JavaExec, group: "verification") {
description = "Check Kotlin code style."
classpath = configurations.ktlint
main = "com.pinterest.ktlint.Main"
args "src/**/*.kt"
}
task ktlintFormat(type: JavaExec, group: "formatting") {
description = "Fix Kotlin code style deviations."
classpath = configurations.ktlint
main = "com.pinterest.ktlint.Main"
args "-F", "src/**/*.kt"
}
+1
View File
@@ -0,0 +1 @@
/build
+67
View File
@@ -0,0 +1,67 @@
plugins {
id("com.android.application")
id("com.github.triplet.play") version "2.0.0"
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'com.github.triplet.play'
Properties properties = new Properties()
File localPropertiesFiles = project.rootProject.file('local.properties')
if (localPropertiesFiles.exists())
properties.load(localPropertiesFiles.newDataInputStream())
android {
compileSdkVersion rootProject.targetSdkVersion
defaultConfig {
applicationId "com.db.williamchartdemo"
minSdkVersion rootProject.minSdkVersion
targetSdkVersion rootProject.targetSdkVersion
versionCode 20
versionName rootProject.williamchartVersion
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
if (localPropertiesFiles.exists()) {
signingConfigs {
release {
// storeFile file(properties.getProperty("storeFile"))
// storePassword properties.getProperty("storePassword")
// keyAlias properties.getProperty("keyAlias")
// keyPassword properties.getProperty("keyPassword")
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
if (localPropertiesFiles.exists())
signingConfig signingConfigs.release
}
}
}
dependencies {
implementation project(path: ':williamchart')
implementation project(path: ':slidertooltip')
//implementation "com.diogobernardino:williamchart:$rootProject.williamchartVersion"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$rootProject.kotlinVersion"
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.2.1'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
testImplementation 'junit:junit:4.13.1'
androidTestImplementation 'androidx.test:runner:1.3.0'
}
play {
serviceAccountEmail = properties.containsKey("play.accountEmail") ? properties.getProperty("play.accountEmail") : "dummyPlayAccountEmail"
serviceAccountCredentials = file(properties.containsKey("play.p12") ? properties.getProperty("play.p12") : "dummyPlayP12")
track = 'alpha'
}
+21
View File
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.db.williamchartdemo">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name="com.db.williamchartdemo.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<meta-data android:name="preloaded_fonts" android:resource="@array/preloaded_fonts"/>
</application>
</manifest>
@@ -0,0 +1,108 @@
package com.db.williamchartdemo
import android.graphics.Color
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.db.williamchart.ExperimentalFeature
import com.db.williamchart.slidertooltip.SliderTooltip
import kotlinx.android.synthetic.main.demo_fragment.*
class DemoFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.demo_fragment, container, false)
@OptIn(ExperimentalFeature::class)
override fun onViewCreated(view: View, saveInstanceState: Bundle?) {
/**
* Line Chart
*/
lineChart.gradientFillColors =
intArrayOf(
Color.parseColor("#81FFFFFF"),
Color.TRANSPARENT
)
lineChart.animation.duration = animationDuration
lineChart.tooltip =
SliderTooltip().also {
it.color = Color.WHITE
}
lineChart.onDataPointTouchListener = { index, _, _ ->
lineChartValue.text =
lineSet.toList()[index]
.second
.toString()
}
lineChart.animate(lineSet)
/**
* Bar Chart
*/
barChart.animation.duration = animationDuration
barChart.animate(barSet)
/**
* Donut Chart
*/
donutChart.donutColors = intArrayOf(
Color.parseColor("#FFFFFF"),
Color.parseColor("#9EFFFFFF"),
Color.parseColor("#8DFFFFFF")
)
donutChart.animation.duration = animationDuration
donutChart.animate(donutSet)
/**
* Horizontal Bar Chart
*/
horizontalBarChart.animation.duration = animationDuration
horizontalBarChart.animate(horizontalBarSet)
}
companion object {
private val lineSet = listOf(
"label1" to 5f,
"label2" to 4.5f,
"label3" to 4.7f,
"label4" to 3.5f,
"label5" to 3.6f,
"label6" to 7.5f,
"label7" to 7.5f,
"label8" to 10f,
"label9" to 5f,
"label10" to 6.5f,
"label11" to 3f,
"label12" to 4f
)
private val barSet = listOf(
"JAN" to 4F,
"FEB" to 7F,
"MAR" to 2F,
"MAY" to 2.3F,
"APR" to 5F,
"JUN" to 4F
)
private val horizontalBarSet = listOf(
"PORRO" to 5F,
"FUSCE" to 6.4F,
"EGET" to 3F
)
private val donutSet = listOf(
20f,
80f,
100f
)
private const val animationDuration = 1000L
}
}
@@ -0,0 +1,12 @@
package com.db.williamchartdemo
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
@@ -0,0 +1,34 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillType="evenOdd"
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
android:strokeColor="#00000000"
android:strokeWidth="1">
<aapt:attr name="android:fillColor">
<gradient
android:endX="78.5885"
android:endY="90.9159"
android:startX="48.7653"
android:startY="61.0927"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
android:strokeColor="#00000000"
android:strokeWidth="1" />
</vector>
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M19,3L5,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2zM9,17L7,17v-7h2v7zM13,17h-2L11,7h2v10zM17,17h-2v-4h2v4z"/>
</vector>
@@ -0,0 +1,170 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillColor="#26A69A"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
</vector>
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M3.5,18.49l6,-6.01 4,4L22,6.92l-1.41,-1.41 -7.09,7.97 -4,-4L2,16.99z"/>
</vector>
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<gradient
android:startColor="#A4C8B1"
android:endColor="#85B496"
android:angle="0"/>
</shape>
</item>
</layer-list>
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#E1FFFFFF"/>
<corners android:radius="30dp"/>
<padding android:left="0dp" android:top="0dp" android:right="0dp" android:bottom="0dp"/>
</shape>
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:app="http://schemas.android.com/apk/res-auto"
app:fontProviderAuthority="com.google.android.gms.fonts"
app:fontProviderPackage="com.google.android.gms"
app:fontProviderQuery="name=Istok Web&amp;weight=700"
app:fontProviderCerts="@array/com_google_android_gms_fonts_certs">
</font-family>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<font-family
xmlns:app="http://schemas.android.com/apk/res-auto"
app:fontProviderAuthority="com.google.android.gms.fonts"
app:fontProviderPackage="com.google.android.gms"
app:fontProviderQuery="Supermercado One"
app:fontProviderCerts="@array/com_google_android_gms_fonts_certs">
</font-family>
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<fragment
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/contentFrame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.db.williamchartdemo.DemoFragment"/>
@@ -0,0 +1,153 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/layout_background"
android:paddingLeft="20dp"
android:paddingRight="20dp">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/backgroundGuideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.07" />
<TextView
android:id="@+id/appLogo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="25dp"
android:layout_marginBottom="20dp"
android:fontFamily="@font/supermercado_one"
android:text="williamchart"
android:textColor="@android:color/white"
android:textSize="35sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/lineChartTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/open_sans_bold"
android:text="Lorem"
android:textColor="#475F50"
android:textSize="20sp"
app:layout_constraintBottom_toTopOf="@id/lineChart"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="@id/backgroundGuideline" />
<com.db.williamchart.view.LineChartView
android:id="@+id/lineChart"
android:layout_width="0dp"
android:layout_height="70dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
app:chart_axis="none"
app:chart_gridEffect="dotted"
app:chart_labelsColor="#FF70977F"
app:chart_labelsFont="@font/open_sans_bold"
app:chart_labelsSize="10sp"
app:chart_lineColor="#ffffff"
app:chart_lineThickness="3dp"
app:chart_smoothLine="true"
app:layout_constraintBottom_toTopOf="@id/lineChartValue"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/lineChartTitle" />
<TextView
android:id="@+id/lineChartValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginLeft="20dp"
android:fontFamily="@font/open_sans_bold"
android:text="320"
android:textColor="#FF70977F"
android:textSize="24sp"
app:layout_constraintBottom_toTopOf="@id/barChartTitle"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/lineChart" />
<TextView
android:id="@+id/lineChartUnits"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginLeft="5dp"
android:fontFamily="@font/open_sans_bold"
android:text="stinu"
android:textColor="#FF70977F"
android:textSize="17sp"
app:layout_constraintBaseline_toBaselineOf="@id/lineChartValue"
app:layout_constraintLeft_toRightOf="@id/lineChartValue"
app:layout_constraintTop_toTopOf="@id/lineChartValue" />
<TextView
android:id="@+id/barChartTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/open_sans_bold"
android:text="Ipsum Dolor"
android:textColor="#475F50"
android:textSize="20sp"
app:layout_constraintBottom_toTopOf="@id/barChart"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/lineChartValue" />
<com.db.williamchart.view.BarChartView
android:id="@+id/barChart"
android:layout_width="0dp"
android:layout_height="150dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
app:chart_axis="x"
app:chart_barsColor="#fff"
app:chart_barsRadius="4dp"
app:chart_labelsColor="#FF70977F"
app:chart_labelsFont="@font/open_sans_bold"
app:chart_labelsSize="10sp"
app:chart_spacing="15dp"
app:layout_constraintBottom_toTopOf="@id/horizontalBarChart"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/donutChart"
app:layout_constraintTop_toBottomOf="@id/barChartTitle" />
<com.db.williamchart.view.DonutChartView
android:id="@+id/donutChart"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
app:chart_donutBackgroundColor="#70977F"
app:chart_donutRoundCorners="true"
app:chart_donutThickness="15dp"
app:chart_donutTotal="200"
app:layout_constraintBottom_toBottomOf="@id/barChart"
app:layout_constraintLeft_toRightOf="@id/barChart"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@id/barChart" />
<com.db.williamchart.view.HorizontalBarChartView
android:id="@+id/horizontalBarChart"
android:layout_width="0dp"
android:layout_height="120dp"
android:layout_marginEnd="20dp"
android:layout_marginRight="20dp"
app:chart_axis="y"
app:chart_barsColor="#fff"
app:chart_barsRadius="6dp"
app:chart_labelsColor="#475F50"
app:chart_labelsFont="@font/open_sans_bold"
app:chart_labelsSize="15sp"
app:chart_spacing="20dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/barChart" />
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 947 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 705 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#475F50</color>
<color name="colorAccent">#FF4081</color>
</resources>
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<array name="com_google_android_gms_fonts_certs">
<item>@array/com_google_android_gms_fonts_certs_dev</item>
<item>@array/com_google_android_gms_fonts_certs_prod</item>
</array>
<string-array name="com_google_android_gms_fonts_certs_dev">
<item>
MIIEqDCCA5CgAwIBAgIJANWFuGx90071MA0GCSqGSIb3DQEBBAUAMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTAeFw0wODA0MTUyMzM2NTZaFw0zNTA5MDEyMzM2NTZaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTCCASAwDQYJKoZIhvcNAQEBBQADggENADCCAQgCggEBANbOLggKv+IxTdGNs8/TGFy0PTP6DHThvbbR24kT9ixcOd9W+EaBPWW+wPPKQmsHxajtWjmQwWfna8mZuSeJS48LIgAZlKkpFeVyxW0qMBujb8X8ETrWy550NaFtI6t9+u7hZeTfHwqNvacKhp1RbE6dBRGWynwMVX8XW8N1+UjFaq6GCJukT4qmpN2afb8sCjUigq0GuMwYXrFVee74bQgLHWGJwPmvmLHC69EH6kWr22ijx4OKXlSIx2xT1AsSHee70w5iDBiK4aph27yH3TxkXy9V89TDdexAcKk/cVHYNnDBapcavl7y0RiQ4biu8ymM8Ga/nmzhRKya6G0cGw8CAQOjgfwwgfkwHQYDVR0OBBYEFI0cxb6VTEM8YYY6FbBMvAPyT+CyMIHJBgNVHSMEgcEwgb6AFI0cxb6VTEM8YYY6FbBMvAPyT+CyoYGapIGXMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbYIJANWFuGx90071MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADggEBABnTDPEF+3iSP0wNfdIjIz1AlnrPzgAIHVvXxunW7SBrDhEglQZBbKJEk5kT0mtKoOD1JMrSu1xuTKEBahWRbqHsXclaXjoBADb0kkjVEJu/Lh5hgYZnOjvlba8Ld7HCKePCVePoTJBdI4fvugnL8TsgK05aIskyY0hKI9L8KfqfGTl1lzOv2KoWD0KWwtAWPoGChZxmQ+nBli+gwYMzM1vAkP+aayLe0a1EQimlOalO762r0GXO0ks+UeXde2Z4e+8S/pf7pITEI/tP+MxJTALw9QUWEv9lKTk+jkbqxbsh8nfBUapfKqYn0eidpwq2AzVp3juYl7//fKnaPhJD9gs=
</item>
</string-array>
<string-array name="com_google_android_gms_fonts_certs_prod">
<item>
MIIEQzCCAyugAwIBAgIJAMLgh0ZkSjCNMA0GCSqGSIb3DQEBBAUAMHQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtHb29nbGUgSW5jLjEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDAeFw0wODA4MjEyMzEzMzRaFw0zNjAxMDcyMzEzMzRaMHQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtHb29nbGUgSW5jLjEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDCCASAwDQYJKoZIhvcNAQEBBQADggENADCCAQgCggEBAKtWLgDYO6IIrgqWbxJOKdoR8qtW0I9Y4sypEwPpt1TTcvZApxsdyxMJZ2JORland2qSGT2y5b+3JKkedxiLDmpHpDsz2WCbdxgxRczfey5YZnTJ4VZbH0xqWVW/8lGmPav5xVwnIiJS6HXk+BVKZF+JcWjAsb/GEuq/eFdpuzSqeYTcfi6idkyugwfYwXFU1+5fZKUaRKYCwkkFQVfcAs1fXA5V+++FGfvjJ/CxURaSxaBvGdGDhfXE28LWuT9ozCl5xw4Yq5OGazvV24mZVSoOO0yZ31j7kYvtwYK6NeADwbSxDdJEqO4k//0zOHKrUiGYXtqw/A0LFFtqoZKFjnkCAQOjgdkwgdYwHQYDVR0OBBYEFMd9jMIhF1Ylmn/Tgt9r45jk14alMIGmBgNVHSMEgZ4wgZuAFMd9jMIhF1Ylmn/Tgt9r45jk14aloXikdjB0MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLR29vZ2xlIEluYy4xEDAOBgNVBAsTB0FuZHJvaWQxEDAOBgNVBAMTB0FuZHJvaWSCCQDC4IdGZEowjTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBAUAA4IBAQBt0lLO74UwLDYKqs6Tm8/yzKkEu116FmH4rkaymUIE0P9KaMftGlMexFlaYjzmB2OxZyl6euNXEsQH8gjwyxCUKRJNexBiGcCEyj6z+a1fuHHvkiaai+KL8W1EyNmgjmyy8AW7P+LLlkR+ho5zEHatRbM/YAnqGcFh5iZBqpknHf1SKMXFh4dd239FJ1jWYfbMDMy3NS5CTMQ2XFI1MvcyUTdZPErjQfTbQe3aDQsQcafEQPD+nqActifKZ0Np0IS9L9kR/wbNvyz6ENwPiTrjV2KRkEjH78ZMcUQXg0L3BYHJ3lc69Vs5Ddf9uUGGMYldX3WfMBEmh/9iFBDAaTCK
</item>
</string-array>
</resources>
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#85B496</color>
</resources>
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<array name="preloaded_fonts" translatable="false">
<item>@font/istok_web_bold</item>
<item>@font/supermercado_one</item>
</array>
</resources>
@@ -0,0 +1,3 @@
<resources>
<string name="app_name">williamchart</string>
</resources>
@@ -0,0 +1,11 @@
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>
+1
View File
@@ -0,0 +1 @@
/build
+27
View File
@@ -0,0 +1,27 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
android {
compileSdkVersion rootProject.targetSdkVersion
buildToolsVersion "29.0.3"
defaultConfig {
minSdkVersion rootProject.minSdkVersion
targetSdkVersion rootProject.targetSdkVersion
versionCode 1
versionName rootProject.williamchartVersion
}
buildTypes {
release {
minifyEnabled false
}
}
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$rootProject.kotlinVersion"
implementation project(path: ':williamchart')
}
apply from: 'publish.gradle'
+62
View File
@@ -0,0 +1,62 @@
apply plugin: 'maven-publish'
apply plugin: 'com.jfrog.bintray'
version rootProject.williamchartVersion
group 'com.diogobernardino.williamchart'
task sourcesJar(type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
}
publishing {
publications {
Production(MavenPublication) {
artifact("$buildDir/outputs/aar/pointstooltip-release.aar")
artifact sourcesJar
groupId this.group
artifactId 'tooltip-points'
version this.version
pom.withXml {
def dependenciesNode = asNode().appendNode('dependencies')
configurations.implementation.allDependencies.each {
if (it.name != 'unspecified') {
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', it.group)
dependencyNode.appendNode('artifactId', it.name)
dependencyNode.appendNode('version', it.version)
}
}
}
}
}
}
bintray {
Properties properties = new Properties()
File localPropertiesFiles = project.rootProject.file('local.properties')
if (localPropertiesFiles.exists())
properties.load(localPropertiesFiles.newDataInputStream())
user = properties.containsKey('bintrayUser') ? properties.getProperty('bintrayUser') : System.getenv('BINTRAY_USER')
key = properties.containsKey('bintrayApiKey') ? properties.getProperty('bintrayApiKey') : System.getenv('BINTRAY_API_KEY')
publications = ['Production']
configurations = ['archives']
// Default: false. Whether to run this as dry-run, without deploying
dryRun = false
// Default: false. Whether to override version artifacts already published
override = false
// Default: false. Whether version should be auto published after an upload
publish = true
pkg {
repo = 'maven' // the name of the repository you created on Bintray
name = 'com.diogobernardino.williamchart:tooltip-points'
// the name of the package you created inside it
version {
name = this.version
released = new Date()
vcsTag = this.version
}
}
}
@@ -0,0 +1 @@
<manifest package="com.db.williamchart.pointtooltip" />
@@ -0,0 +1,35 @@
package com.db.williamchart.pointtooltip
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import com.db.williamchart.Tooltip
class PointTooltip : Tooltip {
private lateinit var tooltipView: View
@Suppress("MemberVisibilityCanBePrivate")
var drawableRes = R.drawable.circle_point
override fun onCreateTooltip(parentView: ViewGroup) {
tooltipView =
LayoutInflater.from(parentView.context)
.inflate(R.layout.point_tooltip_layout, parentView, false)
tooltipView.visibility = View.INVISIBLE
val imageView: ImageView = tooltipView.findViewById(R.id.tooltipImage)
imageView.setImageResource(drawableRes)
parentView.addView(tooltipView)
}
override fun onDataPointTouch(x: Float, y: Float) {}
override fun onDataPointClick(x: Float, y: Float) {
tooltipView.visibility = View.VISIBLE
tooltipView.x = x - tooltipView.width / 2
tooltipView.y = y - tooltipView.height / 2
}
}
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="#000" />
<size
android:width="10dp"
android:height="10dp" />
</shape>
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/tooltipImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:ignore="ContentDescription" />
+1
View File
@@ -0,0 +1 @@
include ':mobile', ':williamchart', ':slidertooltip', ':pointstooltip'
+1
View File
@@ -0,0 +1 @@
/build
+27
View File
@@ -0,0 +1,27 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
android {
compileSdkVersion rootProject.targetSdkVersion
buildToolsVersion "29.0.3"
defaultConfig {
minSdkVersion rootProject.minSdkVersion
targetSdkVersion rootProject.targetSdkVersion
versionCode 1
versionName rootProject.williamchartVersion
}
buildTypes {
release {
minifyEnabled false
}
}
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$rootProject.kotlinVersion"
implementation project(path: ':williamchart')
}
apply from: 'publish.gradle'
+62
View File
@@ -0,0 +1,62 @@
apply plugin: 'maven-publish'
apply plugin: 'com.jfrog.bintray'
version rootProject.williamchartVersion
group 'com.diogobernardino.williamchart'
task sourcesJar(type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
}
publishing {
publications {
Production(MavenPublication) {
artifact("$buildDir/outputs/aar/slidertooltip-release.aar")
artifact sourcesJar
groupId this.group
artifactId 'tooltip-slider'
version this.version
pom.withXml {
def dependenciesNode = asNode().appendNode('dependencies')
configurations.implementation.allDependencies.each {
if (it.name != 'unspecified') {
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', it.group)
dependencyNode.appendNode('artifactId', it.name)
dependencyNode.appendNode('version', it.version)
}
}
}
}
}
}
bintray {
Properties properties = new Properties()
File localPropertiesFiles = project.rootProject.file('local.properties')
if (localPropertiesFiles.exists())
properties.load(localPropertiesFiles.newDataInputStream())
user = properties.containsKey('bintrayUser') ? properties.getProperty('bintrayUser') : System.getenv('BINTRAY_USER')
key = properties.containsKey('bintrayApiKey') ? properties.getProperty('bintrayApiKey') : System.getenv('BINTRAY_API_KEY')
publications = ['Production']
configurations = ['archives']
// Default: false. Whether to run this as dry-run, without deploying
dryRun = false
// Default: false. Whether to override version artifacts already published
override = false
// Default: false. Whether version should be auto published after an upload
publish = true
pkg {
repo = 'maven' // the name of the repository you created on Bintray
name = 'com.diogobernardino.williamchart:tooltip-slider'
// the name of the package you created inside it
version {
name = this.version
released = new Date()
vcsTag = this.version
}
}
}
@@ -0,0 +1 @@
<manifest package="com.db.williamchart.slidertooltip" />
@@ -0,0 +1,32 @@
package com.db.williamchart.slidertooltip
import android.graphics.Color
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.db.williamchart.ExperimentalFeature
import com.db.williamchart.Tooltip
@ExperimentalFeature
class SliderTooltip : Tooltip {
private lateinit var tooltipView: View
var color = Color.BLACK
override fun onCreateTooltip(parentView: ViewGroup) {
tooltipView =
LayoutInflater.from(parentView.context)
.inflate(R.layout.tooltip_layout, parentView, false)
tooltipView.setBackgroundColor(color)
tooltipView.visibility = View.INVISIBLE
parentView.addView(tooltipView)
}
override fun onDataPointTouch(x: Float, y: Float) {
tooltipView.visibility = View.VISIBLE
tooltipView.x = x - tooltipView.width / 2
}
override fun onDataPointClick(x: Float, y: Float) {}
}
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<View xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="2dp"
android:layout_height="match_parent" />
+1
View File
@@ -0,0 +1 @@
/build
+36
View File
@@ -0,0 +1,36 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
android {
kotlinOptions {
jvmTarget = "1.8"
}
compileSdkVersion rootProject.targetSdkVersion
defaultConfig {
minSdkVersion rootProject.minSdkVersion
targetSdkVersion rootProject.targetSdkVersion
versionCode 1
versionName rootProject.williamchartVersion
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.core:core-ktx:1.3.2'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$rootProject.kotlinVersion"
testImplementation 'junit:junit:4.13.1'
testImplementation "org.mockito:mockito-core:3.3.3"
testImplementation "com.nhaarman:mockito-kotlin:1.6.0"
}
apply from: 'publish.gradle'
+21
View File
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
+55
View File
@@ -0,0 +1,55 @@
apply plugin: 'maven-publish'
apply plugin: 'com.jfrog.bintray'
version rootProject.williamchartVersion
group 'com.diogobernardino'
publishing {
publications {
Production(MavenPublication) {
artifact("$buildDir/outputs/aar/williamchart-release.aar")
groupId this.group
artifactId 'williamchart'
version this.version
pom.withXml {
def dependenciesNode = asNode().appendNode('dependencies')
configurations.implementation.allDependencies.each {
if (it.name != 'unspecified') {
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', it.group)
dependencyNode.appendNode('artifactId', it.name)
dependencyNode.appendNode('version', it.version)
}
}
}
}
}
}
bintray {
Properties properties = new Properties()
File localPropertiesFiles = project.rootProject.file('local.properties')
if (localPropertiesFiles.exists())
properties.load(localPropertiesFiles.newDataInputStream())
user = properties.containsKey('bintrayUser') ? properties.getProperty('bintrayUser') : System.getenv('BINTRAY_USER')
key = properties.containsKey('bintrayApiKey') ? properties.getProperty('bintrayApiKey') : System.getenv('BINTRAY_API_KEY')
publications = ['Production']
configurations = ['archives']
// Default: false. Whether to run this as dry-run, without deploying
dryRun = false
// Default: false. Whether to override version artifacts already published
override = false
// Default: false. Whether version should be auto published after an upload
publish = true
pkg {
repo = 'maven' // the name of the repository you created on Bintray
name = 'com.diogobernardino:williamchart' // the name of the package you created inside it
version {
name = this.version
released = new Date()
vcsTag = this.version
}
}
}
@@ -0,0 +1 @@
<manifest package="com.db.williamchart" />
@@ -0,0 +1,58 @@
package com.db.williamchart
import com.db.williamchart.animation.ChartAnimation
import com.db.williamchart.data.configuration.ChartConfiguration
import com.db.williamchart.data.DataPoint
import com.db.williamchart.data.configuration.DonutChartConfiguration
import com.db.williamchart.data.DonutDataPoint
import com.db.williamchart.data.Frame
import com.db.williamchart.data.Label
interface ChartContract {
interface AxisView {
fun postInvalidate()
fun drawLabels(xLabels: List<Label>)
fun drawGrid(
innerFrame: Frame,
xLabelsPositions: List<Float>,
yLabelsPositions: List<Float>
)
fun drawDebugFrame(frames: List<Frame>)
}
interface LineView : AxisView {
fun drawLine(points: List<DataPoint>)
fun drawLineBackground(innerFrame: Frame, points: List<DataPoint>)
fun drawPoints(points: List<DataPoint>)
}
interface BarView : AxisView {
fun drawBars(frames: List<Frame>)
fun drawBarsBackground(frames: List<Frame>)
}
interface DonutView {
fun postInvalidate()
fun drawArc(degrees: List<Float>, innerFrame: Frame)
fun drawBackground(innerFrame: Frame)
fun drawDebugFrame(innerFrame: Frame)
}
interface Renderer {
fun preDraw(configuration: ChartConfiguration): Boolean
fun draw()
fun render(entries: List<Pair<String, Float>>)
fun anim(entries: List<Pair<String, Float>>, animation: ChartAnimation<DataPoint>)
fun processClick(x: Float?, y: Float?): Triple<Int, Float, Float>
fun processTouch(x: Float?, y: Float?): Triple<Int, Float, Float>
}
interface DonutRenderer {
fun preDraw(configuration: DonutChartConfiguration): Boolean
fun draw()
fun render(values: List<Float>)
fun anim(values: List<Float>, animation: ChartAnimation<DonutDataPoint>)
}
}
@@ -0,0 +1,9 @@
package com.db.williamchart
@RequiresOptIn(
level = RequiresOptIn.Level.WARNING,
message = "This feature is experimental and it can change in future."
)
@Retention(AnnotationRetention.BINARY)
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.CLASS)
annotation class ExperimentalFeature
@@ -0,0 +1,13 @@
package com.db.williamchart
import android.graphics.Canvas
import com.db.williamchart.data.Frame
interface Grid {
fun draw(
canvas: Canvas,
innerFrame: Frame,
xLabelsPositions: List<Float>,
yLabelsPositions: List<Float>
)
}
@@ -0,0 +1,9 @@
package com.db.williamchart
import android.graphics.Canvas
import android.graphics.Paint
import com.db.williamchart.data.Label
interface Labels {
fun draw(canvas: Canvas, paint: Paint, xLabels: List<Label>)
}
@@ -0,0 +1,82 @@
package com.db.williamchart
import android.graphics.Paint
import android.graphics.Shader
import android.graphics.Typeface
/**
* The Paint class holds the paint object used to draw charts
* and provides methods to speed up its customization before drawing.
*/
class Painter(
val paint: Paint = Paint(),
var labelsFont: Typeface?
) {
init {
paint.textAlign = Paint.Align.CENTER
}
/**
* Measure text width given a certain font size.
*
* @param text text to be measured.
* @param textSize size used in font.
* @return width of the text.
*/
fun measureLabelWidth(text: String, textSize: Float): Float {
paint.typeface = labelsFont
paint.textSize = textSize
return paint.measureText(text)
}
/**
* Measure the maximum text height for a given font size.
*
* @param textSize size used in font.
* @return height of the text.
*/
fun measureLabelHeight(textSize: Float): Float {
paint.textSize = textSize
return paint.descent() - paint.ascent()
}
fun measureLabelAscent(textSize: Float): Float {
paint.textSize = textSize
return paint.ascent()
}
fun measureLabelDescent(textSize: Float): Float {
paint.textSize = textSize
return paint.descent()
}
/**
* Prepares a Paint object already configured to be used.
*
* @param textSize new font size to set in the paint.
* @param color new color (including alpha) to set in the paint.
* @param style new style to set in the paint.
* @param strokeWidth new stroke width, used when style is Stroke or StrokeAndFill.
* @param shader May be null. New shader to be set in the paint.
* @param typeface May be null. New Typeface to be set in the paint.
* @return Configured Paint object.
*/
fun prepare(
textSize: Float = 15F,
color: Int = -0x1000000,
style: Paint.Style = Paint.Style.FILL,
strokeWidth: Float = 4F,
shader: Shader? = null,
font: Typeface? = null
): Paint {
paint.textSize = textSize
paint.color = color
paint.style = style
paint.strokeWidth = strokeWidth
paint.shader = shader
paint.typeface = font
return paint
}
}
@@ -0,0 +1,9 @@
package com.db.williamchart
import android.view.ViewGroup
interface Tooltip {
fun onCreateTooltip(parentView: ViewGroup)
fun onDataPointTouch(x: Float, y: Float)
fun onDataPointClick(x: Float, y: Float)
}
@@ -0,0 +1,20 @@
package com.db.williamchart.animation
import android.view.animation.DecelerateInterpolator
import android.view.animation.Interpolator
abstract class ChartAnimation<T> {
var duration: Long = DEFAULT_DURATION
var interpolator: Interpolator = DecelerateInterpolator()
abstract fun animateFrom(
startPosition: Float,
entries: List<T>,
callback: () -> Unit
): ChartAnimation<T>
companion object {
private const val DEFAULT_DURATION = 1000L
}
}
@@ -0,0 +1,38 @@
package com.db.williamchart.animation
import android.animation.ObjectAnimator
import android.animation.ValueAnimator
import com.db.williamchart.data.DataPoint
class DefaultAnimation : ChartAnimation<DataPoint>() {
override fun animateFrom(
startPosition: Float,
entries: List<DataPoint>,
callback: () -> Unit
): ChartAnimation<DataPoint> {
// Entries animators
entries.forEach { dataPoint ->
val eAnimator: ObjectAnimator =
ObjectAnimator.ofFloat(
dataPoint,
"screenPositionY",
startPosition,
dataPoint.screenPositionY
)
eAnimator.duration = duration
eAnimator.interpolator = interpolator
eAnimator.start()
}
// Global animator
val animator: ValueAnimator = ValueAnimator.ofInt(0, 1)
animator.addUpdateListener { callback.invoke() }
animator.duration = duration
animator.interpolator = interpolator
animator.start()
return this
}
}
@@ -0,0 +1,33 @@
package com.db.williamchart.animation
import android.animation.ObjectAnimator
import android.animation.ValueAnimator
import com.db.williamchart.data.DonutDataPoint
class DefaultDonutAnimation : ChartAnimation<DonutDataPoint>() {
override fun animateFrom(
startPosition: Float,
entries: List<DonutDataPoint>,
callback: () -> Unit
): ChartAnimation<DonutDataPoint> {
// Entries animators
entries.forEach { dataPoint ->
val eAnimator: ObjectAnimator =
ObjectAnimator.ofFloat(dataPoint, "screenDegrees", 0f, dataPoint.screenDegrees)
eAnimator.duration = duration
eAnimator.interpolator = interpolator
eAnimator.start()
}
// Global animator
val animator: ValueAnimator = ValueAnimator.ofInt(0, 1)
animator.addUpdateListener { callback.invoke() }
animator.duration = duration
animator.interpolator = interpolator
animator.start()
return this
}
}
@@ -0,0 +1,33 @@
package com.db.williamchart.animation
import android.animation.ObjectAnimator
import android.animation.ValueAnimator
import com.db.williamchart.data.DataPoint
class DefaultHorizontalAnimation : ChartAnimation<DataPoint>() {
override fun animateFrom(
startPosition: Float,
entries: List<DataPoint>,
callback: () -> Unit
): ChartAnimation<DataPoint> {
// Entries animators
entries.forEach { dataPoint ->
val eAnimator: ObjectAnimator =
ObjectAnimator.ofFloat(dataPoint, "screenPositionX", startPosition, dataPoint.screenPositionX)
eAnimator.duration = duration
eAnimator.interpolator = interpolator
eAnimator.start()
}
// Global animator
val animator: ValueAnimator = ValueAnimator.ofInt(0, 1)
animator.addUpdateListener { callback.invoke() }
animator.duration = duration
animator.interpolator = interpolator
animator.start()
return this
}
}
@@ -0,0 +1,12 @@
package com.db.williamchart.animation
import com.db.williamchart.data.DonutDataPoint
class DonutNoAnimation : ChartAnimation<DonutDataPoint>() {
override fun animateFrom(
startPosition: Float,
entries: List<DonutDataPoint>,
callback: () -> Unit
): ChartAnimation<DonutDataPoint> = this
}
@@ -0,0 +1,12 @@
package com.db.williamchart.animation
import com.db.williamchart.data.DataPoint
class NoAnimation : ChartAnimation<DataPoint>() {
override fun animateFrom(
startPosition: Float,
entries: List<DataPoint>,
callback: () -> Unit
): ChartAnimation<DataPoint> = this
}
@@ -0,0 +1,16 @@
package com.db.williamchart.data
enum class AxisType {
NONE, // No axis
X, // Only axis X
Y, // Only axis Y
XY // All axis
}
fun AxisType.shouldDisplayAxisX(): Boolean {
return this == AxisType.XY || this == AxisType.X
}
fun AxisType.shouldDisplayAxisY(): Boolean {
return this == AxisType.XY || this == AxisType.Y
}
@@ -0,0 +1,8 @@
package com.db.williamchart.data
data class DataPoint(
val label: String,
val value: Float,
var screenPositionX: Float = 0f,
var screenPositionY: Float = 0f
)
@@ -0,0 +1,6 @@
package com.db.williamchart.data
data class DonutDataPoint(
val value: Float,
var screenDegrees: Float = 0f
)
@@ -0,0 +1,38 @@
package com.db.williamchart.data
import android.graphics.LinearGradient
import android.graphics.Rect
import android.graphics.RectF
import android.graphics.Shader
import androidx.core.graphics.toRectF
data class Frame(val left: Float, val top: Float, val right: Float, val bottom: Float)
fun Frame.toRect(): Rect =
Rect(this.left.toInt(), this.top.toInt(), this.right.toInt(), this.bottom.toInt())
fun Frame.toRectF(): RectF = toRect().toRectF()
fun Frame.withPaddings(paddings: Paddings): Frame =
Frame(
left = left + paddings.left,
top = top + paddings.top,
right = right - paddings.right,
bottom = bottom - paddings.bottom
)
fun Frame.toLinearGradient(gradientColors: IntArray): LinearGradient {
return LinearGradient(
left,
top,
left,
bottom,
gradientColors[0],
gradientColors[1],
Shader.TileMode.MIRROR
)
}
fun Frame.contains(x: Float, y: Float): Boolean =
left < right && top < bottom && // check for empty first
x >= left && x < right && y >= top && y < bottom
@@ -0,0 +1,7 @@
package com.db.williamchart.data
data class Label(
val label: String,
var screenPositionX: Float,
var screenPositionY: Float
)
@@ -0,0 +1,12 @@
package com.db.williamchart.data
data class Paddings(val left: Float, val top: Float, val right: Float, val bottom: Float)
fun Paddings.mergeWith(paddings: Paddings): Paddings {
return Paddings(
maxOf(this.left, paddings.left),
maxOf(this.top, paddings.top),
maxOf(this.right, paddings.right),
maxOf(this.bottom, paddings.bottom)
)
}
@@ -0,0 +1,9 @@
package com.db.williamchart.data
import com.db.williamchart.renderer.RendererConstants.Companion.notInitialized
data class Scale(val min: Float, val max: Float) {
val size = max - min
}
fun Scale.notInitialized() = max == min && min == notInitialized
@@ -0,0 +1,25 @@
package com.db.williamchart.data.configuration
import com.db.williamchart.data.AxisType
import com.db.williamchart.data.Paddings
import com.db.williamchart.data.Scale
data class BarChartConfiguration(
override val width: Int,
override val height: Int,
override val paddings: Paddings,
override val axis: AxisType,
override val labelsSize: Float,
override val scale: Scale,
override val labelsFormatter: (Float) -> String = { it.toString() },
val barsBackgroundColor: Int,
val barsSpacing: Float
) : ChartConfiguration(
width = width,
height = height,
paddings = paddings,
axis = axis,
labelsSize = labelsSize,
scale = scale,
labelsFormatter = labelsFormatter
)

Some files were not shown because too many files have changed in this diff Show More