我有一个 lineChart,我想添加一个点(散点)。那可能吗?有什么解决方法吗?我试图弄清楚这对我来说似乎是不可能的,因为即使只使用散点数据我也必须使用相同的xVals
数组,在我的情况下,这条线有一些xVals
点,而单个散点只有 X 上的一个值和 Y 上的一个值。
谢谢
对我来说,使用 iOS 图表的唯一解决方案是叠加两个视图图表......
我有一个 lineChart,我想添加一个点(散点)。那可能吗?有什么解决方法吗?我试图弄清楚这对我来说似乎是不可能的,因为即使只使用散点数据我也必须使用相同的xVals
数组,在我的情况下,这条线有一些xVals
点,而单个散点只有 X 上的一个值和 Y 上的一个值。
谢谢
对我来说,使用 iOS 图表的唯一解决方案是叠加两个视图图表......
您是否要求截断折线图?我不清楚你的问题是什么。如果您只想要散点图 + 折线图,请使用CombinedChartView
.
我有一个截断折线图的功能请求,所以我们可以在折线图中有“单点”,所以如果你不想连接这些点。检查它是否是https://github.com/danielgindi/ios-charts/issues/280。如果属实,您可以帮助发表评论,以便作者知道。
在您这边,您可以尝试对折线图渲染器和协议进行子类化,以允许您添加单个点。对我来说,如果当前点无法连接到下一个点,我想截断该行。比如y值:1-2-3 5(单点)7-8-9。
你必须提供你想要的,这样我才能更好地帮助你。
对于您在评论中提出的问题,我只能提供一些代码让您入门,但是您必须完全理解我要做什么。
必备知识:CoreGraphics + CGAffineTransform (iOS)、viewPortHandler、transformer、axisRenderer (ios-charts)。
在我的问题中,我将 ScatterChartView 子类化,所以我可以像绘制 yAxis 一样绘制 xAxis。这个想法是禁用 xAxis,并让 rightAxis 成为 HorizontalBarChartYAxisRenderer 充当 xAxis。
首先,继承 ScatterChartView 并覆盖 initialize():
public override func initialize() {
super.initialize();
doubleTapToZoomEnabled = false;
xAxis.enabled = false;
// to determine how much space left for the dots to be drawn
_leftYAxisRenderer = ChartYAxisRenderer(viewPortHandler: _viewPortHandler, yAxis: _leftAxis, transformer: _leftAxisTransformer);
// right axis will be the bottom axis above xAxis
_rightAxisTransformer = ChartTransformerHorizontalBarChart(viewPortHandler: _viewPortHandler);
_rightYAxisRenderer = MyChartYAxisRendererHorizontalBarChart(viewPortHandler: _viewPortHandler, yAxis: _rightAxis, transformer: _rightAxisTransformer);
renderer = MyScatterChartRenderer(delegate: self, animator: _animator, viewPortHandler: _viewPortHandler);
}
覆盖prepareValuePxMatrix
internal override func prepareValuePxMatrix()
{
// replace the chartXMin and deltaX with rightAxis values to keep the CTM correct
_rightAxisTransformer.prepareMatrixValuePx(chartXMin: _rightAxis.axisMinimum, deltaX: CGFloat(_rightAxis.axisRange), deltaY: CGFloat(_leftAxis.axisRange), chartYMin: _leftAxis.axisMinimum);
_leftAxisTransformer.prepareMatrixValuePx(chartXMin: _rightAxis.axisMinimum, deltaX: CGFloat(_rightAxis.axisRange), deltaY: CGFloat(_leftAxis.axisRange), chartYMin: _leftAxis.axisMinimum);
}
到目前为止,您已经创建了充当 xAxis 的 rightAxis,并生成了它的矩阵。
现在对于数据部分,我将创建两个数据集,并通过 dataSet.axisDependency 将它们分配给 AxisDependencyLeft 和 AxisDependencyRight,这样我就可以知道如何渲染它们了。
在图表渲染器中,我将读取两个数据集,一个用于 x,一个用于 y,并利用转换器获取要绘制的位置。
如:
var xDataSet = scatterData.getRight()
var yDataSet = scatterData.getLeft()
var dataSet = yDataSet as! ScatterChartDataSet
var trans = delegate!.scatterChartRenderer(self, transformerForAxis: dataSet.axisDependency)
var phaseX = _animator.phaseX
var phaseY = _animator.phaseY
var xEntries = (xDataSet as! ScatterChartDataSet).yVals
var entries = dataSet.yVals
// if count not equal, something goes off
if (xEntries.count != entries.count)
{
return
}
var shapeSize = dataSet.scatterShapeSize
var shapeHalf = shapeSize / 2.0
var point = CGPoint()
var valueToPixelMatrix = trans.valueToPixelMatrix
var shape = dataSet.scatterShape
CGContextSaveGState(context)
for (var j = 0, count = Int(min(ceil(CGFloat(entries.count) * _animator.phaseX), CGFloat(entries.count))); j < count; j++)
{
var e = entries[j]
var xEntry = xEntries[j]
point.x = CGFloat(xEntry.value)
point.y = CGFloat(e.value) * phaseY
point = CGPointApplyAffineTransform(point, valueToPixelMatrix)
// now you have the point to render, such as:
if (shape == .Circle)
{
CGContextSetFillColorWithColor(context, dataSet.colorAt(j).CGColor)
var rect = CGRect()
rect.origin.x = point.x - shapeHalf
rect.origin.y = point.y - shapeHalf
rect.size.width = shapeSize
rect.size.height = shapeSize
CGContextFillEllipseInRect(context, rect)
}
}
我无法提供我拥有的所有代码。你必须明白我在做什么,这样你才能想象你的。唯一的魔力是你有机会定义你想如何渲染它。