رسم نمودارهای ۳ بعدی در iOS با Plot3d – از صفر تا صد
رسم دادهها در سه بُعد، روشی عالی برای بصریسازی آنها محسوب میشود. یک نمودار سه بعدی از دادهها موجب برانگیختن خلاقیت میشود. در iOS رسم نمودار در سه بعد کمی چالشبرانگیز است، زیرا فریمورک های زیادی برای استفاده به این منظور وجود ندارند و تنها گزینه موجود نیز رایگان نیست. Plot3d یک پروژه اوپن سورس است که میتوان از آن برای رسم نمودارهای 3 بعدی در iOS بهره جست.
طرز کار Plot3d
Plot3d از SceneKit (+) برای بازنمایی دادهها در سه بُعد بهره میگیرد. در دو بخش بَعدی توضیح مختصری در مرود این فریمورکها ارائه میکنیم.
توضیح SceneKit
در SceneKit یک SCNScene به جایی گفته میشود که همه اشیای 3 بعدی در آن حضور دارند. هر شیء بصری در یک صحنه در واقع یک SCNScene است. یک هندسه (Geometry) به هر SCNScene الصاق یافته است که یک عنصر ساختاری از یک صحنه محسوب میشود و موقعیت و تبدیل آن را در یک فضای با مختصات سه بعدی نشان میدهد.
توضیح Plot3d
Plot3d برای مدیریت یک صحنه که شامل همه گرهها و هندسه مورد نیاز برای رسم دادهها در فضای سه بعدی است از یک PlotView استفاده میکند. PlotView یک زیرکلاس از UIView است و هر چیزی که در صحنه باشد به یک PlotSpaceNode اضافه میشود.
PlotSpaceNode در واقع گره ریشه یک صحنه در یک PlotView است. اغلب عملیات سه بعدی در یک فضای نموداری (plot-space) مدیریت میشود که از دید توسعهدهنده پنهان است. دادههایی که باید در یک plot-space رسم شوند، با استفاده از یک منبع داده شناسایی شده و با الگویی مشابه شیوه استفاده از UITableView رسم میشوند.
کاربرد عملی Plot3d
برای شروع صرفاً یک نما با پیکربندی مفروض ایجاد میکنیم و سپس دادهها را ارائه میکنیم. در همه کدهای زیر فرض شده است که از یک UIViewController استفاده میکنیم.
ایجاد یک PlotView
ابتدا یک PlotView را با پیکربندی سفارشی مقداردهی میکنیم و سپس عناوین محورها را تعیین میکنیم:
1// Configure the plot.
2var config = PlotConfiguration()
3config.xAxisHeight = 3
4config.yAxisHeight = 4
5config.zAxisHeight = 3
6config.xTickInterval = 1
7config.zTickInterval = 1
8config.xMax = 6
9config.zMax = 6
10
11// Initialize the PlotView
12let frame = CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height)
13let plotView = PlotView(frame: frame, configuration: config)
14view.addSubview(plotView)
15
16// When using a custom configuration, the camera's position and orientation might need to be updated
17plotView.setCamera(position: PlotPoint(10, 6, 10))
18plotView.setCamera(lookAt: PlotPoint(0, 0, 0))
19
20plotView.setAxisTitle(.x, text: "x axis", textColor: .white)
21plotView.setAxisTitle(.y, text: "y axis", textColor: .white)
22plotView.setAxisTitle(.z, text: "z axis", textColor: .white)
رسم 3 بعدی
یک فضای plot دادهها را با استفاده از یک PlotDataSource و یک PlotDelegate رسم میکند. از آنجا که PlotDataSource افشا نشده است، منبع داده و delegate از طریق PlotView انتساب مییابند.
برای رسم دادهها کنترلر نما را طوری بسط میدهیم که پروتکلهای data source و delegate را پیادهسازی کند و سپس آنها را به نمای plot انتساب میدهیم.
plotView.dataSource = self plotView.delegate = self plotView.reloadData()
PlotDataSource
منابع داده برای تعیین تعداد نقاطی که باید رسم شده و اتصالهایی برقرار شوند مورد استفاده قرار میگیرد. فضای plot زیرین روی مقادیر مفروض حلقهای تعریف میکند و هر نقطه و اتصال را بر همین اساس رسم میکند.
1extension ViewController: PlotDataSource {
2 func numberOfPoints() -> Int {
3 return 33 // The example in this artcile will only need a fixed number of points.
4 }
5}
PlotDelegate
در ادامه برخی از متدهای delegate که میتوانند برای ارائه دادهها به فضای نمودار پیادهسازی شوند، ارائه شدهاند:
- یک PlotPoint (مختصات 3 بعدی) برای رسم هر نقطه ارائه شود (پیادهسازی ضروری است).
- هندسه برای استفاده در هر نقطه رسم شده ارائه میشود (پیادهسازی ضروری است).
- PlotText برای استفاده در هر علامت تیک ارائه میشود (پیادهسازی اختیاری است).
1extension ViewController: PlotDelegate {
2
3 // 1
4 func plot(_ plotView: PlotView, pointForItemAt index: Int) -> PlotPoint {
5 let v = CGFloat(index % 16)
6 if index < 16 {
7 return PlotPoint(cos(v) + 5, v, sin(v) + 5)
8 }
9 return PlotPoint(cos(v + 1.57) + 5, v, sin(v + 1.57) + 5)
10 }
11
12 // 2
13 func plot(_ plotView: PlotView, geometryForItemAt index: Int) -> SCNGeometry? {
14 let geo = SCNSphere(radius: 0.15)
15 if index < 16 {
16 geo.materials.first!.diffuse.contents = UIColor.red
17 } else {
18 geo.materials.first!.diffuse.contents = UIColor.blue
19 }
20 return geo
21 }
22
23 // 3
24 func plot(_ plotView: PlotView, textAtTickMark index: Int, forAxis axis: PlotAxis) -> PlotText? {
25 let config = PlotConfiguration()
26 switch axis {
27 case .x:
28 return PlotText(text: "\(index + 1)", fontSize: 0.3, offset: 0.25)
29 case .y:
30 return PlotText(text: "\(Int(CGFloat(index + 1) * config.yTickInterval))", fontSize: 0.3, offset: 0.1)
31 case .z:
32 return PlotText(text: "\(index + 1)", fontSize: 0.3, offset: 0.25)
33 }
34 }
35}
افزودن اتصالها
میتوانیم نمودار را یک گام به پیش بریم و اتصالهایی بین نقاط رسم شده نیز برقرار سازیم تا بصریسازی دادهها آسانتر شود. با افزودن کد زیر به PlotDataSource تعداد اتصالهایی که باید برقرار شوند را ذکر میکنیم:
1func numberOfConnections() -> Int {
2 return 47
3}
با افزودن کد زیر به PlotDelegate نقاطی که باید اتصال یابند و شیوه نمایش اتصال را تعیین میکنیم:
1// Connect the points in a way that creates a double helix.
2func plot(_ plotView: PlotView, pointsToConnectAt index: Int) -> (p0: Int, p1: Int)? {
3 guard index != 31 else {
4 return nil
5 }
6
7 if index < 16 {
8 return (p0: index, p1: index + 16)
9 }
10
11 let i = index - 16
12 return (p0: i, p1: i + 1)
13}
14
15// Define the geometry of each connection.
16func plot(_ plotView: PlotView, connectionAt index: Int) -> PlotConnection? {
17 if index < 16 {
18 return PlotConnection(radius: 0.025, color: .green)
19 }
20
21 if index - 16 < 16 {
22 return PlotConnection(radius: 0.04, color: .red)
23 } else {
24 return PlotConnection(radius: 0.04, color: .blue)
25 }
26}
سخن پایانی
هدف از Plot3d آسانتر ساختن ایجاد بصریسازیهای 3 بعدی از دادهها در iOS است. اگرچه ممکن است تقاضای گرافهای 3 بعدی روی آیفون چندان بالا نباشد، اما به هر حال آشنایی با یک کتابخانه اوپن سورس برای انجام این کار موجب آسودگی خیال ما میشود.
اگر این مطلب برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای برنامهنویسی
- آموزش برنامه نویسی Swift (سوئیفت) برای برنامه نویسی iOS
- مجموعه آموزشهای دروس علوم و مهندسی کامپیوتر
- پنج کتابخانه iOS برای بهبود اپلیکیشنها — راهنمای کاربردی
- ۵ کتابخانه iOS برای توسعه بهینه اپلیکیشنها — فهرست کاربردی
==