0

my problem is how to know or define the other(couple) value of the y-axis or x-axis. My code :

  formatterValueY = new ValueFormatter() {
            @Override
            public String getAxisLabel(float valueY, AxisBase axis) {
                //how to find the valueX of valueY ??
                // need it to return string 
                //note: I know the search solution(data loop 
               //search),
                // it is useless if there is two equal values y1=y2
      
                //this is example of what I wanna achieve,
                // this is simple example,
                
               float x = findTheRealXOfY(valueY);
               //or
               //float x = findTheRealXOfY(valueY,axis);

               if(x %2==0)
               {
                    return "Pair:"+valueY;
                 }
               else{
                  return "inPair:"+valueY;
                }

                
            }
        }


        YAxis yAxis = myBarChar.getYAxis();
        yAxis.setValueFormatter(formatterValueY);

so if there is way to find the real pair value of Y using the valueY and axis.

This is an example of what I want

example chart

Tyler V
  • 9,694
  • 3
  • 26
  • 52
MehdiS
  • 89
  • 5
  • What are you trying to achieve with this? Maybe if you added a more concrete example of why you want this people could suggest approaches. Normally the y axis labels on a chart would be independent of the x values. – Tyler V Dec 21 '21 at 16:13
  • @TylerV done dude check out the simple example. – MehdiS Dec 22 '21 at 07:44
  • 1
    You didn't answer why do you want to do this in the first place. – Ricky Mo Dec 22 '21 at 07:54
  • There could be multiple x values for a given y value though (or none at all, axis labels are not tied to data points). Why would you want to put this in the y axis labels at all? Maybe add a simple picture of what you want the chart to look like and why you need this? If you want labels on individual points there is a better way of doing that, not using the y axis labels. – Tyler V Dec 22 '21 at 15:00
  • @RickyMo it is clear dude the value "string" of y depend in the value of x, example : lets say it 7day bar chart (in X axis) and so if the day position is pair the y value should be = to "Rest" and the other unpair days should be = to "Work", this is only simple example. – MehdiS Dec 23 '21 at 03:49
  • 1
    @MehdiS you are only telling "what" you want to do, not "why" you want to do. Your proposed solution may or may not be the best approach to solve your actual problem. That's why people ask for "why" you want to do this. There maybe other approaches to suit your actual needs. See [What is the XY problem?](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) – Ricky Mo Dec 23 '21 at 03:54
  • @TylerV the Y value depend on X value, I am using ValueFormatter for x label because the entries "data" of the bar chart are pairs, I need to know the id of the Y value so I decide what to return according to it is "id". example : if (id == BOY_ID) return valueY+"/BOY" else return valueY+"/Girl". I think it is clear now with this example. I am here for any other information – MehdiS Dec 23 '21 at 04:05
  • @RickyMo I already told you because the value of y depend of the value of Y, it is bar chart no line chart, and bar chart each bar has values. example: the X is Id the Y is Float value but I to add some text to it like (boy / girl) – MehdiS Dec 23 '21 at 04:09
  • The axis labels are independent of the data shown on the plot, so what you are asking for still makes no sense. Please add a picture to the question showing what you are trying to achieve. It sounds like maybe you are confused about what an axis label is. – Tyler V Dec 23 '21 at 04:12
  • Also, take a look [here](https://stackoverflow.com/questions/38857038/mpandroidchart-adding-labels-to-bar-chart) – Tyler V Dec 23 '21 at 04:20
  • @TylerV sorry dude for the bad explanation but here is picture===> https://ibb.co/Lr9JDWc . the boy/girl mean the majeure voter for the color. – MehdiS Dec 23 '21 at 04:26
  • @RickyMo please read my last comment with a picture, it is example of what I need. – MehdiS Dec 23 '21 at 04:27
  • @TylerV I know that solution you provided but it not what I need, because "float value" are the number of people voted for that color, and it can be +10K vote so that solution not logic at all. – MehdiS Dec 23 '21 at 04:35
  • Ok, the picture helps - but why doesn't `mBarChart.getXAxis().setValueFormatter(new IndexAxisValueFormatter(labels));` work for you? If you have the data you set on the chart, you can prepare an array of labels based on their values. – Tyler V Dec 23 '21 at 04:37
  • @TylerV I told you in the last comment x working 100% the y value not working – MehdiS Dec 23 '21 at 05:22
  • @TylerV I found it after 2day of search, read my solution. – MehdiS Dec 23 '21 at 06:14
  • @RickyMo read my solution I found it. – MehdiS Dec 23 '21 at 06:14
  • Yes, I posted an answer below that shows how to do that already... This would have gone a lot smoother if you had just asked "how do I put labels on top of the bars on a bar chart?" – Tyler V Dec 23 '21 at 06:20

2 Answers2

0

Depending on where you want these labels you have a couple options. If you want to set the labels along the bottom of the chart, you can use the IndexAxisValueFormatter(labels) on the x axis. If you want to add labels on the top of the bars you can set a ValueFormatter on the BarDataSet. Here is an example that sets "L" or "M" on the lower axis depending on the bar height, and "Less" or "More" on the bar label itself - also depending on the bar height.

example app

For setting the x axis labels, the relevant command is

xaxis.valueFormatter = IndexAxisValueFormatter(labels)

and for the bar labels

barDataSet.valueFormatter = object : ValueFormatter() {
    override fun getBarLabel(barEntry: BarEntry?): String {
        var label = ""
        barEntry?.let { e ->
            // here you can access both x and y
            label = if( e.y > 25 ) {
                "More"
            } else {
                "Less"
            }
        }
        return label
    }
}

If you want the labels above the bars, you can use

barChart.setDrawValueAboveBar(true)

Complete Example

val barChart = findViewById<BarChart>(R.id.bar_chart)

// the values on your bar chart - wherever they may come from
val yVals = listOf(10f, 20f, 30f, 40f, 50f, 60f)

val valueSet1 = ArrayList<BarEntry>()
val labels = ArrayList<String>()

// You can create your data sets and labels at the same time - 
// then you have access to the x and y values and can 
// determine what labels to set
for (i in yVals.indices) {
    val yVal = yVals[i]
    val entry = BarEntry(i.toFloat(), yVal)
    valueSet1.add(entry)

    if( yVal > 20) {
        labels.add("M")
    }
    else {
        labels.add("L")
    }
}

val dataSets: MutableList<IBarDataSet> = ArrayList()
val barDataSet = BarDataSet(valueSet1, " ")

barChart.setDrawBarShadow(false)
barChart.setDrawValueAboveBar(false)
barChart.description.isEnabled = false
barChart.setDrawGridBackground(false)


val xaxis: XAxis = barChart.xAxis
xaxis.setDrawGridLines(false)
xaxis.position = XAxis.XAxisPosition.BOTTOM
xaxis.granularity = 1f
xaxis.isGranularityEnabled = true
xaxis.setDrawLabels(true)
xaxis.setDrawAxisLine(false)
xaxis.valueFormatter = IndexAxisValueFormatter(labels)
xaxis.textSize = 15f

val yAxisLeft: YAxis = barChart.axisLeft
yAxisLeft.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART)
yAxisLeft.setDrawGridLines(true)
yAxisLeft.setDrawAxisLine(true)
yAxisLeft.isEnabled = true
yAxisLeft.textSize = 15f

