Skip to content

Commit

Permalink
FranzCocoa,ResultDetail: enable programmatic control of candle widths
Browse files Browse the repository at this point in the history
  • Loading branch information
Bogdanp committed Nov 5, 2023
1 parent 1802f6c commit 33d2f9d
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 24 deletions.
4 changes: 2 additions & 2 deletions FranzCocoa/Backend.swift
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public enum ChartScaleType: Readable, Writable {

public enum ChartStyle: Readable, Writable {
case bar
case candlestick(UVarint)
case candlestick(UVarint?)
case line
case scatter

Expand All @@ -106,7 +106,7 @@ public enum ChartStyle: Readable, Writable {
return .bar
case 0x0001:
return .candlestick(
UVarint.read(from: inp, using: &buf)
UVarint?.read(from: inp, using: &buf)
)
case 0x0002:
return .line
Expand Down
27 changes: 9 additions & 18 deletions FranzCocoa/ResultDetail.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Charts
import NoiseSerde
import SwiftUI

struct ResultDetail: View {
Expand Down Expand Up @@ -61,11 +62,11 @@ fileprivate struct ChartResult: View {
switch chart.style {
case .bar:
try? p.barMark(xLabel: chart.xLabel, yLabel: chart.yLabel)
case .candlestick:
case .candlestick(let width):
try? p.candlestickMark(
xLabel: chart.xLabel,
yLabel: chart.yLabel,
previous: p.id > 0 && p.id < ps.endIndex ? ps[p.id-1] : nil
width: width
)
case .line:
try? p.lineMark(xLabel: chart.xLabel, yLabel: chart.yLabel)
Expand All @@ -91,21 +92,17 @@ fileprivate struct ChartResult: View {
case badMarks
}

private enum CandlestickDirection {
case up
case down
}

private struct CandlestickMark<X: Plottable, Y: Plottable>: ChartContent {
let x: PlottableValue<X>
let o: PlottableValue<Y>
let h: PlottableValue<Y>
let l: PlottableValue<Y>
let c: PlottableValue<Y>
let w: UVarint?

var body: some ChartContent {
RectangleMark(x: x, yStart: l, yEnd: h, width: 1)
RectangleMark(x: x, yStart: o, yEnd: c, width: 14)
RectangleMark(x: x, yStart: o, yEnd: c, width: MarkDimension(integerLiteral: Int(w ?? 14)))
}
}

Expand All @@ -132,25 +129,19 @@ fileprivate struct ChartResult: View {
func candlestickMark(
xLabel: String,
yLabel: String,
previous: Pair?
width: UVarint?
) throws -> some ChartContent {
switch (x, y) {
case (.timestamp(let ts), .candlestick(let o, let h, let l, let c)):
var direction: CandlestickDirection
switch previous?.y {
case .some(.candlestick(_, _, _, let oc)):
direction = oc > c ? .down : .up
default:
direction = .up
}
return CandlestickMark(
x: .value("Date", Date(timeIntervalSince1970: Double(ts))),
o: .value("Open", o),
h: .value("High", h),
l: .value("Low", l),
c: .value("Close", c)
c: .value("Close", c),
w: width
)
.foregroundStyle(direction == .down ? .red : .green)
.foregroundStyle(o > c ? .red : .green)
default:
throw ChartError.badMarks
}
Expand Down
5 changes: 3 additions & 2 deletions FranzCross/result-detail.rkt
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,9 @@
(ormap ChartValue.timestamp? (Chart-ys c)))
(parameterize ([candlestick-width
(match (Chart-style c)
[(ChartStyle.candlestick width) width]
[_ 1])]
[(ChartStyle.candlestick width)
(or width 60)]
[_ 60])]
[plot-x-ticks
(if x-date-ticks?
(date-ticks)
Expand Down
4 changes: 2 additions & 2 deletions core/script.rkt
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
(define-enum ChartStyle
[bar]
[candlestick
{width : UVarint}]
{width : (Optional UVarint)}]
[line]
[scatter])

Expand Down Expand Up @@ -106,7 +106,7 @@
[(#"CandlestickChart")
(ChartStyle.candlestick
(let ([width (table-ref v #"candlestick_width")])
(if (nil? width) 1 (inexact->exact width))))]
(if (nil? width) #f (inexact->exact width))))]
[(#"LineChart")
(ChartStyle.line)]
[(#"ScatterChart")
Expand Down
3 changes: 3 additions & 0 deletions manual/index.scrbl
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,9 @@ aggregated data to a window when applying a script.
chart. The width of a candle must be the length of the interval (in
seconds) between x ticks on the chart. For example, if the chart is to
display daily candles, the width of each candle would be @tt{86400}.

On macOS, this method controls the pixel width of the candles. Use it
to make thinner candles when necessary.
}

@deflua[render.Candlestick (o h l c) Candlestick]{
Expand Down

0 comments on commit 33d2f9d

Please sign in to comment.