Integration Example
This page describes a short example of integrating an Android DXcharts library into an application. For the full algorithm for connecting the DXcharts library, please check Quick Start page
Add dependencies
First step is to add dependencies into your build.gradle file
plugins {
//...
id 'org.jetbrains.kotlin.android' version '1.9.0' apply false
}
android {
//...
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.5.2"
}
//...
}
dependencies {
//Compose dependencies
def composeBom = platform('androidx.compose:compose-bom:$COMPOSE_BOM_VERSION')
implementation composeBom
androidTestImplementation composeBom
implementation 'androidx.compose.foundation:foundation'
implementation 'androidx.compose.ui:ui'
implementation 'androidx.activity:activity-compose:$ACTIVITY_COMPOSE_VERSION'
implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.8.0'
implementation 'androidx.constraintlayout:constraintlayout-compose:1.1.0'
implementation 'androidx.compose.material3:material3'
//Additional dependencies that used in the library
implementation 'com.google.code.gson:gson:2.10.1' // For JSON parsing
implementation 'com.jakewharton.threetenabp:threetenabp:1.4.7' // For date and time API
//Required DxCharts dependencies
implementation 'com.devexperts.dxcharts.lib:dxcharts_lib:$MAIN_LIB_VERSION'
implementation 'com.devexperts.dxcharts.provider:dxcharts_data_providers:$'DATA_PROVIDER_VERSION'
//Not necessary dependencies. Default implementations of data providers with DxFeed API
implementation 'com.devexperts.dxcharts.provider.candles:dxcharts_dxfeed_candles_provider:$CANDLES_PROVIDER_VERSION'
implementation 'com.devexperts.dxcharts.provider.events:dxcharts_dxfeed_events_provider:$EVENTS_PROVIDER_VERSION'
implementation 'com.devexperts.dxcharts.provider.ipf:dxcharts_dxfeed_ipf_provider:$IPF_PROVIDER_VERSION'
implementation 'com.devexperts.dxcharts.provider.news:dxcharts_dxfeed_news_provider:$NEWS_PROVIDER_VERSION'
implementation 'com.devexperts.dxcharts.provider.studies:dxcharts_studies_provider:$STUDIES_PROVIDER_VERSION'
}
DxCharts configuration
Next step will be creating DxCharts view.
class DXChartsActivity : AppCompatActivity() {/*** Creating providers objects.* In this example we use our default providers implementations, but you can create your own.* Notice that default implementations based on the DxFeed API and require endpointAddress, url and token.*/private val quotesProvider = DxFeedQuotesProvider(endpointAddress = "ENDPOINT_ADDRESS")private val candlesProvider = DxFeedCandlesProvider(endpointAddress = "ENDPOINT_ADDRESS")private val newsProvider = DxFeedNewsProvider(url = "NEWS_URL",token = "Basic " + String(Base64.encode("NEWS_TOKEN".encodeToByteArray(),Base64.NO_WRAP)))private val dxFeedIpfProvider = DxFeedHttpIpfProvider(url = "IPF_URL",token = "Basic " + String(Base64.encode("IPF_TOKEN".encodeToByteArray(),Base64.NO_WRAP)))private val eventsProvider = DxFeedEventsProvider(url = "EVENTS_URL",token = "Basic " + String(Base64.encode("EVENTS_TOKEN".encodeToByteArray(), Base64.NO_WRAP)))private val studiesProvider = DxStudiesDataProviderImplementation()private val studiesPreviewProvider = DxStudiesPreviewDataProviderImplementation()private val scheduleProvider = DxFeedHttpScheduleProvider(token = "Basic " + String(Base64.encode(BuildConfig.IPF_TOKEN.encodeToByteArray(),Base64.NO_WRAP)))/*** Creating repositories objects.* Library provides 2 default variants of implementations of repositories.* 1. SerializableStorage repositories. They implement saving their inner state into shared preferences. To restore their state you need to use deserialize() method.* 2. LocalStorage repositories. They don't save any state across instances of chart and don't need context as a parameter.* Also you can create your own implementations of repositories.*/private val studiesRepository by lazy {/*** StudiesRepository needs indicator items to be passed. Default studies list can be obtained by using StudiesLoader().load(assets).*/SerializableStorageDefaultStudiesRepository(application, StudiesLoader().load(assets))}private val aggregationsRepository by lazy {SerializableStorageDefaultAggregationsRepository(application)}private val colorsRepository by lazy {SerializableStorageDefaultColorsRepository(application)}private val drawingsLineWidthRepo by lazy {SerializableStorageDefaultDrawingsLineWidthRepo(application)}private val drawingsSnapshotsRepo by lazy {SerializableStorageDefaultDrawingsSnapshotsRepo(application)}private val drawingsFirstClickRepo by lazy {SerializableStorageDefaultFirstClickRepo(application)}private val drawingsTypesRepo by lazy {SerializableStorageDefaultDrawingsTypesRepo(application)}private val highlighterColorsRepository by lazy {SerializableStorageDefaultHighlighterColorsRepository(application)}private val instrumentRepository by lazy {SerializableStorageDefaultInstrumentRepository(application)}private val timeframePresetsRepository by lazy {SerializableStorageDefaultTimeframePresetsRepository(application)}private val ordersRepository by lazy {SerializableStorageDefaultOrdersRepository(application)}private val settingsRepository by lazy {SerializableStorageDefaultSettingsRepository(application)}private val studiesTemplatesRepository by lazy {SerializableStorageDefaultStudiesTemplatesRepository(application)}private var isSystemInDarkTheme: Boolean = trueoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)isSystemInDarkTheme =resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES/*** Method that restore state into SerializableStorage repositories.*/deserializeRepositories()/*** Initializing providers.*/quotesProvider.connect()candlesProvider.connect()dxFeedIpfProvider.connect()studiesProvider.connect()studiesPreviewProvider.connect()/*** Handling errors in default repositories.* Default providers have errorFlow that let you set your own way of handling errors.* It's optional and can be customized depending on your needs.*/lifecycleScope.launch {merge(candlesProvider.errorFlow,quotesProvider.errorFlow,dxFeedIpfProvider.errorFlow,eventsProvider.errorFlow,newsProvider.errorFlow,studiesProvider.errorFlow,studiesPreviewProvider.errorFlow).collect { error ->// Custom error handling logicval errorClassName = error?.javaClass?.simpleNameval parentClassName = error?.javaClass?.superclass?.simpleNameLog.e("DxChartsProviderError", "$errorClassName from $parentClassName : $error?.message")if(error?.error != null){throw error.error!!}}}setContent {/*** Get initial theme and from settings repository and set according color palette for DxCharts*/val initialTheme = getPalette(settingsRepository.getCurrentTheme())var theme by remember { mutableStateOf(initialTheme) }/*** Get initial instrument from settings repository*/val initialInstrument = instrumentRepository.getSelectedInstrument()/*** Initializing DxChart*/DxChartsTheme(colors = theme) {Surface(modifier = Modifier.fillMaxSize(),color = DxChartsTheme.colors.mainChartBg) {DxChartsScreen(DxChartsConfig(/*** Passing repositories to the DxChartConfig.* By default all repositories are LocalStorage and don't save their state across instances.*/repositories = DxChartsConfig.Repositories(studiesRepository = studiesRepository,aggregationsRepository = aggregationsRepository,colorsRepository = colorsRepository,drawingsLineWidthRepo = drawingsLineWidthRepo,drawingsSnapshotsRepo = drawingsSnapshotsRepo,drawingsFirstClickRepo = drawingsFirstClickRepo,drawingsTypesRepo = drawingsTypesRepo,highlighterColorsRepository = highlighterColorsRepository,instrumentRepository = instrumentRepository,ordersRepository = ordersRepository,timeframePresetsRepository = timeframePresetsRepository,settingsRepository = settingsRepository,studiesTemplatesRepository = studiesTemplatesRepository),/*** Passing providers to the DxChartConfig.* By default all providers are null*/providers = DxChartsDataProviders(candlesProvider = candlesProvider,ipfProvider = dxFeedIpfProvider,scheduleProvider = scheduleProvider,quotesProvider = quotesProvider,eventsProvider = eventsProvider,newsProvider = newsProvider,studiesDataProvider = studiesProvider,studiesDataPreviewProvider = studiesPreviewProvider),/*** Set initial instrument that will be used if there are no saved instruments in the instrument repository.*/initialInstrument = instrument),/*** Callback for click on Buy button.*/buyClicked = {},/*** Callback for click on Sell button.*/sellClicked = {},/*** Callback for changing theme in the DxCharts settings.*/themeChanged = { theme = getPalette(it) },/*** Setting your logo.* By default it's null.*/logo = Logo(image = R.drawable.devexperts_logo,position = Logo.LogoPosition.BOTTOM_LEFT,),/*** Whether to show toolbar or not.*/showToolbar = true,)}}}}/*** Disconnecting default providers.*/override fun onDestroy() {newsProvider.disconnect()dxFeedIpfProvider.disconnect()quotesProvider.disconnect()candlesProvider.disconnect()eventsProvider.disconnect()studiesProvider.disconnect()studiesPreviewProvider.disconnect()super.onDestroy()}/*** Function that checks what color palette to use.*/private fun getPalette(theme: Theme): DxChartsColors {return when (theme) {Theme.AUTO -> {if (isSystemInDarkTheme) darkPalette() else lightPalette()}Theme.LIGHT -> {lightPalette()}Theme.DARK -> {darkPalette()}}}/*** Function that responsible for restoring state of SerializableStorage repositories.*/private fun deserializeRepositories() {val prefs = application.getSharedPreferences("dxcharts_demo_app", MODE_PRIVATE)val aggregations = prefs.getString("aggregations_repo", null)val colors = prefs.getString("colors_repo", null)val drawingsLine = prefs.getString("drawings_line_repo", null)val drawingsSnapshots = prefs.getString("drawings_snapshots_repo", null)val drawingsTypes = prefs.getString("drawings_types_repo", null)val drawingsFirstClick = prefs.getString("drawings_first_click_repo", null)val highlighter = prefs.getString("highlighter_repo", null)val instrument = prefs.getString("instrument_repo", null)val orders = prefs.getString("orders_repo", null)val settings = prefs.getString("settings_repo", null)val studies = prefs.getString("studies_repo", null)val studiesTemplates = prefs.getString("studies_templates_repo", null)val timeframePresets = prefs.getString("timeframe_presets_repo", null)aggregations?.let {aggregationsRepository.deserialize(it)}colors?.let {colorsRepository.deserialize(it)}drawingsLine?.let {drawingsLineWidthRepo.deserialize(it)}drawingsSnapshots?.let {drawingsSnapshotsRepo.deserialize(it)}drawingsTypes?.let {drawingsTypesRepo.deserialize(it)}drawingsFirstClick?.let {drawingsFirstClickRepo.deserialize(it)}highlighter?.let {highlighterColorsRepository.deserialize(it)}instrument?.let {instrumentRepository.deserialize(it)}orders?.let {ordersRepository.deserialize(it)}settings?.let {settingsRepository.deserialize(it)}studies?.let {studiesRepository.deserialize(it)}studiesTemplates?.let {studiesTemplatesRepository.deserialize(it)}timeframePresets?.let {timeframePresetsRepository.deserialize(it)}}}