AnyChart / AnyChart-Android

AnyChart Android Chart is an amazing data visualization library for easily creating interactive charts in Android apps. It runs on API 19+ (Android 4.4) and features dozens of built-in chart types.
2.32k stars 369 forks source link

How to change chart in AnyChartView? #225

Open kamieniarzk opened 3 years ago

kamieniarzk commented 3 years ago

I have a following layout:


     ...

     <Button
        android:id="@+id/changeChart"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
     <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="10dp">

        <com.anychart.AnyChartView
            android:id="@+id/any_chart_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

        <ProgressBar
            android:id="@+id/progress_bar"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            />

    </androidx.constraintlayout.widget.ConstraintLayout>

     ...

And In my Activity I have the following code:

public class ChartActivity extends AppCompatActivity {
   private AnyChartView mChartView;
   private boolean mCartesianSet;
   private Cartesian mCartesian;
   private Pie mPie;

   ...

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_video);
        initializeChart1();
        initializeChart2();
        Button button = findViewById(R.id.changeChart);
        button.setOnClickListener(view -> changeChart());
    }

    private void initializeChart1() { // example from one of your samples modified to my needs
        Cartesian cartesian = AnyChart.column();

        List<DataEntry> data = new ArrayList<>(); // I didn't paste the initialization of mVideoMetadata as it's not relevant here
        String segmentationLabel = mVideoMetadata.getSegmentationMethod() == SegmentationMethod.THRESHOLDING ?
                "Thresholding" :
                "Edge detection";
        data.add(new ValueDataEntry(segmentationLabel, mVideoMetadata.getSegmentationTime()));

        if (mVideoMetadata.getFilteringMethod() != FilteringMethod.None) {
            String filteringLabel = mVideoMetadata.getFilteringMethod().toString();
            data.add(new ValueDataEntry(filteringLabel, mVideoMetadata.getFilteringTime()));
        }

        String extractionLabel = mVideoMetadata.getExtractionMethod() == ExtractionMethod.DRAW_CONTOURS ?
                "Finding and drawing contours" :
                "Substituting colour";
        data.add(new ValueDataEntry(extractionLabel, mVideoMetadata.getExtractionTime()));

        Column column = cartesian.column(data);

        column.tooltip()
                .titleFormat("{%X}")
                .position(Position.CENTER_BOTTOM)
                .anchor(Anchor.CENTER_BOTTOM)
                .offsetX(0d)
                .offsetY(5d)
                .format("{%Value}{groupsSeparator: }ms");

        cartesian.animation(true);
        cartesian.title("CPU time consumed by each algorithm step.");

        cartesian.yScale().minimum(0d);

        cartesian.yAxis(0).labels().format("{%Value}{groupsSeparator: }ms");

        cartesian.tooltip().positionMode(TooltipPositionMode.POINT);
        cartesian.interactivity().hoverMode(HoverMode.BY_X);

        cartesian.xAxis(0).title("Algorithm step");
        cartesian.yAxis(0).title("Time");
        mCartesian = cartesian;
    }

    private void initializeChart2() { //example straight from your samples
        Pie pie = AnyChart.pie();

        pie.setOnClickListener(new ListenersInterface.OnClickListener(new String[]{"x", "value"}) {
            @Override
            public void onClick(Event event) {
                Toast.makeText(VideoActivity.this, event.getData().get("x") + ":" + event.getData().get("value"), Toast.LENGTH_SHORT).show();
            }
        });

        List<DataEntry> data = new ArrayList<>();
        data.add(new ValueDataEntry("Apples", 6371664));
        data.add(new ValueDataEntry("Pears", 789622));
        data.add(new ValueDataEntry("Bananas", 7216301));
        data.add(new ValueDataEntry("Grapes", 1486621));
        data.add(new ValueDataEntry("Oranges", 1200000));

        pie.data(data);

        pie.title("Fruits imported in 2015 (in kg)");

        pie.labels().position("outside");

        pie.legend().title().enabled(true);
        pie.legend().title()
                .text("Retail channels")
                .padding(0d, 0d, 10d, 0d);

        pie.legend()
                .position("center-bottom")
                .itemsLayout(LegendLayout.HORIZONTAL)
                .align(Align.CENTER);

        mPie = pie;
    }

And the button in my layout has an OnClick listener set to the following method


    private void changeChart() {
        mCartesianSet = !mCartesianSet;
        if (mCartesianSet) {
            mChartView.setChart(mCartesian);
        } else {
            mChartView.setChart(mPie);
        }
    }

To my surprise, clicking the button does nothing (only initializes the view with the cartesian chart when clicked for the first time, every next click only reloads the view with the cartesian chart)

Am I doing something wrong or is it not possible to change charts on a view? (because I've tried having multiple views in one ConstraintLayout and only one of them was showing)

Shestac92 commented 3 years ago

@kamieniarzk We recommend overriding the view. Remove the existing one and create a new one.

kamieniarzk commented 3 years ago

Okay, in the meantime I have one more issue - when I set up two AnyChartViews in one layout, I cannot get two charts to show - if Iset their height to match_parent then one of them alwasy has height = 0dp like on this screenshot. image The only way I've managed to get both of them to show was by setting layout_height="0dp" and layout_weight="1" but in that way they are squashed and you can't really see all the data. Are there some recommendations as to how to make multiple views in a single layout?

Shestac92 commented 3 years ago

@kamieniarzk The only possible solution now is described in the wiki article.