วาดกราฟข้อมูลจากเซ็นเซอร์ที่เชื่อมต่อกับ Internet of Things (IoT) ด้วย SVG
ในบทความนี้ในซีรีส์เรื่อง แสดงกราฟข้อมูลใน IoT ฉันอธิบายวิธีการพล็อตกราฟโดยใช้ ภาษา SVG. ในโอกาสอื่นๆ บทความนี้ยังทำหน้าที่เป็นการแนะนำสั้นๆ เกี่ยวกับภาษาอีกด้วย
รูปแบบ SVG
SVG สอดคล้องกับตัวย่อของ Scalable Vector Graphics (กราฟิกเวกเตอร์ที่ปรับขนาดได้ เป็นภาษาอังกฤษ) มันคือ ภาษามาร์กอัป ซึ่งขึ้นอยู่กับ XML และนั่นช่วยให้สามารถอธิบายการวาดภาพตามเรขาคณิตที่กำหนดได้เป็นหลัก ตรงข้ามกับวิธีเมทริกซ์ ซึ่งใช้สำหรับภาพถ่าย ซึ่งจะใช้ตารางพิกเซลสีเพื่อเข้ารหัส
ภายในภาพวาด SVG นอกจากนี้ยังสามารถรวมรูปภาพ (เมทริกซ์พิกเซล) ไว้ด้วย โดยอ้างอิงถึงเอกสารภายนอกหรือฝังอยู่ภายในภาพวาดก็ได้ SVG.
เวอร์ชันภาษาปัจจุบัน ณ เวลาที่เขียนบทความนี้คือ เอสวีจี 1.1 แม้ว่าคำจำกัดความของเวอร์ชันจะได้รับการพัฒนาแล้วก็ตาม เอสวีจี 2. ฉันจะพยายามทำให้สิ่งที่อธิบายไว้ในบทนำให้มากที่สุดเท่าที่จะเป็นไปได้ แม้ว่าจะหมายถึงก็ตาม เอสวีจี 1.1 ยังทำหน้าที่เพื่อ เอสวีจี 2.
ถ้าเป็นการวาดภาพ SVG รวมอยู่ในเอกสารแยกต่างหากและไม่ได้อยู่ในโค้ด HTML (ข้อเสนอของฉันในโซลูชันนี้เพื่อแสดงข้อมูล IoT ฝังไว้ในโค้ด HTML) จะต้องนำหน้าด้วยการอ้างอิง XML และ คำจำกัดความประเภทเอกสาร (DTD).
1
2
|
<?xml version=“1.0” encoding=“utf-8” standalone=“yes”?>
<!DOCTYPE svg PUBLIC “-//W3C//DTD SVG 1.1//EN” “http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd”>
|
ในบรรทัดแรกของโค้ดก่อนหน้า เวอร์ชันจะได้รับแจ้ง XML ใช้ (1.0) การเข้ารหัสอักขระ (UTF-8) และระบุว่าคุณต้องการคำจำกัดความภายนอก (standalone="no"
) หรือเป็นเอกสารแบบสแตนด์อโลน (standalone="yes"
). บรรทัดที่ 2 แสดงถึง คำจำกัดความประเภทเอกสาร (DTD)ซึ่งจะไม่จำเป็นในเวอร์ชันถัดไปของ SVG.
รหัสที่ใช้กำหนดรูปวาดนั้นอยู่ระหว่างป้ายกำกับ <sgv>
y </sgv>
ซึ่งก็บ่งบอกดังที่กล่าวไปแล้วเมื่อพูดถึง โค้ด HTML ที่ทำหน้าที่เป็นคอนเทนเนอร์สำหรับกราฟข้อมูลใน IoTการวัด ส่วนของผลรวมที่แสดง สัดส่วน รวมถึงประเภทและเวอร์ชันด้วย
1
2
3
4
5
6
7
|
<?xml version=“1.0” standalone=“yes”?>
<!DOCTYPE svg PUBLIC “-//W3C//DTD SVG 1.1//EN” “http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd”>
<svg width=“500px” height=“250px” viewBox=“20 10 460 80” preserveAspectRatio=“none” xmlns=“http://www.w3.org/2000/svg” version=“1.1”>
<!–
dibujo en formato SVG
–>
</svg>
|
ตัวอย่างข้างต้นกำหนดภาพวาดที่มีความกว้าง 500 พิกเซล x สูง 250 พิกเซล (วิวพอร์ต 500x250) ที่จะครอบตัดด้วยสี่เหลี่ยมขนาด 460x80 (ช่องมองภาพ 460x80) เริ่มต้นที่พิกัด 20,10 โดยใช้พื้นที่ทั้งหมดที่มีอยู่ในคอนเทนเนอร์ (องค์ประกอบบนหน้าเว็บ ใน กรณีของเรา) โดยไม่คำนึงถึงสัดส่วนการใช้งานเดิม preserveAspectRatio="none"
. นอกจากนี้ คุณสามารถดูเนื้อหาแรกของเอกสาร รวมถึงความคิดเห็นที่รวมอยู่ด้วย <!--
y -->
เช่นเดียวกับในรูปแบบอื่น ๆ ตาม XML.
ระบบพิกัดที่เลือกโดย SVG มีการวางแนวในแนวนอน (แกน X) และแนวตั้ง (แกน Y) และทิศทางบวกคือทิศทางของการเขียนแบบตะวันตก กล่าวคือ ค่าของแกน X จะเพิ่มขึ้นไปทางขวา และค่าบวกของแกน Y จะเพิ่มขึ้น ลง.
กำหนดกราฟด้วย SVG
ในการกำหนดกราฟิกของข้อมูลที่เก็บไว้โดยเซ็นเซอร์ของเราที่เชื่อมต่อกับ IoT เราจะต้องระบุประเภทของวัตถุที่วาด เรขาคณิต (พิกัด ขนาด...) และรูปลักษณ์ของมัน (ความหนา สี...) ใน ตัวอย่างของบทความนี้ กราฟเส้นที่สามารถทำได้โดยการรวมส่วนของเส้นตรงเข้ากับวัตถุ line
มีประโยชน์มากที่สุดสำหรับการวางแผนองค์ประกอบอิสระ หรือวัตถุที่มีเส้นหลายส่วน path
ใช้งานได้จริงมากขึ้นสำหรับชุดสายที่เชื่อมต่อกัน
ด้วยองค์ประกอบ path
จุดมุ่งหมายคือการสร้างภาพวาดเหมือนในภาพด้านล่าง ซึ่งประกอบด้วยเส้นทางปิดที่เต็มไปด้วยสีอ่อนกว่าและปิดด้านบนด้วยเส้นทางเปิด โดยไม่ต้องเติมและวาดด้วยเส้นหนา
ในการอธิบายบรรทัดจะใช้นิพจน์ประเภท:
1
|
<line x1=“10.0” y1=“20.0” x2=“30.0” y2=“40.0” stroke-width=“5” />
|
โดยที่ X1,Y1 คือพิกัดของจุดแรกบนเส้นตรง และ X2,Y2 คือพิกัดของจุดที่สอง มีการใช้แอตทริบิวต์ stroke-width
เพื่อกำหนดความหนา มีหลายวิธีในการกำหนดลักษณะที่ปรากฏของวัตถุ SVGด้วยคุณสมบัติเฉพาะตัว เช่นเดียวกับคุณสมบัติก่อนหน้า หรือด้วยคุณสมบัติ style
ซึ่งนำทั้งหมดมารวมกันและเป็นวิธีการที่จะใช้ในข้อเสนอบทความ
1
|
<line x1=“10.0” y1=“20.0” x2=“30.0” y2=“40.0” style=“stroke:#205587; stroke-width:5; stroke-opacity:1.0;” />
|
รหัสข้างต้นเข้าร่วมในคุณสมบัติ style
ค่าของ stroke
(สีของเส้นขีด) stroke-width
(ความหนาของเส้น) และ stroke-opacity
(ความทึบของวัตถุ)
คำอธิบายของวัตถุ path
มีรูปแบบ
1
|
<path d=“M 10.0,20.0 L 30.0,40.0 L 50.0,60.0 L 70.0,80.0 Z” style=“fill:#A8C3EA; fill-opacity:1.0; stroke:#205587; stroke-width:2; stroke-opacity:1.0;” />
|
รหัสข้างต้นใช้การดำเนินการ SVG M
, L
y Z
ภายในทรัพย์สิน d
ซึ่งหมายถึงตามลำดับ "moveto" (ย้ายไป), "lineto" (line to) และ "closepath" (เส้นทางปิด) สามารถแสดงเป็นตัวพิมพ์ใหญ่หรือตัวพิมพ์เล็กเพื่อระบุค่าสัมบูรณ์หรือค่าสัมพัทธ์ตามความเหมาะสม (ในกรณีของ Z
เช่น ไม่มีความเกี่ยวข้อง) มีการดำเนินการอื่นๆ อีกมากมาย เช่น เราสามารถวาดเส้นโค้งวงกลม เส้นโค้งวงรี เส้นโค้งเบซิเยร์... ซึ่งเราไม่ต้องใช้ในตัวอย่างนี้
แม้ว่าข้อเสนอนี้จะวาดกราฟเส้นที่สามารถล้อมรอบพื้นที่ได้ แต่การวาดองค์ประกอบง่ายๆ อื่นๆ เพื่อทำเครื่องหมายจุดหรือเน้นพื้นที่ก็มีประโยชน์ ของที่มีอยู่ใน SVG รูปหลายเหลี่ยม (ซึ่งคุณสามารถวาดไส้ได้) สี่เหลี่ยม (สะดวกกว่าสำหรับกรณีเฉพาะ) วงรีและวงกลม (ในกรณีของวงรีโดยเฉพาะ) อาจเป็นเรื่องที่น่าสนใจ ไวยากรณ์ขององค์ประกอบเหล่านี้สามารถดูได้ในโค้ดตัวอย่างต่อไปนี้
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<svg id=“formas_sencillas” width=“100%” height=“180px” viewBox=“0 0 100 100” preserveAspectRatio=“none” class=“foto_columna_sombra” style=“background-color:#A8C3EA;margin:20px auto;”>
<polygon points=“0,100 0,42 8,38 14,37 22,40 29,33 35,36 44,40 51,30 57,42 64,33 74,38 80,34 87,40 92,38 100,32 100,100” style=“fill:none;stroke:#205587;stroke-width:4;stroke-opacity:1;fill:#205587;fill-opacity:0.5;” vector-effect=“non-scaling-stroke” />
<circle cx=“0” cy=“42” r=“5” style=“stroke:none;fill:#205587;fill-opacity:1;” />
<circle cx=“8” cy=“38” r=“5” style=“stroke:none;fill:#205587;fill-opacity:1;” />
<circle cx=“14” cy=“37” r=“5” style=“stroke:none;fill:#205587;fill-opacity:1;” />
<circle cx=“22” cy=“40” r=“5” style=“stroke:none;fill:#205587;fill-opacity:1;” />
<circle cx=“29” cy=“33” r=“5” style=“stroke:none;fill:#205587;fill-opacity:1;” />
<circle cx=“35” cy=“36” r=“5” style=“stroke:none;fill:#205587;fill-opacity:1;” />
<circle cx=“44” cy=“40” r=“5” style=“stroke:none;fill:#205587;fill-opacity:1;” />
<circle cx=“51” cy=“30” r=“5” style=“stroke:none;fill:#205587;fill-opacity:1;” />
<circle cx=“57” cy=“42” r=“5” style=“stroke:none;fill:#205587;fill-opacity:1;” />
<circle cx=“64” cy=“33” r=“5” style=“stroke:none;fill:#205587;fill-opacity:1;” />
<circle cx=“74” cy=“38” r=“5” style=“stroke:none;fill:#205587;fill-opacity:1;” />
<circle cx=“80” cy=“34” r=“5” style=“stroke:none;fill:#205587;fill-opacity:1;” />
<circle cx=“87” cy=“40” r=“5” style=“stroke:none;fill:#205587;fill-opacity:1;” />
<circle cx=“92” cy=“38” r=“5” style=“stroke:none;fill:#205587;fill-opacity:1;” />
<circle cx=“100” cy=“32” r=“5” style=“stroke:none;fill:#205587;fill-opacity:1;” />
<rect x=“0” y=“0” width=“100” height=“100” style=“fill:none;stroke:#205587;stroke-width:4;stroke-opacity:1;” vector-effect=“non-scaling-stroke” />
</svg>
|
ลักษณะของโค้ดก่อนหน้าจะเหมือนกับรูปภาพต่อไปนี้ (มีเคล็ดลับบางประการเพื่อให้สามารถนำจุดจากตัวอย่างด้านบนกลับมาใช้ใหม่ได้)
จุดของรูปหลายเหลี่ยม (polygon
) ระบุไว้ในคุณสมบัติ points
เป็นคู่ของพิกัด x,y ที่คั่นด้วยช่องว่างระหว่างพิกัดเหล่านั้น เพื่อกำหนดวงรี (ellipse
) มีการใช้คุณสมบัติ cx
(พิกัด x ของศูนย์กลาง) cy
(พิกัดของศูนย์) rx
(ความกว้าง) และ ry
(สูง). แทนที่จะเป็นค่ารัศมีสองค่า (รัศมีแนวนอนและแนวตั้ง rx
y ry
) วงกลม (circle
) ถูกกำหนดโดยรัศมีพร้อมกับคุณสมบัติ r
และพิกัดของศูนย์ด้วย cx
y cy
. เพื่อกำหนดสี่เหลี่ยม (rectangle
) ระบุพิกัดของมุมซ้ายบน (x
e y
) ความกว้าง (width
) และตัวสูง (height
)
สุดท้ายนี้ เพื่อรวมข้อความ วัตถุจะถูกใช้ text
ดังต่อไปนี้:
1
2
3
|
<text x=“10.0” y=“20.0” font-family=“DejaVu” font-size=“24” fill=“#A8C3EA” >
Texto en formato SVG
</text>
|
ตำแหน่งของข้อความระบุด้วยพิกัด x และ y แบบอักษรสอดคล้องกับคุณสมบัติ font-family
,ขนาดด้วย font-size
และสีที่มีคุณสมบัติ fill
.
HTML ช่วยให้คุณสามารถรวมภาพวาดได้ SVG เป็นอีกองค์ประกอบหนึ่งของหน้า เช่นเดียวกับวัตถุอื่นๆ คุณสามารถใช้คุณสมบัติได้ ID
เพื่อกำหนดตัวระบุที่ไม่ซ้ำกันซึ่งสามารถอ้างอิงถึงพวกเขาได้ JavaScript เพื่อจัดการพวกเขา จากมุมมองของ HTML, วัตถุ SVG ก็จะมีรูปแบบดังนี้
1
2
3
4
5
6
7
|
<svg width=“200.0” height=“100.0” id=“cosa_fea”>
<line x1=“10.0” y1=“20.0” x2=“30.0” y2=“40.0” style=“stroke:#205587; stroke-width:5; stroke-opacity:1.0;” />
<path d=“M 10.0,20.0 L 30.0,40.0 L 50.0,60.0 L 70.0,80.0 Z” style=“fill:#A8C3EA; fill-opacity:1.0; stroke:#205587; stroke-width:2; stroke-opacity:1.0;” />
<text x=“10.0” y=“20.0” font-family=“DejaVu” font-size=“24” fill=“#A8C3EA” >
Texto en formato SVG
</text>
</svg>
|
จากสิ่งที่เราเห็นมานี้ เป็นไปได้ที่จะวาดประเภทของกราฟพื้นฐานที่ต้องการในข้อเสนอนี้ แต่เพื่อให้เกิดความยืดหยุ่นกับรูปลักษณ์ของคอนเทนเนอร์ (หน้าเว็บ) สัดส่วนของกราฟจะได้รับผลกระทบ (ตัวอย่างเช่น preserveAspectRatio="none"
) โดยการปรับเปลี่ยนขนาดเพื่อปรับให้เข้ากับเค้าโครงในหน้าต่างเบราว์เซอร์ขององค์ประกอบ HTML.
พูดกว้างๆ มีสองทางเลือกนอกเหนือจากลักษณะการทำงานเมื่อแก้ไขขนาดของหน้าต่างเบราว์เซอร์ที่แสดงหน้าเว็บที่มีแผนภูมิ: (1) รักษาขนาดของแผนภูมิ SVG เว้นช่องว่างหากมีส่วนเกิน หรือเพิ่มแถบเลื่อนหากหายไป หรือ (2) แก้ไขขนาดของกราฟ SVG เป็นจังหวะในการเปลี่ยนขนาดของหน้าต่างเบราว์เซอร์ที่แสดงเว็บ หากคุณเลือกสูตรแรก คุณสามารถทำนายขนาดและวาดด้วยการวัดสัมบูรณ์ได้ แม้ว่าจะได้รับการแก้ไขตามขนาดที่เลือกและค่าของกราฟก็ตาม หากคุณเลือกวิธีที่สองซึ่งเป็นวิธีที่ฉันเสนอ ขนาดจะเป็นเปอร์เซ็นต์ของค่าที่แสดงเสมอ ข้อดีของวิธีที่สองคือความสามารถในการปรับตัวเข้ากับเว็บได้ และข้อเสียเปรียบคือการวาดองค์ประกอบที่มาพร้อมกับกราฟ เช่น จุดหรือข้อความ
เพื่อแก้ไขการเสียรูปที่อาจเกิดขึ้นกับความหนาของเส้น จึงมีการใช้เอฟเฟกต์ vector-effect="non-scaling-stroke"
บนเส้นทางที่จำเป็น (เส้นทางที่มีมูลค่า stroke
นอกเหนือจากนี้ none
). สำหรับวัตถุมงคลนั้น text
ไม่มีผลที่เทียบเคียงได้ ดังนั้นจึงจำเป็นต้องเปลี่ยนรูปร่าง (รวมถึงสิ่งที่เกี่ยวข้องด้วย) ในทิศทางตรงกันข้ามกับการเปลี่ยนแปลงขนาดภาชนะ
การเปลี่ยนแปลงใน SVG สามารถนำไปใช้กับกลุ่มของวัตถุเพื่อให้สามารถรวมข้อความหลายรายการและวัตถุอื่นๆ ในภาพกราฟิกเข้าไว้ในกลุ่มเดียวได้ และทำการแปลงสำหรับทั้งหมดได้สะดวกยิ่งขึ้น
องค์ประกอบที่เป็นส่วนหนึ่งของกลุ่มจะรวมอยู่ในแท็ก <g>
y </g>
เพื่อกำหนดการเปลี่ยนแปลงคุณสมบัติที่ใช้ transform
และชุดปฏิบัติการที่เกี่ยวข้องกับกรณีของเรา scale
ซึ่งมีการระบุปัจจัยการขยายแนวนอนและแนวตั้ง ถ้ามูลค่าของ scale
มากกว่าหนึ่งจะทำให้แกนที่สอดคล้องกันกว้างขึ้น และหากน้อยกว่าหนึ่ง ขนาดของวัตถุตามแกนนั้นจะลดลง
1
2
3
4
5
6
7
8
9
10
11
12
|
<svg width=“200.0” height=“100.0” id=“cosa_fea”>
<line x1=“10.0” y1=“20.0” x2=“30.0” y2=“40.0” style=“stroke:#205587; stroke-width:5; stroke-opacity:1.0;” />
<path d=“M 10.0,20.0 L 30.0,40.0 L 50.0,60.0 L 70.0,80.0 Z” style=“fill:#A8C3EA; fill-opacity:1.0; stroke:#205587; stroke-width:2; stroke-opacity:1.0;” />
<g transform=“scale(0.5,2.0)”>
<text x=“10.0” y=“20.0” font-family=“DejaVu” font-size=“24” fill=“#A8C3EA” >
Primer texto
</text>
<text x=“10.0” y=“50.0” font-family=“DejaVu” font-size=“24” fill=“#A8C3EA” >
Segundo texto
</text>
</g>
</svg>
|
ในตัวอย่างก่อนหน้านี้ ข้อความที่หนึ่งและที่สองได้รับการแก้ไขโดยการลดขนาดการวัดในแนวนอนลงครึ่งหนึ่ง และเพิ่มการวัดในแนวตั้งเป็นสองเท่าด้วยค่า 0.5 และ 2.0 ที่ใช้ใน scale(0.5,2.0)
บทความต่อไปในชุดเกี่ยวกับ การแสดงกราฟข้อมูลจากเซ็นเซอร์ที่เชื่อมต่อกับ IoT อธิบายวิธีการสร้างหรือแก้ไขกราฟแบบเรียลไทม์โดยใช้ JavaScript ซึ่งจะช่วยให้คุณเห็นภาพเคลื่อนไหวของกราฟเมื่อแสดงค่าล่าสุดที่โหลดจากเซิร์ฟเวอร์
ต่อไปนี้เป็นตัวอย่างลักษณะของกราฟที่สร้างขึ้นโดยใช้ข้อเสนอนี้
แสดงความคิดเห็น