Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stacked Bar Chart not working properly? #2683

Open
seenoevo opened this issue Aug 6, 2017 · 2 comments
Open

Stacked Bar Chart not working properly? #2683

seenoevo opened this issue Aug 6, 2017 · 2 comments

Comments

@seenoevo
Copy link

seenoevo commented Aug 6, 2017

I'm really confused, how and when does stringForValue actually work?

I thought I knew how it is being called but I guess I don't.

I'm trying to combine data into one stacked bar if the x-axis values are the same, but I'm confused on when stringForValue is called to format the x-axis labels.

This is currently what I'm seeing:

untitled

I was somewhat able to combine the data from the date label 08/06/17 because there's 2 data for that x-axis date (as can be seen in the table below), but the upper red part should be 5.66, not 8.66. Somehow, it is adding 3.00 to 5.66 to make 8.66.

However, that's not what I'm concerned about. I'm trying to eliminate the first blank 08/06/17 x-axis label, but for some reason, stringForValue is being called for each index.

Here's a bit of my code:

extension ServiceChargeViewController: IAxisValueFormatter
{
    func stringForValue(_ value: Double, axis: AxisBase?) -> String
    {
        let tempServiceRecord_ARRAY = serviceRecord_ARRAY.sorted(by: {$0.date < $1.date})
        
        print("value = \(value)")
        
        let date = tempServiceRecord_ARRAY[Int(value)].date
        
        print("date = \(date)")
        
        return ReusableClass.typeThreeDateFormat(date: date)
    }
}

func createBarChart(dataPoints: [Date], values: [Double])
{
    var dataEntries: [BarChartDataEntry] = []

    ....
      
    for lastIndex  in 0..<someArray.count
    {
        ...
        var duplicateDateCosts = [Double]()

        let dataEntry = BarChartDataEntry(x: Double(lastIndex),
                                                      yValues: duplicateDateCosts)

        dataEntries.append(dataEntry)
   }

   barChartView.xAxis.valueFormatter = self

    barChartView.xAxis.granularity = 1
    
    // duplicateDateIndices_ARRAY.count = 4
    barChartView.xAxis.setLabelCount(duplicateDateIndices_ARRAY.count, force: false)

    let chartDataSet = BarChartDataSet(values: dataEntries, label: "")
    let chartData = BarChartData(dataSet: chartDataSet)
        
    barChartView.data = chartData
}

The dataPoints array contains the following dates:

[2017-08-05, 2017-08-06, 2017-08-06, 2017-08-07, 2017-08-10]

The values array contains the following:

[8.0, 3.0, 5.66, 4.44, 5.0]

Now ignoring the trivial things happening in the for loop of createBarChart, every time I create the BarChartDataEntry, the value in lastIndex is 0, 2, 3, 4 respectively. duplicateDateCosts is an array of Double costs value associated with the lastIndex.

However, stringForValue is called with the value being passed in as 0, 1, 2, 3, 4. This causes the date x-axis label 08/06/17 to be displayed twice even though I combined the two dates into one stacked bar, hence the duplicateDateCosts array containing 3.0 and 5.66 for the associated 08/06/17 date label.

I thought the value in stringForValue corresponds to the x Double value in the initialization BarChartDataEntry(x: [Double], yValues: [Double] ). This is based on what @tuantmdev said in #1527: "The value of x you pass when init BarChartDataEntry should be the same the value of formatter method"

Therefore, why isn't the value in stringForValue suppose to be 0, 2, 3, 4, but instead is 0, 1, 2, 3, 4???

I don't understand. This is why I have a repeated x-axis label.

Can someone explain this to me?

@tuantmdev
Copy link

I do not really understand what you do with dataPoints, someArray & duplicateDateCosts in your createBarChart method but if you want to display 4 stack bar chart (same date in same bar), you must prepare data your own, the bar chart does not do it for you.

For example

let values = [[8.0], [3.0, 5.66], [4.44], [5.0]]
for lastIndex in 0..3
{
    let dataEntry = BarChartDataEntry(x: Double(lastIndex), yValues: values[lastIndex])
    dataEntries.append(dataEntry)
}

And stringForValue should be

func stringForValue(_ value: Double, axis: AxisBase?) -> String
{
    let tempServiceRecord_ARRAY = ["2017-08-05", "2017-08-06", "2017-08-07", "2017-08-10"]
    let date = tempServiceRecord_ARRAY[Int(value)]
    return date
}

@seenoevo
Copy link
Author

seenoevo commented Aug 8, 2017

@tuantmdev I understand exactly what you're doing, but as mentioned in my description, my dataPoints array contains: [2017-08-05, 2017-08-06, 2017-08-06, 2017-08-07, 2017-08-10]

And the values array: [8.0, 3.0, 5.66, 4.44, 5.0]

At index 1 and index 2 are the repeated dates 2017-08-06.

So then in this code:

let dataEntry = BarChartDataEntry(x: Double(lastIndex), yValues: duplicateDateCosts)

What I tried to do was, the lastIndex represents the index from my dataPoints array, or in other words, the last index that contains a "repeated" date. The duplicateDateCosts array contains the cost(s) associated with the "date", or in other words the "index" from my dataPoints array.

Therefore, if lastIndex = 2, it represents the last index in the array that contains the repeated date 2017-08-06, which contains 2 associated costs 3.0 and 5.66 from the values array, which I put into duplicateDateCosts in other to display the stacked bar that you see.

Since index 1 and index 2 contains the repeated data 2017-08-06, I don't pass lastIndex as 1 into BarChartDataEntry(x: Double(lastIndex), yValues: duplicateDateCosts), but instead, pass lastIndex as 2.

In other words, in my for loop, I'm skipping an index (index 1) when I create the BarChartDataEntry.

However, the point of my question was how does the stringForValue function work because it's causing my bar chart to have a repeated x-value label of 2017-08-06.

I was quoting what you said in another issue: "The value of x you pass when init BarChartDataEntry should be the same the value of formatter method".

If what you said is what I think you said, then when stringForValue is called, why isn't the value in the parameter the same value as in lastIndex (0, 2, 3, 4) when I create the BarChartEntry but instead goes in order (0, 1, 2, 3, 4)?...which is why I have a blank bar for one of the 08/06/17 x-axis label.

I wish someone can help me understand what is happening, as I'm really stuck on this part and unsure how to fix it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants