user1928896
user1928896

Reputation: 673

MPAndroidChart Legend with different shapes (forms)

I am using MPAndroidChart and have the need to plot a number of datasets using ScatterChart. As the number of datasets is dynamic, I used a logic that creates a combination of color and shape for each dataset. The resultant chart looks like this. As you can see, in this example, there are ten datasets, each represented by a unique Shape+Color combination. The problem is with the legend shapes. How do I change the legend shapes to match with the dataset shapes?

Chart: enter image description here

Source Code:

        private static final int SCATTER_SHAPES_MOD = 4; //there are four shapes
        private static final int SCATTER_COLOR_MOD = 5; //there are five colors
        for (int i=0; i < dataSeries.size(); i++) {
            ScatterDataSet set = new ScatterDataSet(dataSeries.get(i), choiceArray[i]);
            set.setScatterShape(ScatterShapeArray[i % SCATTER_SHAPES_MOD]);
            set.setColor(ColorTemplate.COLORFUL_COLORS[i % SCATTER_COLOR_MOD]);
            set.setScatterShapeSize(10f);
            set.setDrawValues(false); // Hide data labels
            dataSets.add(set); // add the dataset
        }
        if (dataSeries.size() > 0) {
            data = new ScatterData(xVals, dataSets);
            // Set chart data
            chart.setData(data);
        }

Upvotes: 3

Views: 2232

Answers (2)

Learner_Programmer
Learner_Programmer

Reputation: 1299

Actually, now Dear Philipp has added that functionality, I think he forgot to update here, hence I am updating so that for someone it may help.

There is a new function called setCustom in legend class which can be used for the above purpose.I have tested it.Please find code below. The looping is done with dataSets I had already(ScatteredDataSet in my case).

    List<LegendEntry> entries = new ArrayList<>();
    for (int i = 0; i < dataSets.size(); i++) {
        final LegendEntry entry = new LegendEntry();
        IScatterDataSet set = dataSets.get(i);
        String Label = set.getLabel();

        if (Label.equalsIgnoreCase("A")) {
            entry.form = Legend.LegendForm.CIRCLE;
            entry.formColor = set.getColor();
            entry.label = Label;

        } else if(Label.equalsIgnoreCase("B")){

            entry.form = Legend.LegendForm.CIRCLE;
            entry.formColor = set.getColor();
            entry.label = Label;



        } else if(Label.equals("C")){

            entry.form = Legend.LegendForm.SQUARE;
            entry.formColor = set.getColor();
            entry.label = Label;



        }
        else if (entry.formColor == ColorTemplate.COLOR_NONE ||
                entry.formColor == 0) {
            entry.form = Legend.LegendForm.EMPTY;
            entry.label = Label;

        }
        entries.add(entry);
    }

    LegendEntry[] mEntries = entries.toArray(new LegendEntry[entries.size()]);

    Legend l = mChart.getLegend();
    l.setCustom(mEntries);
    l.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);
    l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT);
    l.setOrientation(Legend.LegendOrientation.HORIZONTAL);
    l.setDrawInside(false);
    l.setXOffset(10f);

I Thank Philipp for this awesome library. NOTE:Only limitation I see is that LegendForm has only few shapes as enum which can't be altered and Scatter chart has more shapes which can't be replicated in Legends!If there is a way please post here.

Upvotes: 4

Philipp Jahoda
Philipp Jahoda

Reputation: 51411

Unfortunately that is currently not possible by default. You will have to modify the library to get the behaviour you are describing.

I might add a feature like that in the future.

Upvotes: 2

Related Questions