- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在尝试学习和理解 CoreGraphics。我想做的是制作饼图。
饼图工作正常并且看起来很棒,但我在剪裁内圆时遇到了问题。
这是饼图中每张幻灯片的代码:
CGPoint center = CGPointMake((self.bounds.size.width/2) + self.centerOffset, (self.bounds.size.height/2) - self.centerOffset);
CGFloat radius = MIN(center.x, center.y) - 25;
radius *= self.pieScale;
CGContextBeginPath(ctx);
CGContextMoveToPoint(ctx, center.x, center.y);
CGPoint p1 = CGPointMake(center.x + radius * cosf(self.startAngle), center.y + radius * sinf(self.startAngle));
CGContextAddLineToPoint(ctx, p1.x, p1.y);
int clockwise = self.startAngle > self.endAngle;
CGContextAddArc(ctx, center.x, center.y, radius, self.startAngle, self.endAngle, clockwise);
CGContextClosePath(ctx);
CGContextMoveToPoint(ctx, center.x, center.y);
CGContextAddArc(ctx, center.x, center.y, radius*0.5, self.startAngle, self.endAngle, clockwise);
CGContextSetFillColorWithColor(ctx, self.fillColor.CGColor);
CGContextSetStrokeColorWithColor(ctx, self.strokeColor.CGColor);
CGContextSetLineWidth(ctx, self.strokeWidth);
self.pathRef = CGContextCopyPath(ctx);
CGContextDrawPath(ctx, kCGPathFillStroke);
我现在的馅饼是这样的:
我设法通过绘制一条半径较小的新路径来添加一个内圆。
我尝试用 CGContextClip(ctx);
剪辑第二条路径,但只留下像这样的内圈:
对我来说有点道理为什么会这样,但我想不出我还应该做什么。
编辑:
代码现在看起来像:
CGPoint center = CGPointMake((self.bounds.size.width/2) + self.centerOffset, (self.bounds.size.height/2) - self.centerOffset);
CGFloat radius = MIN(center.x, center.y) - 25;
radius *= self.pieScale;
CGPoint p1 = CGPointMake(center.x + radius * cosf(self.startAngle), center.y + radius * sinf(self.startAngle));
int clockwise = self.startAngle > self.endAngle;
CGContextBeginPath(ctx);
CGContextMoveToPoint(ctx, center.x, center.y);
CGContextAddLineToPoint(ctx, p1.x, p1.y);
CGContextAddArc(ctx, center.x, center.y, radius, self.startAngle, self.endAngle, clockwise);
CGContextClosePath(ctx);
CGContextMoveToPoint(ctx, center.x, center.y);
CGContextAddArc(ctx, center.x, center.y, radius*0.5, self.startAngle, self.endAngle, !clockwise);
CGContextSetFillColorWithColor(ctx, self.fillColor.CGColor);
CGContextSetStrokeColorWithColor(ctx, self.strokeColor.CGColor);
CGContextSetLineWidth(ctx, self.strokeWidth);
self.pathRef = CGContextCopyPath(ctx);
CGContextDrawPath(ctx, kCGPathFillStroke);
看起来像:
所有绘图代码:
我的类是 CALayer 的子类。此代码在饼图上绘制一个切片。
-(void)drawInContext:(CGContextRef)ctx
{
CGPoint center = CGPointMake((self.bounds.size.width/2) + self.centerOffset, (self.bounds.size.height/2) - self.centerOffset);
CGFloat radius = MIN(center.x, center.y) - 25;
radius *= self.pieScale;
int clockwise = self.startAngle > self.endAngle;
/* Clipping should be done first so the next path(s) are not creating the clipping mask */
CGContextMoveToPoint(ctx, center.x, center.y);
CGContextAddArc(ctx, center.x, center.y, radius*0.5, self.startAngle, self.endAngle, !clockwise);
//CGContextClipPath(ctx);
CGContextClip(ctx);
/* Now, start drawing your graph and filling things in... */
CGContextBeginPath(ctx);
CGContextMoveToPoint(ctx, center.x, center.y);
CGPoint p1 = CGPointMake(center.x + radius * cosf(self.startAngle), center.y + radius * sinf(self.startAngle));
CGContextAddLineToPoint(ctx, p1.x, p1.y);
CGContextAddArc(ctx, center.x, center.y, radius, self.startAngle, self.endAngle, clockwise);
CGContextClosePath(ctx);
CGContextSetFillColorWithColor(ctx, self.fillColor.CGColor);
CGContextSetStrokeColorWithColor(ctx, self.strokeColor.CGColor);
CGContextSetLineWidth(ctx, self.strokeWidth);
self.pathRef = CGContextCopyPath(ctx);
CGContextDrawPath(ctx, kCGPathFillStroke);
// LABELS
UIGraphicsPushContext(ctx);
CGContextSetFillColorWithColor(ctx, self.labelColor.CGColor);
CGFloat distance = [self angleDistance:(self.startAngle * 180/M_PI) angle2:(self.endAngle * 180/M_PI)];
CGFloat arcDistanceAngle = distance * M_PI/180;
CGFloat arcCenterAngle = self.startAngle + arcDistanceAngle/2;
CGPoint labelPoint = CGPointMake(center.x + radius * cosf(arcCenterAngle), center.y + radius * sinf(arcCenterAngle));
/*
Basic drawing of lines to labels.. Disabled for now..
CGContextBeginPath(ctx);
CGContextMoveToPoint(ctx, labelPoint.x, labelPoint.y);
*/
if(labelPoint.x <= center.x)
labelPoint.x -= 50;
else
labelPoint.x += 5;
if(labelPoint.y <= center.y)
labelPoint.y -= 25;
/*
Basic drawing of lines to labels.. Disabled for now..
CGContextAddLineToPoint(ctx, labelPoint.x, labelPoint.y);
CGContextClosePath(ctx);
CGContextSetFillColorWithColor(ctx, self.fillColor.CGColor);
CGContextSetStrokeColorWithColor(ctx, self.strokeColor.CGColor);
CGContextSetLineWidth(ctx, self.strokeWidth);
CGContextDrawPath(ctx, kCGPathFillStroke);
*/
[self.labelString drawAtPoint:labelPoint forWidth:50.0f withFont:[UIFont systemFontOfSize:18] lineBreakMode:NSLineBreakByClipping];
UIGraphicsPopContext();
}
最佳答案
如果您不想拥有饼图的中心(即制作所谓的 donut 车),那么我建议您创建独立的 donut 部分的形状,而不是制作饼图切片并遮住中心。
可能首先想到的是用两条直线和两条半径不同但中心坐标相同的圆弧共同创建该线段。幸运的是,在 Core Graphics 中有更简单的方法来制作这种形状。这种形状实际上只是一个角度和另一个角度之间的单一弧形,但更粗。我已经在 this answer 中解释了这一切(针对“从圆形或 donut 中绘制线段”的问题),但这里只是对 donut 线段形状的简短解释。
创建将位于 donut 段中心的圆弧(下图中的橙色线)。半径将为 (r<sub>max</sub> + r<sub>min</sub>) / 2
.
CGMutablePathRef arc = CGPathCreateMutable();
CGPathMoveToPoint(arc, NULL,
startPoint.x, startPoint.y);
CGPathAddArc(arc, NULL,
centerPoint.x, centerPoint.y,
radius,
startAngle,
endAngle,
YES);
通过描边圆弧创建最终的 donut 段形状。这个功能对你来说可能看起来很神奇,但这就是在 Core Graphics 中找到隐藏宝藏的感觉。它将以特定的描边宽度描边路径。 “线帽”和“线连接”控制形状的开始和结束的外观以及路径组件之间的连接方式(此形状中只有一个组件)。
CGFloat lineWidth = 10.0; // any radius you want
CGPathRef donutSegment =
CGPathCreateCopyByStrokingPath(arc, NULL,
lineWidth,
kCGLineCapButt,
kCGLineJoinMiter, // the default
10); // 10 is default miter limit
像填充饼图一样填充此形状。 (上图 2 中使用了浅灰色和黑色)。
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextAddPath(c, donutSegment);
CGContextSetFillColorWithColor(c, [UIColor lightGrayColor].CGColor);
CGContextSetStrokeColorWithColor(c, [UIColor blackColor].CGColor);
CGContextDrawPath(c, kCGPathFillStroke);
关于ios - CALayer clip CGContextAddArc(制作 donut 幻灯片/饼图),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18614376/
我一直致力于使用 highcharts 复制此图表设计。 我一直在玩 jsfiddle 试图获得想要的结果,但问题是我无法设法获得百分比未填充的白色区域,也无法获得条形之间的间隙。 使用 highch
我正在使用 Steema.TeeChart for .Net(用 C# 编码) 有人知道如何在圆环图的饼图内做标签吗? 它应该看起来像: http://www.steema.com/uploads/g
当点击内部 donut 时,我试图将内部和其他 donut 滑出。在下面的链接中,只切掉了内部 donut 。 http://jsfiddle.net/bvL0r6tq/ 我试图通过点选择选择外部切片
我正在尝试将内部 donut 名称设置为 highchart 中外部 donut 工具提示的标题。任何人都可以帮我解决这个问题。在示例中,内部饼图上显示的链接镶边应显示为外部 donut 工具提示中所
我正在使用 jqplot 设置一个具有两个级别的圆环图,但有两个问题,我偷偷怀疑它们是相关的。 当我将设置保留为默认设置时,它会正确显示,但一旦我开始设置直径、内径等。尺寸适用于内部和外部图表,并且它
我想制作一个 donut 风格的饼图,在特定的 donut 扇区带有弯曲的标签,就像这个: 在此模型中,用户单击了“Raphael.js”扇区。现在对于单击的扇区,还应该有一个事件处理程序,负责在饼图
我是编程新手,如果问题很愚蠢,我很抱歉。我正在用 chart.js 做一些图形. 我已经成功地通过 onclick 事件在另一个内部创建了一个 donut ,我遇到的问题是它为每次点击生成一个 don
您好,我想实现一个像这样的 donut 菜单 http://dribbble.com/shots/610433-Wheel-Nav我知道有一种在 css3 中制作 donut 的简单方法。 .doug
我创建了一个带有 highcharts 的饼图,效果很好。现在我想做的是当我悬停一个区域时,我想突出显示它的 parent 和 child ,并在工具提示中显示他们的所有数据。 这是我的图表: htt
我正在尝试增加圆环图的内半径,并且还能够在圆环图内写入。 $scope.donut = new RGraph.Pie('myDonut', $scope.donutData) .
我有一个简单的 SVG donut ,其中使用 stroke-dashoffset="xx"放置了 5 个相等的切片。 donut 本身看起来不错,但是当我尝试为每个切片添加一些悬停更改时,例如,简单
板级: import java.awt.*; import java.awt.geom.AffineTransform; import java.awt.geom.Ellipse2D; import
请帮我修改代码。我使用 D3 v5.7.0 并尝试绘制 donut 。 现场演示 is here. 我的代码在这里: const dataset = [ [ 5, 3 ] ]; const s
我使用 highchart 库开发了一个圆环图。我需要在 donut 的内部添加一个标签。 预期结果: JS: $(function () { $('#container8').highcha
我在 Highcharts 中对 donut 中的馅饼很感兴趣,但我似乎无法显示图例或共享工具提示。工作正常with non-shared tooltips : tooltip: {
我创建了一个圆环图,如下所示: 我生成的 donut chart 应采用以下方式: 我的问题是,我怎样才能用图像实现线条(它们在第二个屏幕截图中四舍五入) 供引用,这是我编写的代码: public c
我有一个 2D map ,它在边缘处环绕。因此,如果您离开右边缘,您将重新出现在 map 的左侧。其他三个边也是如此。 这是我用来在点范围内查找元素的 KDTree 的可继承问题。通常,您会检查超球体
我正在使用 Plotly 来绘制 Donut Plot。下面你可以看到我的数据 df1% plot_ly(labels = ~manuf, values = ~count) fig % add_pie
我正在尝试为圆圈内的点生成一个分布,其中有更多的点朝向中心,但对于 donut 形状 我可以制作一个均匀分布的 donut 形状 (1),或者一个有更多点朝向中心的圆圈 (2),但不能制作一个有这么多
http://www.mediafire.com/view/z8ad4pedqr7twbl/donut.png 我想像那个图像一样绘制这个 donut 。我已经使用 raphaeljs 来绘制它。但是
我是一名优秀的程序员,十分优秀!