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.3k stars 368 forks source link

Any way to add both maximum and minimum labels to the graphs? #125

Open ghost opened 4 years ago

ghost commented 4 years ago

This is with regards to a range chart. Right now when I use cartesian.labels(true), it only displays the data in tempHigh but I want it to display both temp high and temp low. I'm looking at the library to see if there's anything that'll let me display the tempHigh on the top of the bar and the tempLow on the bottom part of the bar, instead of having to click on the range to view the high and low

Edit: I've tried normal().lowerLabels(true) and it didnt work for me, normal().upperLabels(true) did work however for displaying only the upper labels, why is this?

Shestac92 commented 4 years ago

@GCGsauce Unfortunately, the range series API doesn't support low/high labels simultaneously, but there's a workaround. You can add a hidden marker series (with 0 marker size) at low values and enable labels for this series. These labels will represent the low value of the range series. Below is the code sample:

        AnyChartView anyChartView = findViewById(R.id.any_chart_view);
        Cartesian cartesian = AnyChart.cartesian();

        List<DataEntry> data = new ArrayList<>();
        data.add(new HighLowDataEntry("Jan",  7.9, 5.8));
        data.add(new HighLowDataEntry("Feb",  6.1, 4.6));
        data.add(new HighLowDataEntry("Mar",  8.1, 5.9));
        data.add(new HighLowDataEntry("Apr",  10.7, 7.8));
        data.add(new HighLowDataEntry("May",  13.7, 10.5));
        data.add(new HighLowDataEntry("June",  17.1, 13.8));
        data.add(new HighLowDataEntry("July",  18.5, 16.5));
        data.add(new HighLowDataEntry("Aug",  19.2, 17.8));
        data.add(new HighLowDataEntry("Sep",  17.8, 15.4));
        data.add(new HighLowDataEntry("Oct",  15.3, 12.7));
        data.add(new HighLowDataEntry("Nov",  13.1, 9.8));
        data.add(new HighLowDataEntry("Dec",  10.1, 9.2));

        Set set = Set.instantiate();
        set.data(data);
        Mapping mapping = set.mapAs("{ x: 'x', value: 'low' }");

        RangeColumn series = cartesian.rangeColumn(data);
        series.labels(true);

        Marker additionalSeries = cartesian.marker(mapping);
        additionalSeries.size(0);
        additionalSeries.labels(true);
        additionalSeries.labels().position("center-bottom");

        cartesian.xAxis(true);
        cartesian.yAxis(true);

        anyChartView.setChart(cartesian);

Here is the result: Screenshot 2019-11-06 at 10 58 50

ghost commented 4 years ago

Wow! Thanks so much! Is there anyway to add additional thing to the box that pops up when you click on a bar? I want to change it to Apparent Low, Apparent High. Seems to be set with the mapping of values...

Shestac92 commented 4 years ago

@GCGsauce Do you want to include additional fields to the data and show that field-value in the tooltip? Or simply rename the existing fields in the tooltip?

ghost commented 4 years ago

Possibly both. Rename High to Apparent High or Predicted High / same with low. And I possible want to add a field below Apparent High called Time period: 357 mins, etc.

Also adding a degrees sign after the number in the label...format would be my guess but im not sure how to include the temperature value in the format

Shestac92 commented 4 years ago

@GCGsauce Both are possible! You should add custom fields to the data set and then get their values in the tooltip format. In the tooltip format, we recommend using string tokens. Below is the modified code. Pay attention to custom data set fields and tooltip format:

        AnyChartView anyChartView = findViewById(R.id.any_chart_view);
        Cartesian cartesian = AnyChart.cartesian();

        List<DataEntry> data = new ArrayList<>();
        data.add(new CustomDataEntry("Jan",  7.9, 5.8, 357, 23));
        data.add(new CustomDataEntry("Feb",  6.1, 4.6, 420, 24));
        data.add(new CustomDataEntry("Mar",  8.1, 5.9, 357, 22));
        data.add(new CustomDataEntry("Apr",  10.7, 7.8, 356, 23));
        data.add(new CustomDataEntry("May",  13.7, 10.5,350, 25));

        Set set = Set.instantiate();
        set.data(data);
        Mapping mapping = set.mapAs("{ x: 'x', value: 'low' }");
        Mapping rangeMapping = set.mapAs("{ x: 'x', low: 'low', high: 'high' }");

        RangeColumn series = cartesian.rangeColumn(rangeMapping);
        series.labels(true);
        series.tooltip().format("x: {%x}\\nPredicted High: {%high}\\nPredicted Low: {%low}\\nTime period: {%period} mins\\nTemp: {%temp}°");

        Marker additionalSeries = cartesian.marker(mapping);
        additionalSeries.size(0);
        additionalSeries.labels(true);
        additionalSeries.labels().position("center-bottom");

        cartesian.xAxis(true);
        cartesian.yAxis(true);

        anyChartView.setChart(cartesian);

Code for the CustomDataEntry:

    private class CustomDataEntry extends DataEntry {
        public CustomDataEntry(String x, Number high, Number low, Number period, Number temp) {
            setValue("x", x);
            setValue("high", high);
            setValue("low", low);
            setValue("period", period);
            setValue("temp", temp);
        }
    }

And here is the result: Screenshot 2019-11-07 at 10 56 42

ghost commented 4 years ago

Thanks again you're so much help. Great library, tough to figure out how to do stuff though!

Shestac92 commented 4 years ago

@GCGsauce Speaking about formatters you can always check our documentation. It's for the core web library, but we saved the same and approaches for the native Android library.