所以我有自定义视图,我试图在那里绘制折线图。首先我绘制xGrid,yGrid和middleline。以下是我的功能:
var width: CGFloat = 400
var height: CGFloat = 200
var xLines: CGFloat = 20
var yLines: CGFloat = 10
let color = NSColor.blackColor()
func drawMiddleLine() {
let middleHeight = height / 2
var context = NSGraphicsContext.currentContext()?.CGContext
CGContextSetStrokeColorWithColor(context, color.CGColor)
CGContextSetLineWidth(context, 2)
CGContextMoveToPoint(context, 0, middleHeight)
CGContextAddLineToPoint(context, width, middleHeight)
CGContextStrokePath(context)
}
func drawYGrid() {
let space = height / yLines
var context = NSGraphicsContext.currentContext()?.CGContext
CGContextSetStrokeColorWithColor(context, color.CGColor)
for index in 0...Int(yLines) {
CGContextMoveToPoint(context, width, (CGFloat(index) * space))
CGContextAddLineToPoint(context, 0, (CGFloat(index) * space))
}
CGContextStrokePath(context)
}
func drawXGrid() {
let space = width / xLines
var context = NSGraphicsContext.currentContext()?.CGContext
CGContextSetStrokeColorWithColor(context, color.CGColor)
for index in 0...Int(xLines) {
CGContextMoveToPoint(context, (CGFloat(index) * space), self.bounds.height)
CGContextAddLineToPoint(context, CGFloat(index) * space, 0)
}
CGContextStrokePath(context)
}
现在我有基本网格,宽度是高度的两倍。现在我想缩放我的y轴,所以我要扩展我的数据(在这个例子中,我只取最大正数):
func getMaxValue(data: Array<CGFloat>) ->CGFloat {
let max = maxElement(data)
return max
}
现在我缩放我的y轴:
func scaleYAxis(data: Array<CGFloat>) ->Array<CGFloat> {
let maxValue = getMaxValue(data)
var factor = height / maxValue / 4
var scaledY = data.map({datum -> CGFloat in
var newValue = datum * factor
return newValue
})
return scaledY
}
但是当我用太多的数据点绘制我的线条时,我的绘图会搞砸,因为数据点太多了。当有大约50个数据点时,它没问题。
例如,我想在结果中得到类似的内容:JavaScript linechart with many many datapoints
我有什么想法可以设法在Swift中获得它?
我的绘图方法是这样的:
func drawLine(data: Array<CGFloat>) {
var path = CGPathCreateMutable()
var middleHeight = height / 2
CGPathMoveToPoint(path, nil, 0, middleHeight)
var scaledY = sclaleYAxis(data)
for index in 0..<data.count {
var xSpot = data[index]
var ySpot = middleHeight + scaledY[index]
CGPathAddLineToPoint(path, nil, xSpot, ySpot)
}
var layer = CAShapeLayer()
layer.frame = self.bounds
layer.path = path
layer.strokeColor = NSColor.greenColor().CGColor
layer.fillColor = nil
layer.lineWidth = 3
self.layer?.addSublayer(layer)
// I Have lineLayerStore and I delete all lines when it is needed
lineLayerStore.append(layer)
}
答案 0 :(得分:1)
如果没有看到屏幕截图,我无法理解确切的问题,但数据点的可见性取决于屏幕上的像素数。
您不能显示比像素数更多的数据点,不允许某些数据点共享相同的像素列或下采样数据。
您有3个选项:
使X轴可滚动并将scrollview的contentSize宽度设置为 数字数据点。
保持X轴宽度固定,对数据进行下采样以减少数量 要显示的数据点,然后绘制关于的图表 下采样数据。
什么都不做,尝试在固定宽度内绘制所有数据点, 如果你的计算是正确的,一些数据点会重叠 在图表中共享相同的像素列。
解释编辑第3个选项:
为了在200像素宽的X轴上显示1000个数据点,每个像素将有5个数据点。所以;
数据点0,1,2,3和4将在第1个像素列上绘制。
将在第二像素列上绘制数据点5,6,7,8和9。
数据点10,11,12,13和14将绘制在第3像素列上。
等等。
对于您的示例,有400像素和1000个数据点,这意味着每像素2.5个数据点。所以;
数据点0,1,2将在第1个像素列上绘制。
数据点3,4将在第二个像素列上绘制。
数据点5,6,7将在第3像素列上绘制。
数据点8,9将在第4像素列上绘制。
继续这样下去。