2

I want to show the steps of a sorting algorithm in real time (and animated) using for example charts for iOS (danielgindi). I need to update with each iteration the chart and I couldn't find a way to do so.

Tried:

sortingWindow.reloadInputViews()

sortingWindow.data?.notifyDataChanged(); sortingWindow.notifyDataSetChanged();

sortingWindow.animate(xAxisDuration: 1) //sortingWindow.setNeedsDisplay()

@IBOutlet weak var sortingWindow: BarChartView!
var counter = 0
var dataVector = [BarChartDataEntry]()


override func viewDidLoad() {
    super.viewDidLoad()
}
///. this works but. not when it is called in the for loop
func updateSorting( values :[BarChartDataEntry]){

    var dataSet = BarChartDataSet(values: values, label: "")
    var  data = BarChartData(dataSets: [dataSet])
    sortingWindow.data = data
    sortingWindow.notifyDataSetChanged()
}

@IBAction func addNumber(_ sender: Any) {

    let number = Int.random(in: 0 ..< 30)
    counter=counter+1
    var entry = BarChartDataEntry(x: Double(counter), y: Double(number))
    dataVector.append(entry)
    updateSorting(values:dataVector)

}

@IBAction func sort(_ sender: Any) {

    for i in 0...dataVector.count-1{
        for  j in 0...dataVector.count-2{
            if(dataVector[i].y<dataVector[j].y){

                var aux = dataVector[i].y
                dataVector[i].y=dataVector[j].y
                dataVector[j].y=aux
                usleep(10000)//0.01s
                //updateSorting(values:dataVector)


                sortingWindow.reloadInputViews()

                sortingWindow.data?.notifyDataChanged();
                sortingWindow.notifyDataSetChanged();

                 sortingWindow.animate(xAxisDuration: 1)
                //sortingWindow.setNeedsDisplay()

            }
        }

    }

}

}

1 Answers1

0

I had the same problem, I came up with a method very similar with the one below. I also tried all the methods to update the chart but none worked, maybe there's a simple way of doing things, this was just my solution!

func updateChart(_ chart: LineChartView) {

        var chartsDataSets: [LineChartDataSet] {
            var chartDataSets = [LineChartDataSet]()
            // sets is an array of Sets, please see the model below
            sets.forEach {
                var charts = [ChartDataEntry]()
                $0.dataSets!.forEach({
                    let chartEntry = ChartDataEntry(x: Double($0.xValue), y: Double($0.yValue))
                    charts.append(chartEntry)
                })
                let set = LineChartDataSet(entries: charts, label: $0.name)
                setupSet(set, color: $0.color)

                chartDataSets.append(set)
            }
            return chartDataSets
        }
        chart.data = LineChartData(dataSets: chartsDataSets)
        chart.animate(yAxisDuration: 1, easing: .none)
    }

And here's a example of a model to help you understand.

class Set {

    let name: String
    var dataSets: [DataSet]?
    let color: UIColor

    init(name: String, dataSets: [DataSet]?, color: UIColor) {
        self.name = name
        self.dataSets = dataSets
        self.color = color
    }
}

class DataSet {

    let xValue: Int 
    let yValue: Int
    let date: Date?

    init(xValue: Int, yValue: Int, date: Date) {
        self.xValue = xValue
        self.yValue = yValue
        self.date = date
    }
}

This is a model that give's you the possibility of having many sets of the same item and have all the data separated by set. At the moment I'm using core data to save all the data, but its almost the same :)