# 在 SVG 中呈现动态图形

## 一点高中数学知识

• A=100
• B=50
• C=25

• 为了简单起见，Y 轴的高度设为 1000 像素，这样计算起来很方便。
• 数据集中的最大值是 100（A）。
• 对于该图，比例因子应该是： 1000/100 = 10
• 因此对于这个柱状图，每单位的值在高度上用 10 个像素表示。
• 要得到每个条的高度，只需要用比例因子乘上数据集中的值即可，就是说每个条的高度为：

• A=2000
• B=5000
• C=800

##### 清单 1. 计算 Y 轴比例因子
`51.	YAxisScalingFactor = 1000/(double)largestNumber;`

##### 清单 2. 标记 Y 轴
```86.	SVGout.write("\n <text style=\"fill:black; stroke:none\"
x=\"-10\" y=\"0\" >" + largestNumber + "</text>");
87.	SVGout.write("\n <text style=\"fill:black; stroke:none\"
x=\"-10\" y=\"500\" >" + (largestNumber/2) + "</text>");```

##### 清单 3. 绘制条
```90.// The graph is ready to be rendered with the values.
91.for(i=0;i<barChartValues.length;i++){
92.
93. // Calculate the Y position. First work out how high the bar
94. // will be by multiplying the value by the scaling factor.
94. // calculated earlier
95. double barHeight =
96.    Integer.parseInt(barChartValues[i]) * YAxisScalingFactor;
97.
98. System.out.println("Bar Height is =" + barHeight);
99.
100. // You now have the height that the bar will be. Need to work
101. // out now where to place the bar. With Y values running
102. // positively down, and the Y-axis being 1000 pixels tall,
103. // simply subtract the  bar height from 1000 to get the position
104. // of where to place the bar.
105.
106. double YStart = 1000 - barHeight;
107.
108. // Each of the bars is 100 pixels wide. So to space them out
109. //(with a 10-pixel gap between them), multiply the readings position
110. // in the array by 110.
111.
112. double XPosition = (i*110);
113.
114. // Generate some random numbers for your bar colours
115. int randomRed = random.nextInt(255);
116. int randomGreen = random.nextInt(255);
117. int randomBlue = random.nextInt(255);
118.
119. // You now have all your values ready. Draw the rectangle.
120. SVGout.write("\n<rect x=\""+XPosition+"\" y=\""+
121.  YStart+"\" width =\""+ 100 +"\" height=\""+barHeight+
122.  "\" style=\"fill:rgb("+randomRed+"
123.  ,"+randomGreen+","+randomBlue+");\" /> ");
124.
125.}```

## 线图

`10,20,30,50,90,25,45,60,70,10`

`<polyline points="0 0, 10 10, 20 20">`

##### 清单 4. 计算 X 轴的比例因子
`40. XAxisScalingFactor = 1000/(double)valuesToPlot.length;`

Y 轴比例因子是在第 104 行计算的，方法和上面的柱状图使用的方法一样（请参阅 清单 2）。

##### 图 5. 绘制折线
```108. // Render the line
109. SVGout.write("\n<polyline points=\"0 1000,");
110.
111. for(i=0;i<valuesToPlot.length;i++){
112.
113.  // Calculate the X position by determining which
114.  //value in the array you are dealing with.
115.  XValue = ((i+1)*XAxisScalingFactor);
116.
117.  YValue = Integer.parseInt(valuesToPlot[i]);
118.  YValue = YValue*YAxisScalingFactor;
119.  YValue = 1000-YValue;
120.
121.  // You now have your polyline point.
122.  SVGout.write(" " + XValue + " " + YValue +",\n");
123.
124. }
125. // Close off the polyline.
126. SVGout.write("\" style=\"stroke:red; stroke-width: 3; fill :
127. none;\"/>");```

• `XAxisScalingFactor` = `1000/(double)valuesToPlot.length;`
• `XAxisScalingFactor` = `1000/(double)50;`
• `XAxisScalingFactor` = `20`

• 第 1 个点： x=20,<1st value>
• 第 2 个点： x=40,<2nd value>
• 第 3 个点： x=60,<3rd value>
• ...
• ...
• 第 49 个点： x=980,<49th value>
• 第 50 个点： x=1000,<50th value>

1. 第 117 行从数组中提取数据并转化成整数。
2. 第 118 行将该值乘以 Y 轴的比例因子，以确定其位置。
3. 最后从 1000 中减去这个值，这是因为 Y 轴是从页面的上方向下增长，X 轴从 Y 轴的第 1000 个像素的位置开始绘制，因此，要确定计算得到的 Y 值在 X 轴的上方多远的位置上，就必须从 1000 中减去它。

## 散点图

##### 清单 6. 计算和绘制散点图
```122. // The axis and the guide lines are ready; now draw the data.
123. SVGout.write("\n    <g style=\"fill:none;
124. stroke:red; stroke-width:3\">");
125.
126. for(i=0;i<dataToPlot.length;i++){
127.
128.    // Get the value out of the array.
129.	String value = dataToPlot[i];
130.
131.	// The data is in the form (X-Value),(Y-Value), so find
132.	// the comma and get the values on either side of it.
133.	index = value.indexOf (',');
134.	String X_Pos = value.substring(0,index);
135.	String Y_Pos = value.substring(index+1);
136.
137.	// Change them to numbers
138.	XValue = Integer.parseInt(X_Pos);
139.	YValue = Integer.parseInt(Y_Pos);
140.
141.	// Calculate the point's position by using the scaling
142.	// factor calculated earlier
143.	XValue = XValue*XAxisScalingFactor;
144.	YValue = YValue*YAxisScalingFactor;
145.	YValue = 1000-YValue;
146.
147.	// You now have your point. As it's a scatter plot, it
148.	// would look nice with an X, so use the point to draw
149	// a line from the top left to the bottom right, and from
150.	// the top right to the bottom left.
151.
152.	SVGout.write("\n  <line x1=\""+ (int)(XValue-5) +
153		"\" y1=\""+(int)(YValue+5)+ "\" x2=\""+(int)(XValue+5)+
154.	"\" y2=\""+(int)(YValue-5)+"\" />");
155.	SVGout.write("\n  <line x1=\""+ (int)(XValue+5) +
156.	"\" y1=\""+(int)(YValue+5)+ "\" x2=\""+(int)(XValue-5)+
157.	"\" y2=\""+(int)(YValue-5)+"\" />");
158.}```

## 结束语

#### 评论

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=XML
ArticleID=49153
ArticleTitle=在 SVG 中呈现动态图形
publish-date=11012004