Sci-Chart 在 Android 中使用 Dagger2 进行图表更新

Sci-Chart using Dagger2 for chart update in Android

我正在构建一个基于 arch 的应用程序。用于实时图形数据的 MVVM+Databinding。使用 Sci-chart 既快速又简单,但尝试使用 Dagger2 使用 DI 更新应用程序时,在尝试使用 SuspendUpdates() 更新图形时生成 sci-chart 构建器实例 null。 ISuspendable 接口已经通过 ViewModelModule 中的@Binds 绑定。

@Module
abstract class ViewModelModule { 
@Singleton
@Binds
abstract fun getSuspendable(aSuspendable: AccurynSuspendableImpl): ISuspendable

@Binds
@IntoMap
@ViewModelKey(AViewModel::class)
abstract fun bindAViewModel(aViewModel: AViewModel): ViewModel

@Binds
internal abstract fun bindViewModelFactory(factory: AppViewModelFactory): ViewModelProvider.Factory
}

@Singleton
class AccurynSuspendableImpl @Inject constructor() : ISuspendable {


    override fun decrementSuspend() {
    }

   override fun suspendUpdates(): IUpdateSuspender? {
    return null
   }

   override fun getIsSuspended(): Boolean {
    return true
   }

    override fun resumeUpdates(p0: IUpdateSuspender?) {
    }
  }


 class AMFragment : Fragment() {
 private val acmVM by viewModel<AViewModel>()

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
     mBinding = binding(inflater, R.layout.display, container)
     mBinding.viewModel =  acmVM
     mBinding.lifecycleOwner = this
     mBinding.executePendingBindings()
     return mBinding.root
   }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
      super.onViewCreated(view, savedInstanceState)
      initializeVM()
    }
    private fun initializeVM() {

       **//TODO: how to bind these xml feature through dagger ahead of time.**
        /*acmVM = AViewModel(
        mBinding.multiPaneChart.iChart,
        mBinding.multiPaneChart.uChart)*/
    }
 }

 class AViewModel @Inject constructor(
     private val iSusp: ISuspendable,
     private val uSusp: ISuspendable,
      ) :    BaseViewModel() {....

    var iRenderDataSeries = XyDataSeries<Date, Float>().apply { 
    fifoCapacity = FIFO_CAPACITY }
    var uColumnDataSeries = XyDataSeries<Date, Float>().apply { 
    fifoCapacity = FIFO_CAPACITY }
    var uLineDataSeries = XyDataSeries<Date, Float>().apply { 
    fifoCapacity = FIFO_CAPACITY }

    private val iColor = ContextCompat.getColor(mContext, 
    R.color.pink)
    private val uColumnColor = ContextCompat.getColor(mContext, 
    R.color.yellow)
    private val uLineColor = ContextCompat.getColor(mContext, 
    R.color.gray)

    val xIAxes = AxisCollection()
    val xUAxes = AxisCollection()
    val yIAxes = AxisCollection()
    val yUAxes = AxisCollection()

    val iRenderableSeries = RenderableSeriesCollection()
    val uRenderableSeries = RenderableSeriesCollection()
    private var iChartModifiers = ChartModifierCollection()
    private var uChartModifiers = ChartModifierCollection()

    init {
       initChartDisplay(context)
    }

    private fun initChartDisplay(context: Context) {
        xIAxes.add(generateXAxis(context, View.GONE, 
        AxisAlignment.Auto))
        xUAxes.add(generateXAxis(context, View.VISIBLE, 
        AxisAlignment.Top))

        yIAxes.add(generateYAxis(context, LABEL_ID_I))
        yUAxes.add(generateYAxis(context, LABEL_ID_U))

        iRenderableSeries.add(
        generateLineRenderableSeries(
            LABEL_ID_I, iRenderDataSeries, SolidPenStyle(iColor, 
            true, lineThickness, null)
            )
        )

        val uColumnSeries =
        generateColumnRenderableSeries(LABEL_ID_U, 
        uColumnDataSeries, SolidBrushStyle(uColumnColor))
        uColumnSeries.dataPointWidth = .95
        uRenderableSeries.add(uColumnSeries)

        uRenderableSeries.add(
           generateLineRenderableSeries(
           LABEL_ID_U, uLineDataSeries, SolidPenStyle(uLineColor, 
           true, lineThickness, null)
           )
        )

     }

     private fun loadData() {
         UpdateSuspender.using(iSusp) {
                iRenderDataSeries.append(Date(lastTimeStamp), 
                median)
            }
         }

       **--Based on certain condition need to update line and column 
       UpdateSuspender.using(uRenderableSeries.single()) {
                uColumnDataSeries.updateYAt(uCurIndex, hourlyTotal) 
       //hour is a current one.  We're going to update with the latest 
       // total for the hour
            }
       **-- whereas on other condition update line series over same 
       renderable series
       UpdateSuspender.using(uRenderableSeries.single()) {
            if (priorTimeStamp + GRAPH_CALC_GAP_CONSTANT < 
            lastTimeStamp)
            {
                UpdateSuspender.using(uRenderableSeries.single()) {
                    uLineDataSeries.append(Date(priorTimeStamp + 
                    GRAPH_DISPLAY_GAP_CONSTANT), Float.NaN)
                }
            }
            //line data series updates
            uLineDataSeries.append(

       Date(DateTimeUtils.toEpochMilli(mData.getRtcTimeStamp())),
                mData.uRate.toFloat()
            )
        }

  }

  XML:

   <com.xyz.widgets.ASciChart
       android:id="@+id/u_chart"
       android:layout_width="match_parent"
       android:layout_height="0dp"
       android:visibility="@{graphViewModel.displayChartU ? 
               View.VISIBLE : View.GONE}"
       scichart:verticalGroup="@{graphViewModel.sharedVG}"        
      scichart:renderableSeries="@{graphViewModel.uRenderableSeries}"
      scichart:xAxes="@{graphViewModel.xUAxes}"
      scichart:yAxes="@{graphViewModel.yUAxes}"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintTop_toTopOf="parent" />

   <com.xyz.widgets.ASciChart
       android:id="@+id/i_chart"
       android:layout_width="match_parent"
       android:layout_height="0dp"
       android:visibility="@{graphViewModel.displayChartI ? 
            View.VISIBLE : View.GONE}"
       scichart:verticalGroup="@{graphViewModel.sharedVG}"
       scichart:renderableSeries="@{graphViewModel.iRenderableSeries}"
       scichart:xAxes="@{graphViewModel.xIAxes}"
       scichart:yAxes="@{graphViewModel.yIAxes}"/>

如何在dagger2中绑定这个sci图表实例,以便在ViewModel中访问它?任何帮助将不胜感激。

文学错误致歉

此致, PK

我认为将作为 Android 视图的 SciChartSurface 传递到 ViewModel 会违反 MVVM 模式的原则。

正如我从 XML 看到的那样,您将 RenderableSeries 存储在 ViewModel 中。我建议您暂停更新与您需要更新的 DataSeries 关联的 RenderableSeries 实例:

private fun loadData() {
    // I assume you have only one renderable series in collection
    val renderableSeries = iRenderableSeries.single()
    UpdateSuspender.using(renderableSeries) {
        iRenderDataSeries.append(Date(lastTimeStamp), median)
    }
}

在这种情况下,您不需要将 SciChartSurface 传递到 ViewModel 中,并且您将保持 View 层与 ViewModel 分离