Search code examples
swiftdatetimechartsaxis-labelscandlestick-chart

Candlestick Chart with dates and time on x-axis


I am trying to create an candlestick chart using Charts Framework using with Codable as JSON passing myclass can be shown as :

struct ChartDataPair: Codable {
var DateTime: String  = ""
var Open: Double = 0.0
var High: Double = 0.0
var Low: Double = 0.0
var Close: Double = 0.0
}

Which creates an array of chartDataPairs as shown :

struct ChartData: Codable {
var chartDataPairs: [ChartDataPair]
}

The value that I am fetching will be shows below a bit as example :

 {"chartDataPairs":
               [{
              "DateTime": "2018/10/1 10:00:01",
              "Open": 50.05,
              "High": 50.05,
              "Low": 49.00,
              "Close":49.00
              },
              {
              "DateTime": "2018/10/1 10:05:02",
              "Open": 51.05,
              "High": 54.06,
              "Low": 40.00,
              "Close":45.06
              },
              {
              "DateTime": "2018/10/1 10:10:02",
              "Open": 50.05,
              "High": 64.06,
              "Low": 40.00,
              "Close":58.06
              }]
}

The data is just a sample so just wrote 3 values. Now I have to fetch only time and convert the DateTime String to Double to plot it in x-axis of the charts. For with I m using :

var dataEntries: [ChartDataEntry] = []
guard let financialData = dataChart.self else {
return
}
for chartData in financialData{
let open = chartData.Open
let close = chartData.Close
let high = chartData.High
let low = chartData.Low
let datetime = chartData.DateTime
let formatter = DateFormatter()
formatter.dateFormat = "YYYY/MM/dd HH:mm:ss"
let yourDate = formatter.date(from: datetime)
formatter.dateFormat = "HH:mm"
let myStringafd = formatter.string(from: yourDate!)

let time = myStringafd
let components = time.characters.split { $0 == ":" } .map { (x) -> Int in return Int(String(x))! }

let hours = components[0]
let minutes = components[1]

let double1 = Double("\(hours).\(minutes)")

let dataEntry = CandleChartDataEntry(x: double1! , shadowH: high, shadowL: low, open: open, close: close)
dataEntries.append(dataEntry)
}
    let chartDataSet = CandleChartDataSet(values: dataEntries, label: "")

chartDataSet.axisDependency = .left
chartDataSet.drawIconsEnabled = false
chartDataSet.shadowColor = .darkGray
chartDataSet.shadowWidth = 0.7
chartDataSet.decreasingColor = .red
chartDataSet.decreasingFilled = true   // fill up the decreasing field color
chartDataSet.increasingColor = UIColor(red: 122/255, green: 242/255, blue: 84/255, alpha: 1)
chartDataSet.increasingFilled = true  // fill up the increasing field color
chartDataSet.neutralColor = .blue
chartDataSet.barSpace = 1.0
chartDataSet.drawValuesEnabled = false

let chartData = CandleChartData(dataSet: chartDataSet)
candlestickView.data = chartData

I know that the conversion of the time to double ins't correct as per it is needed, Here I need some help on converting the datetime to double value.

The second issue is the bar width of the candlestick, I am unable to decrease the width of the candlestick.

And I want to fill up the x-axis with the time value like HH:MM with certain intervals like 15 mins, 50 mins, 4 hrs etc.

For which I followed few questions and suggestions here in given link below : iOS-Charts Library: x-axis labels without backing data not showing

On this issue: candlestickView.xAxisRenderer = XAxisWeekRenderer()

isn't working. It is calling for viewporthandler, x-axis and transformation.

Though I can get the custom labels from the custom IAxisValueFormatter. The interval between the two values in the x-axis is not what I wanted it to be like in 15 mins or 50 mins or 4 hrs etc.

ios Charts 3.0 - Align x labels (dates) with plots

On the above mentioned link I am unable to get the minTimeInterval and referenceTimeInterval

Basically What I want to do here is plot the hour and minute form the string that I am fetching from the JSON in x-axis and create a custom interval in between the values of x-axis while creating the custom x-axis labels.

My chart is currently shown as : Candlestick Chart


Solution

  • I have same thing to display so I used this way to display the data

            let xAxis = chartView.xAxis
            var dataPoints = [String]()
            for i in 0 ..< arrData.count
            {
    
    
                let timeStampFrom = arrData[i].time
                dataPoints.append(self.stringFromTimestamp(timeStampFrom, strDateFormat: "h a"))
    
            }
            xAxis.valueFormatter = IndexAxisValueFormatter(values:dataPoints)
            xAxis.setLabelCount(5, force: false)
    

    Some needed function

    func stringFromTimestamp(_ timeInterval : Double ,strDateFormat : String)->String 
        {
            let dateFormatter = DateFormatter()
            self.setDateFormat(dateFormatter,dateFormat: strDateFormat)
            let date = Date(timeIntervalSince1970: TimeInterval(timeInterval))
            return dateFormatter.string(from: date)
        }
    

    here is the output

    enter image description here