- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我必须使用 pdfbox 绘制饼图。
让数据为:
学科成绩百分号累计学位设半径和中心为 100 像素和 ( 250, 400)。
让我们取平行于 x 轴的初始线。
绘制初始行语句将是:
contentStream.drawLine(250, 400, 350, 400);
我坚持了下来:
a) 找到圆上点的 x, y 坐标,该点与初始线相距一定程度以绘制半径
b) 使用贝塞尔曲线在两点之间绘制圆弧。
如能提供解决问题的帮助,我们将不胜感激!
最佳答案
根据角度在圆上找到 x、y 坐标是学校数学,即 sin() 和 cos(),棘手的部分是用贝塞尔曲线绘制圆弧。
这是一些绘制您要求的饼图的代码。请注意,createSmallArc()
只能处理最大 90° 的角度。如果您想要更多,则必须通过绘制几条弧直到返回 (0,0) 来修改代码,或者只绘制几条切片。
(createSmallArc()
由 Hans Muller 提供,许可证:Creative Commons Attribution 3.0。所做的更改:将原始 AS 代码实现到 java 中。算法由 Aleksas Riškus 提供)
public class PieChart
{
public static void main(String[] args) throws IOException
{
PDDocument doc = new PDDocument();
PDPage page = new PDPage();
doc.addPage(page);
PDPageContentStream cs = new PDPageContentStream(doc, page);
cs.transform(Matrix.getTranslateInstance(250, 400));
cs.setNonStrokingColor(Color.yellow);
drawSlice(cs, 100, 0, 80);
cs.fill();
cs.setNonStrokingColor(Color.red);
drawSlice(cs, 100, 80, 150);
cs.fill();
cs.setNonStrokingColor(Color.green);
drawSlice(cs, 100, 150, 215);
cs.fill();
cs.setNonStrokingColor(Color.blue);
drawSlice(cs, 100, 215, 305);
cs.fill();
cs.setNonStrokingColor(Color.ORANGE);
drawSlice(cs, 100, 305, 360);
cs.fill();
cs.close();
doc.save("piechart.pdf");
doc.close();
}
private static void drawSlice(PDPageContentStream cs, float rad, float startDeg, float endDeg) throws IOException
{
cs.moveTo(0, 0);
List<Float> smallArc = createSmallArc(rad, Math.toRadians(startDeg), Math.toRadians(endDeg));
cs.lineTo(smallArc.get(0), smallArc.get(1));
cs.curveTo(smallArc.get(2), smallArc.get(3), smallArc.get(4), smallArc.get(5), smallArc.get(6), smallArc.get(7));
cs.closePath();
}
/**
* From https://hansmuller-flex.blogspot.com/2011/10/more-about-approximating-circular-arcs.html
*
* Cubic bezier approximation of a circular arc centered at the origin,
* from (radians) a1 to a2, where a2-a1 < pi/2. The arc's radius is r.
*
* Returns a list with 4 points, where x1,y1 and x4,y4 are the arc's end points
* and x2,y2 and x3,y3 are the cubic bezier's control points.
*
* This algorithm is based on the approach described in:
* Aleksas Riškus, "Approximation of a Cubic Bezier Curve by Circular Arcs and Vice Versa,"
* Information Technology and Control, 35(4), 2006 pp. 371-378.
*/
private static List<Float> createSmallArc(double r, double a1, double a2)
{
// Compute all four points for an arc that subtends the same total angle
// but is centered on the X-axis
double a = (a2 - a1) / 2;
double x4 = r * Math.cos(a);
double y4 = r * Math.sin(a);
double x1 = x4;
double y1 = -y4;
double q1 = x1*x1 + y1*y1;
double q2 = q1 + x1*x4 + y1*y4;
double k2 = 4/3d * (Math.sqrt(2 * q1 * q2) - q2) / (x1 * y4 - y1 * x4);
double x2 = x1 - k2 * y1;
double y2 = y1 + k2 * x1;
double x3 = x2;
double y3 = -y2;
// Find the arc points' actual locations by computing x1,y1 and x4,y4
// and rotating the control points by a + a1
double ar = a + a1;
double cos_ar = Math.cos(ar);
double sin_ar = Math.sin(ar);
List<Float> list = new ArrayList<Float>();
list.add((float) (r * Math.cos(a1)));
list.add((float) (r * Math.sin(a1)));
list.add((float) (x2 * cos_ar - y2 * sin_ar));
list.add((float) (x2 * sin_ar + y2 * cos_ar));
list.add((float) (x3 * cos_ar - y3 * sin_ar));
list.add((float) (x3 * sin_ar + y3 * cos_ar));
list.add((float) (r * Math.cos(a2)));
list.add((float) (r * Math.sin(a2)));
return list;
}
}
如果您在切片之间看到白线并且不想要它,请参阅 this answer .
关于java - 如何使用pdfbox绘制饼图?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40781610/
有人可以帮我理解为什么我的饼图百分比计算不正确吗?看截图: 根据我的计算,如 RHS 上所示,支出百分比应为 24.73%。传递给 Highcharts 的值如下:- 花费:204827099.36-
我正在制作圆环饼图。 我设置数据的颜色并获取钻取(它是保存外部切片的数据和配置的对象)切片的颜色为同一组颜色。我想设置要在向下钻取对象中使用的不同颜色数组。请参阅附图(外层切片有两种颜色:橙色和透明)
我是一名优秀的程序员,十分优秀!