barChart.axisRight.isEnabled = false
barChart.extraBottomOffset = 10f
barChart.extraLeftOffset = 10f

val legend: Legend = barChart.legend
legend.isEnabled = false


barDataSet.color = Color.CYAN
barDataSet.valueTextSize = 15f

// You can also set a value formatter on the bar data set itself (and enable
// setDrawValues). In this you get a BarEntry which has both the x position
// and bar height.
barDataSet.setDrawValues(true)
barDataSet.valueFormatter = object : ValueFormatter() {
    override fun getBarLabel(barEntry: BarEntry?): String {
        var label = ""
        barEntry?.let { e ->
            // here you can access both x and y
            // values with e.x and e.y
            label = if( e.y > 25 ) {
                "More"
            } else {
                "Less"
            }
        }
        return label
    }
}
dataSets.add(barDataSet)

val data = BarData(dataSets)
barChart.data = data
barChart.invalidate()
Tyler V
  • 9,694
  • 3
  • 26
  • 52
  • oh big thanks but already found it :D , but thanks so mush. your solution in Kotlin my in Java. the mistake is I was using "getAxisLabel" instead of "getBarLabel", tnx dude – MehdiS Dec 23 '21 at 06:25
0

example of what I needed, this is the best solution, with no over-code

this is the code:

BarData data = new BarData(colorBarSet);

data.setValueFormatter(new ValueFormatter() {

                @Override
                public String getBarLabel(BarEntry barEntry) {
                    Log.e("TAG", "this is the X value: " + barEntry.getX());
                    Log.e("TAG", "this is the Y value: " + barEntry.getY());

                // this will return "Girl" for red color with x value=1, 
                // value of x is the index of the color in bar chart
                return getMajeureVoteOfColor(barEntry.getX);
                }
            });
MehdiS
  • 89
  • 5