Thiết kế biểu đồ hình tròn linh hoạt và có thể bảo trì với CSS và SVG. Cách tạo nhanh biểu đồ hình tròn với CSS và JavaScript

Lưu ý rằng trong chương này, chúng tôi sẽ tải xuống mã trực tiếp từ ổ cứng cục bộ, không phải thông qua máy chủ web. Bạn có thể cần phải tắt bảo mật trong Chrome trong quá trình phát triển. Nếu bạn gặp sự cố khi tải hình ảnh hoặc các tệp khác trực tiếp từ đĩa trong Chrome, hãy thử thêm một số cờ bảo mật trên dòng lệnh.

Trên Mac OS X, nó sẽ như thế này:

/ Applications / Google \ Chrome.app/Contents/MacOS/Google \ Chrome - cho phép-tệp-truy cập-từ-tệp - vô hiệu hoá-web-bảo mật

Chromium-browser - vô hiệu hóa-web-bảo mật

Chrome.exe - vô hiệu hóa-web-bảo mật

Ngoài ra, bạn có thể tải các trang thông qua máy chủ web cục bộ của mình.

Trong chương này, chúng tôi sẽ hiển thị một số dữ liệu bằng cách vẽ biểu đồ. Điều này sẽ cho bạn thấy những điều cơ bản về cách vẽ đường thẳng, hình dạng và văn bản, sau đó chúng ta sẽ tạo một biểu đồ hình tròn với một gradient.

Tạo một trang mới

Bắt đầu bằng cách tạo một tệp văn bản mới có tên barchart.html và nhập:

Trang trên chứa các phần tử

Bây giờ, hãy thêm danh sách các màu (một màu cho mỗi điểm dữ liệu) và tính toán tổng của tất cả dữ liệu.

// danh sách các màu var Colors = ["orange", "green", "blue", "yellow", "teal"]; // tính tổng của tất cả dữ liệu var total = 0; for (var i = 0; i

Vẽ các sector thực có vẻ khó, nhưng thực ra lại khá dễ. Mỗi cung bắt đầu từ tâm của vòng tròn (250,250), sau đó một cung tròn được vẽ từ góc trước đến góc mới. Góc là dữ liệu được chuyển đổi sang radian. Góc trước là góc từ lần lặp lại vòng lặp trước đó (bắt đầu từ 0). Một cung tròn có tâm là 250,250 có bán kính là 100. Sau đó, vẽ một đường thẳng trở lại tâm, tô màu và phác thảo hình dạng.

// vẽ dữ liệu hình tròn var presAngle = 0; for (var i = 0; i

Cuối cùng, hãy thêm một số văn bản bên dưới biểu đồ. Để căn giữa văn bản, trước tiên bạn phải tính chiều rộng của văn bản:

// vẽ văn bản được căn giữa c.fillStyle = "black"; c.font = "24pt sans-serif"; var text = "Dữ liệu bán hàng từ năm 2025"; var metrics = c.measureText (text); c.fillText (văn bản, 250-metrics.width / 2.400);

Và đây là cách nó trông:

Thêm một gradient

Để làm cho biểu đồ trông đẹp hơn một chút, bạn có thể tô từng đoạn bằng một gradient xuyên tâm, như sau:

// vẽ đoạn //c.fillStyle = Colors [i]; // tô với một gradient xuyên tâm var grad = c.createRadialGradient (250,250, 10, 250,250, 100); grad.addColorStop (0, "trắng"); grad.addColorStop (1, màu [i]); c.fillStyle = grad;

Tô màu gradient của phân đoạn chuyển từ màu trắng ở trung tâm sang màu ở rìa và thêm một chút chiều sâu cho biểu đồ. Nó sẽ giống như thế này:

Có một số cải tiến mà bạn có thể thử để làm cho các sơ đồ này hữu ích hơn:

  • Thêm dữ liệu và thay đổi phép toán để biểu đồ chứa tất cả 12 tháng dữ liệu.
  • Xây dựng biểu đồ đường vẽ mỗi điểm dữ liệu dưới dạng một vòng tròn, sau đó vẽ một đường đứt đoạn nối tất cả các vòng tròn.
  • Làm cho biểu đồ đẹp hơn với tô màu gradient, các góc tròn hoặc đường viền màu đen.
  • Vẽ nhãn trên mỗi đoạn của biểu đồ hình tròn.

"Nhà bếp" của một nhà phát triển web có phần tương tự như nấu ăn tại nhà. Nhà phát triển có quyền truy cập vào nhiều thư viện từ mã tạo sẵn sẽ giúp anh ta tạo một ứng dụng web giống như cách mà một đầu bếp ở nhà có thể sử dụng thực phẩm tiện lợi để nấu bữa ăn của mình hiệu quả hơn. Trong cả hai trường hợp, chất lượng của các mặt hàng đã chuẩn bị trước phải rất quan trọng. Tuy nhiên, đôi khi chất lượng bị hy sinh vì sự tiện lợi. Đừng hiểu sai ý tôi, sự tiện lợi không phải lúc nào cũng là điều xấu. Nó có thể hữu ích khi những ưu và nhược điểm được biết đến và được phân tích rõ ràng. Phân tích các tùy chọn cho biểu đồ bánh và bánh rán trong HTML, chúng tôi chỉ có thể làm nổi bật một vài:

  1. Biểu đồ dựa trên phần tử canvas được tạo trên máy khách (tức là JavaScript)
  2. Một sơ đồ dựa trên SVG và được tạo trên máy khách (tức là JavaScript)
  3. Máy chủ biểu đồ dựa trên SVG đã tạo

Thư viện bên ngoài sử dụng Canvas và SVG JavaScript

Các thư viện JavaScript để vẽ sơ đồ thường thuận tiện hơn và được tải với một loạt các tùy chọn thú vị như tương tác. Dưới đây là một số thư viện:

  1. D3.js
  2. Chartist.js
  3. Biểu đồ của Google

Một vài dòng JavaScript và một mảng dữ liệu sẽ cho phép bạn tạo một sơ đồ trên trang web của mình trong vài giây. Không có gì ngạc nhiên khi nhiều người chọn con đường này.

Vậy tại sao phải bận tâm và tự viết mã chúng? Đây là một câu hỏi tuyệt vời mà tôi cũng đã tự hỏi mình. Cuối cùng, tôi đã bị thuyết phục về ba điều:

  1. Hầu hết các thư viện JavaScript đều khó tìm, đặc biệt là những thư viện dựa trên phần tử Canvas (ngoại trừ Google Charts)
  2. Nếu thông tin trong sơ đồ là rất quan trọng (như trong trường hợp của tôi), chúng ta có nên dựa vào một tập lệnh chạy trên máy khách để tạo ra thông tin không? Tôi không nghĩ vậy.
  3. Nếu tôi tìm hiểu sâu hơn về mã SVG và làm bẩn tay, tôi có thể tìm hiểu thêm một chút về điều vô nghĩa ma thuật tiềm ẩn. Nói cách khác, quá trình học tập có thể rất thú vị và đáng để bạn nỗ lực.

Hoàn cảnh của tôi

Nhóm của tôi cần một thành phần đơn giản có thể được biên dịch trên máy chủ và hiển thị thông tin sử dụng tài khoản đơn giản. Ngoài ra, sở thích của chúng tôi là độ nhẹ của thành phần này (tránh JavaScript nếu có thể); nó không cần phải quá phức tạp hoặc tương tác, nó chỉ cần hiển thị dữ liệu quan trọng.

Ghi chú bổ sung về biểu đồ dựa trên Canvas

Bạn có thể nhận thấy (nếu bạn đã quen với việc tạo biểu đồ cho web) rằng tôi đã không đưa Chart.js vào danh sách các thư viện được đề xuất ở trên. Mặc dù bạn chắc chắn có thể sử dụng nó, nhưng cần lưu ý rằng Chart.js sử dụng phần tử Canvas để hiển thị biểu đồ của nó và nội dung của phần tử không phải là một phần của DOM. Do đó, chúng không có sẵn cho trình đọc màn hình. Điều này có nghĩa là bạn sẽ phải thực hiện các bước bổ sung để đảm bảo rằng dữ liệu của bạn có sẵn.

Giới thiệu về biểu đồ CSS và SVG

Sơ đồ CSS và SVG vốn dễ tiếp cận và dễ hiểu hơn các công nghệ khác. Nhưng chúng có thể phức tạp và có thể tốn nhiều thời gian hơn nếu bạn viết mã chúng bằng tay.

CSS Ninja Lea Verou cung cấp một số tùy chọn để tạo biểu đồ hình tròn từ đầu trong bài viết "Thiết kế biểu đồ hình tròn linh hoạt, có thể bảo trì với CSS và SVG". Phương pháp của cô ấy cũng có thể được áp dụng cho biểu đồ bánh rán.

Robin Randle cũng đã viết về việc tạo biểu đồ hoàn toàn bằng CSS, nơi anh ấy cũng chỉ ra những thất bại của mình trong cách tiếp cận.

Không thể giải thích được

Tôi đã tìm kiếm trên Google về biểu đồ SVG và bánh rán và xem các bài báo của Leah Verou và Robin Randle (đã đề cập ở trên) cùng với một số bài báo khác. Hầu như tất cả họ đều thảo luận về việc sử dụng các thuộc tính stroke-dasharray và stroke-dashoffset trong SVG để định vị các phần của một sơ đồ. Các thuộc tính này giống với "nét vẽ" khi tạo vectơ trong các chương trình như Adobe Illustrator.

Một số bài báo này thậm chí còn thảo luận về hoạt ảnh trong SVG, điều này thật tuyệt, nhưng nó cũng không phải là thứ tôi đang tìm kiếm.

Sau khi nghiên cứu, tôi đã có thể tìm ra rằng bằng cách sử dụng từ SVG cùng với đột quỵ và đột quỵ-dasharray có thể cung cấp cho tôi các phân đoạn bánh lồng nhau mà tôi cần. Tôi cũng nhận ra rằng stroke-dashoffset sẽ cho phép tôi "tạo hoạt ảnh", hay nói cách khác, định vị phân đoạn mà tôi muốn nó nằm trong vòng tròn.

Tuy nhiên, tôi dường như không tìm thấy bất kỳ lời giải thích rõ ràng nào về cách các thuộc tính dấu gạch ngang hoạt động và cách chúng liên quan đến chu vi của hình tròn. Và điều không thể đạt được hơn là đính kèm một số phần tử (cái này đến cái khác) xung quanh vòng tròn. Tốt hơn, công thức để có được các vị trí tương đối này bằng cách sử dụng kích thước phân đoạn động / duy nhất và thuộc tính đột quỵ của SVG là gì?

Vì vậy, tôi quyết tâm tự tìm hiểu.

Lưu ý: Nếu bạn tìm thấy bất kỳ tài nguyên nào giải thích những khái niệm này, vui lòng chia sẻ.

Cách tạo sơ đồ SVG DIY

Giải thích về đột quỵ-dasharray và đột quỵ-dashoffset

Hãy bắt đầu với một biểu đồ "donut" SVG đơn giản.

Bạn sẽ nhận thấy một số điều:

  1. Bán kính (thuộc tính "r") trông thật vô lý! Tại sao? Tôi muốn làm cho kích thước phân khúc của mình hợp lý, dễ hiểu và dễ đọc. Để đạt được điều này, tôi quyết định dựa trên mọi thứ dựa trên 100% (hoặc vòng tròn 100). Các hình dạng SVG có thể thay đổi tỷ lệ, vì vậy nó không thực sự quan trọng về kích thước của chúng; ít nhất là toán học sẽ đơn giản ở đây. Tiến xa hơn vào khu vực mà tôi nhớ được từ môn toán cấp ba: Tôi biết rằng bán kính của hình tròn là r = C / (2π) hoặc r = 100 / (2π). Kết quả là 15,91549430918952. Một con số điên rồ với một loạt các con số, vâng, tôi biết, nhưng sau này nó sẽ giúp cuộc sống của tất cả chúng ta dễ dàng hơn.
  2. viewBox các giá trị là "0 0 42 42". Chúng phải gấp đôi giá trị cx & cy (tâm x và tâm y) và lớn hơn một chút so với đường kính của các vòng tròn (bao gồm cả chiều rộng của đường viền).
  3. với lớp "donut-hole". Đây là những gì được đảm bảo để làm cho trung tâm trắng. Nếu điều này không quan trọng đối với bạn (trong trường hợp biểu đồ tròn đơn giản), thì bạn có thể xóa mục này.
  4. Cũng có với lớp "donut-ring". Nó dùng làm nền màu xám nhạt trong trường hợp các cung không lấp đầy 100% hình tròn.

Vì vậy, chúng ta cần điều chỉnh kích thước khu vực theo tỷ lệ phần trăm mong muốn. Hãy sử dụng 85%:


Các cung được tạo bằng cách sử dụng thuộc tính nét SVG được gọi là stroke-dasharray. Giá trị chúng tôi đặt trong ví dụ trên là "85 15".

Nếu chúng ta coi sơ đồ là một hình tròn, thì từ sự hiện diện của 85% sector, chúng ta có thể đánh giá khoảng 15% còn lại. Hai giá trị này là một mảng được phân cách bằng dấu cách. Đây là những gì sẽ xảy ra: một nét gồm 85 đơn vị được tạo ra, sau đó là một khoảng trắng 15 đơn vị, sau đó là một nét 85, một khoảng cách 15, v.v. Nhưng vì chúng ta đang sử dụng một vòng tròn và tổng là 100, mọi thứ được lặp lại một lần nữa. Nếu chúng ta chưa tạo giá trị thứ hai trong mảng sao cho nó bổ sung cho số đầu tiên thành một trăm, thì chúng ta sẽ nhận được nét thứ ba (hoặc một phần) trở lên. Ví dụ: đây là một nét-dasharray từ "10 10":


Vì vậy, trong hình 2 và hình 3, bạn có thể nhận thấy rằng stroke-dasharray không bắt đầu ở đầu (lúc 12:00). Thay vào đó, nó thực sự bắt đầu ở phía bên phải (3:00) và di chuyển theo chiều kim đồng hồ trong một vòng tròn.

Nếu chúng ta muốn định vị (hoặc bắt đầu) ở trên cùng, thì chúng ta phải sử dụng stroke-dashoffset. Tuy nhiên, không giống như stroke-dasharray, stroke-dashoffset di chuyển ngược chiều kim đồng hồ. Vì vậy, chúng tôi sẽ cần đặt giá trị thành "25" (25% theo hướng khác từ 3:00, trở lại 12:00). Hãy nhớ rằng đây không phải là một số âm, vì phần bù di chuyển ngược lại với mũi tên.


Cách sắp xếp các lát bánh rán xung quanh SVG

Bây giờ chúng ta cần thêm các cung khác xung quanh vòng tròn. Hãy sử dụng một sector bằng 15% của vòng tròn. Tỷ lệ còn lại đối với đột quỵ-dasharray sẽ là 85%, không phụ thuộc vào bất kỳ lĩnh vực nào khác. Do đó, mã sẽ trông như thế này:

Chúng tôi để bộ đột quỵ-dashoffset ở 25, vì vậy khu vực màu xanh lá cây bắt đầu ở trên cùng và đi theo chiều kim đồng hồ, chồng lên khu vực đầu tiên (màu hồng).


Rõ ràng, đây không phải là điều chúng tôi mong muốn. Chúng tôi muốn phần trăm mười lăm (màu xanh lá cây) vừa với không gian còn lại của tám mươi lăm phần trăm (màu hồng). Chúng ta có thể điều chỉnh đột quỵ-dashoffset cho đến khi chúng ta may mắn, nhưng sẽ không dễ dàng như vậy nếu chúng ta có thêm hai cung. Thay vào đó, chúng ta cần một công thức:

Vòng tròn - tổng chiều dài của tất cả các lĩnh vực trước đó + bù đắp của lĩnh vực đầu tiên = bù đắp của lĩnh vực hiện tại

Cắm số của chúng tôi, chúng tôi nhận được:


Thêm nhiều lát vào sơ đồ của chúng tôi!

Công thức tương tự này hoạt động để thêm các khu vực bổ sung. Hãy điền vào biểu đồ với 40, 30, 20 phần trăm và 10 phần còn lại sẽ không được sử dụng.

Kết quả:


Thêm văn bản vào bên trong biểu đồ

Nó sẽ không phải là một biểu đồ bánh rán mà không có văn bản trong và ngoài; đó là cái lỗ để làm gì, phải không? Chà, việc thêm văn bản rất dễ dàng. Chúng tôi chỉ sử dụng phần tử có nguồn gốc từ các hình dạng SVG.

10 Bia

Bạn sẽ nhận thấy rằng tôi đã chia văn bản biểu đồ thành 2 phần tử và nhóm chúng lại ( ). Điều này được thực hiện để chúng ta có thể dễ dàng chồng tiêu đề và số lên trên nhau, đồng thời sắp xếp chúng thành một đơn vị. Tôi đã điều chỉnh các thuộc tính X và Y để bắt đầu ở tâm của hình dạng trên đường cơ sở và căn chỉnh chúng ở bên trái.


Như bạn có thể thấy, vị trí không hoàn toàn chính xác, vì vậy chúng tôi sẽ cần trang trí nó bằng một chút CSS:

Đầu tiên, hãy thêm phông chữ Montserrat (chỉ vì tôi thích nó). Sau đó, chúng ta cần điều chỉnh kích thước phông chữ và chiều cao dòng. Sau khi thêm "translateY" trong 0,25em, văn bản được căn chỉnh theo chiều dọc một chút, nhưng chúng tôi vẫn chưa hoàn thành.

Chúng ta cần làm cho cả hai hộp văn bản nhỏ hơn và căn giữa bằng cách điều chỉnh kích thước phông chữ ở bất kỳ đâu chúng ta muốn (0,6em cho số lớn hơn và 0,2em cho tiêu đề trông ổn) và sử dụng thuộc tính "text-anchor" với giá trị "ở giữa ".

Văn bản bây giờ nằm ​​ở trung tâm. Tất cả những gì còn lại là đặt tất cả thành chữ hoa (điều này rất dễ dàng) và sắp xếp các phần tử riêng lẻ của nó bằng cách sử dụng "translateY" để chúng gấp lại đúng cách. Và đây là những gì chúng ta có bây giờ:


Các vấn đề về khả năng tiếp cận

Như tôi đã đề cập trước đó, nội dung SVG là một phần của DOM, vì vậy nó vốn dĩ dễ tiếp cận hơn. Điều này giúp bạn dễ dàng cung cấp ngữ cảnh bổ sung cho trình đọc màn hình thông qua các thuộc tính và phần tử như tiêu đề.

Mức độ quan tâm đầu tiên về khả năng tiếp cận là làm cho biểu đồ SVG có ngữ nghĩa hơn bằng cách gói nó trong một phần tử

(vì đây là một sơ đồ). Như một hình dạng, chúng ta có thể sử dụng phần tử để cung cấp tiêu đề hoặc mô tả cho biểu đồ bánh rán.

Ngoài ra, chúng ta có thể thêm các thẻ nội dung và <desc>(có nguồn gốc từ SVG) và liên kết chúng với tiêu đề ARIA, ID và vai trò "cung cấp thêm ngữ cảnh cho trình đọc màn hình".</p><p> <style> @import url(https://fonts.googleapis.com/css?family=Montserrat:400); body { font: 16px/1.4em "Montserrat", Arial, sans-serif; } * { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } .chart-text { /*font: 16px/1.4em "Montserrat", Arial, sans-serif;*/ fill: #000; -moz-transform: translateY(0.25em); -ms-transform: translateY(0.25em); -webkit-transform: translateY(0.25em); transform: translateY(0.25em); } .chart-number { font-size: 0.6em; line-height: 1; text-anchor: middle; -moz-transform: translateY(-0.25em); -ms-transform: translateY(-0.25em); -webkit-transform: translateY(-0.25em); transform: translateY(-0.25em); } .chart-label { font-size: 0.2em; text-transform: uppercase; text-anchor: middle; -moz-transform: translateY(0.7em); -ms-transform: translateY(0.7em); -webkit-transform: translateY(0.7em); transform: translateY(0.7em); } figure { display: flex; justify-content: space-around; flex-direction: column; margin-left: -15px; margin-right: -15px; } @media (min-width: 768px) { figure { flex-direction: row; } } .figure-content, .figure-key { flex: 1; padding-left: 15px; padding-right: 15px; align-self: center; } .figure-content svg { height: auto; } .figure-key { min-width: calc(8 / 12); } .figure-key { margin-right: 6px; } .figure-key-list { margin: 0; padding: 0; list-style: none; } .figure-key-list li { margin: 0 0 8px; padding: 0; } .shape-circle { display: inline-block; vertical-align: middle; width: 32px; height: 32px; -webkit-border-radius: 50%; -moz-border-radius: 50%; border-radius: 50%; } .shape-fuschia { background-color: #ce4b99; } .shape-lemon-lime { background-color: #b1c94e; } .shape-blue { background-color: #377bbc; } .sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0,0,0,0); border: 0; } </style> <figure> <div class="figure-content"> <svg width="100%" height="100%" viewBox="0 0 42 42" class="donut" aria-labelledby="beers-title beers-desc" role="img"> <title id="beers-title">Bia trong hầm rượu của tôi Quadrupels Bỉ Phân khúc biểu đồ màu hồng chiếm 40% tổng số, tức là 4 Quadrupel của Bỉ trên tổng số 10. Hoàng đế Ấn Độ bia nhạt Phân khúc biểu đồ màu xanh lá cây chiếm 20% toàn bộ, là 2 Imperial India Pale Ales trên tổng số 10. Stouts Hoàng gia Nga Phân đoạn biểu đồ màu xanh lam chiếm 3% toàn bộ, là 3 trong tổng số 10 điểm của Hoàng gia Nga. 10 Bia

Biểu đồ bánh rán cho thấy tổng số 10 loại bia. Hai loại bia là Imperial India Pale Ales, bốn loại bia là Quadrupels của Bỉ, và ba loại là Imperial Stouts của Nga. Bia cuối cùng còn lại không nhãn.

Chúng tôi cũng có thể thêm khóa chú giải cho biểu đồ như một phần của

, ghi nhận nó với vai trò "view" và thuộc tính aria-hidden, vì nó thực sự cần thiết để rõ ràng.

Với một chút ma thuật CSS Flexbox, chúng ta có thể định vị phím ở bên phải và căn chỉnh nó theo chiều dọc với biểu đồ. Sản phẩm cuối cùng sẽ cung cấp cho chúng ta những gì:


Vì thiết kế CSS với một khóa mà thuộc tính bán kính đường viền được áp dụng và Flexbox có thể là các bài viết riêng biệt (phần sau yêu cầu giải thích dài hơn), tôi sẽ để lại các chủ đề đó cho phần sau.

Kết quả cuối cùng

Như tôi đã đề cập trước đó, việc viết mã cho các đối tượng SVG bằng tay có thể tốn thời gian, đặc biệt là khi bạn xem xét thực tế là có rất nhiều thư viện JavaScript tuyệt vời sẽ xây dựng các đối tượng này cho bạn. Nhưng có thể có những trường hợp (như tình huống của tôi) trong đó bạn hoặc nhóm của bạn cần một phương pháp không đụng đến JavaScript, một phương pháp sẽ được biên dịch ở phía máy chủ.

Tin tốt là một khi bạn hiểu rõ nó, nó có thể được áp dụng ở nơi khác với nỗ lực tối thiểu. Ngoài ra, làm bẩn tay với các đối tượng SVG là một cách tốt để tìm hiểu thêm về cách chúng hoạt động và lợi ích của việc sử dụng chúng.

Kết quả của tôi:

  • Áp dụng toán học vào một thứ như thế này thú vị hơn nhiều so với thời trung học.
  • Nhìn lại, tôi nhận ra rằng logic đằng sau đột quỵ-dasharray và đột quỵ-dashoffset không phức tạp như tôi nghĩ ban đầu.
  • Đừng quên thêm các mức khả năng tiếp cận bổ sung tại đây. Rốt cuộc, khả năng truy cập không chỉ dành cho trình đọc màn hình. Nó cũng cần thiết để làm cho nội dung của bạn dễ tiếp cận và có thể tiêu thụ được bởi tất cả mọi người và mọi thiết bị (bao gồm cả các công cụ tìm kiếm). Nếu thư viện JavaScript của bạn không có các chức năng trợ năng, hãy xem xét việc thay đổi nó.
  • Dịch
  • Hướng dẫn

Biểu mẫu là một cách tuyệt vời để thêm một số hương vị vào các phần tử trên trang web của bạn. Vòng kết nối đặc biệt tốt về mặt này vì chúng mang tính tổng thể, đơn giản và giống như chiếc bánh. Bây giờ nghiêm túc, ai không yêu bánh?

Như bạn đã nhận thấy từ kinh nghiệm sử dụng Internet nhiều năm của chính mình, hầu hết các phần tử trên các trang web trên thực tế là hình vuông hoặc hình chữ nhật. Do đó, trong một số trường hợp, các yếu tố thú vị như hình tròn và hình tam giác trong thiết kế của bạn có thể khá hữu ích. Hướng dẫn này sẽ trình bày cách xây dựng biểu đồ hình tròn động tương tự như biểu đồ bạn thường thấy trên các trang web danh mục đầu tư. Điều này có thể giúp làm nổi bật trực quan các kỹ năng của bạn, cũng như chứng minh những nhiệm vụ bạn có thể xử lý. Hãy xem bản demo để xem kết quả cuối cùng.

Vì vậy, hãy bắt đầu!

Khi viết hướng dẫn này, tôi sẽ làm việc với Circliful. Nó là một plugin jQuery mã nguồn mở và miễn phí. Bạn có thể tải xuống tệp chính từ Github. Nó bao gồm một tệp .js cùng với một biểu định kiểu CSS tương ứng. Trang phải chứa cả hai để đạt được hiệu ứng vòng tròn.




 
 
 Số liệu thống kê về vòng tròn hoạt hình - Bản trình diễn mẫu quái vật
 
 
 
 
 
 
 

Trang của tôi chứa một biểu định kiểu styles.css tương tự cho các kiểu CSS cá nhân của tôi. Bạn cũng cần tạo một bản sao của thư viện jQuery. Nó được yêu cầu để plugin hoạt động chính xác.
Bản thân nó, trang này khá dễ cấu trúc. Các phần tử vòng kết nối được chứa trong các thẻ div sử dụng các thuộc tính HTML5 để thao tác dữ liệu. Ngoài ra, chúng có thể được lưu trữ trong một hàm jQuery, nhưng nếu bạn muốn kiểm soát tốt hơn từng phần tử thì việc làm việc trong HTML sẽ dễ dàng hơn.

Photoshop

Người vẽ tranh minh họa

After Effects

Đây là bản sao của hàng vòng tròn đầu tiên, bao gồm 3 đơn vị hoạt hình. Tất cả các thuộc tính dữ liệu này được giải thích thêm trong tài liệu plugin. Mỗi tùy chọn đại diện cho một tùy chọn xác định hiệu ứng hoạt ảnh. Dưới đây là mô tả ngắn gọn về các tùy chọn mà tôi sử dụng:

  • kích thước dữ liệu - tổng kích thước của chiều rộng / chiều cao vòng tròn;
  • data-text - văn bản xuất hiện ở trung tâm của mỗi vòng tròn;
  • data-width - độ dày của vòng cung dữ liệu quay;
  • data-fontsize - kích thước phông chữ trung tâm văn bản;
  • data-phần trăm - một số từ 0-100 đại diện cho phần trăm trong vòng kết nối của bạn;
  • data-fgcolor - màu nền trước của hình tròn;
  • data-bgcolor - màu nền của hình tròn;
  • data-fill - phần tô màu bên trong của màu nền của hình tròn bên trong.

Bố cục trang CSS

Tôi không nhấn mạnh rằng bạn trực tiếp chỉnh sửa jquery.circliful.css Tất nhiên trừ khi bạn muốn tùy chỉnh plugin. Hầu hết các màu có thể được thay đổi trực tiếp từ các thuộc tính dữ liệu HTML5 và nếu bạn thực sự muốn viết lại bất kỳ kiểu nào Circliful, Tôi khuyên bạn nên làm điều này trong biểu định kiểu của riêng bạn.
Đã nói với bạn điều này, tôi đã tạo biểu định kiểu của riêng mình cho dự án đã cho, không phải để viết lại các kiểu Circliful... Bản thân trang web cần một bố cục mặc định thực sự dễ thiết kế. Khu vực nội dung được căn giữa trong một phần nhỏ cho biểu đồ hình tròn. Mỗi vùng di chuyển tự do trong vùng chứa dòng trong vùng gốc #stats div.

/ ** cấu trúc trang ** / .wrap (display: block; margin: 0 auto; max-width: 800px;) #intro (display: block; margin-bottom: 25px; text-align: center;) #intro p (font-size: 1.8em; line-height: 1.35em; color: # 616161; font-style: italic; margin-bottom: 25px;) #stats (display: block; width: 100%; padding: 15px 0; background: # f8f8f8; border-top: 4px solid # c3c3c3; border-bottom: 4px solid # c3c3c3;) #stats .row (display: block;) .circle-container (display: block; float: left; margin-right : 55px; margin-bottom: 45px;) .circle-container h3 (display: block; text-align: center; font-size: 2.25em; line-height: 1.4em; color: # 363636; text-shadow: 1px 1px 0 #fff;)

Trong mỗi phần, nội dung được giữ trong .wrap divđể sửa ở trung tâm. Ngoài ra, các phần tử chuyển động tự do của hình tròn cần có thêm một thùng chứa. .clearfixđể giữ cho mọi thứ được căn chỉnh chính xác.

/ ** clearfix ** / .clearfix: after (content: "."; display: block; clear: cả; khả năng hiển thị: hidden; line-height: 0; height: 0;) .clearfix (display: inline-block; ) html .clearfix (display: block;) * html .clearfix (height: 1%;)

Lớp này clearfixđã được biết đến trong nhiều năm như một giải pháp container di chuyển tự do. Thông thường chúng bị xóa khỏi văn bản của tài liệu và không giữ nguyên chiều rộng / chiều cao ban đầu của chúng. Nhưng điều này giữ cho chiều rộng vùng chứa không đổi #stats và để lại chỗ cho nhiều nội dung hơn để đi xuống trang.

Lần chỉnh sửa cuối cùng

Vì vậy, chúng tôi nhào bột, đổ đầy chảo bánh, đặt nó vào lò nướng và gần như sẵn sàng để lấy mẫu. Nếu mọi thứ có vẻ đủ tốt, bước cuối cùng là gì? Chúng tôi cần một số mã jQuery để trang trí cho dự án này.
Mở một thẻ script mới ở cuối trang HTML này. Nó sẽ chứa một đoạn mã JavaScript nhỏ. Vì tôi đã sử dụng tất cả các thuộc tính dữ liệu HTML5, nên chúng tôi không cần gọi bất kỳ tùy chọn jQuery nào. Tập lệnh chỉ cần chạy chức năng Circliful trên mỗi vòng tròn của div. Sử dụng tên lớp trùng lặp chẳng hạn như .circlestat làm cho quá trình này rất dễ dàng.

$ (function () ($ (". circlelestat"). circleliful ();));

Đối với những người không quen với cấu trúc cú pháp của jQuery, tôi sẽ cung cấp một mô tả ngắn. Sau khi tài liệu được tải, chúng tôi chạy một chức năng mới. Mục tiêu bên trong của chúng tôi là mọi phần tử sử dụng lớp .circlestat và chạy chức năng vòng tròn ()... Điều này dẫn đến plugin Circliful, tạo hiệu ứng hoạt hình, hoạt động và áp dụng nội dung / màu sắc bổ sung.

Tôi không thể nói rằng những vòng tròn này sẽ luôn là giải pháp tốt nhất. Tôi đã thấy rất nhiều danh mục đầu tư dựa trên các từ và số, nhưng không hiệu quả. Cân nhắc sử dụng những vòng kết nối này trong những dịp hiếm hoi và thử mượn chúng cho các mục đích khác ngoài các kỹ năng đơn giản. Số liệu thống kê của bạn không cần phải được đo bằng phần trăm - chúng có thể cho biết bạn đã kinh doanh được bao nhiêu năm, tổng số dự án của bạn hoặc các con số tương tự khác. Bạn có thể tải xuống bản sao hướng dẫn của tôi miễn phí và thử nghiệm với mã để làm cho nó tốt hơn cho các dự án của bạn.

Bạn có thể đã gặp các chỉ báo tải như vậy, đặc biệt là trên các trang web Flash. Đây là một phần của một vòng tròn lớn dần lên cho đến khi nó biến thành một vòng tròn hoàn chỉnh.

Thoạt nhìn, nhiệm vụ có vẻ đơn giản: tạo một vòng tròn, xoay nó và ẩn phần đằng sau một chiếc mặt nạ. Nhưng trên thực tế, mọi thứ hóa ra có phần phức tạp hơn. CSS không được chuẩn bị cho các tác vụ như vậy, ngay cả khi sử dụng các bộ tiền xử lý như SASS & Compass. Chúng tôi luôn gặp khó khăn khi phải tạo ra các hình dạng khác nhau, và đặc biệt là khi xác định phong cách và hình ảnh động cho chúng. Phần lớn thời gian làm việc được dành cho việc đó. để có được thứ gì đó hoạt động và hy sinh ngữ nghĩa của mã và hỗ trợ của nó.

Tại sao chúng ta làm điều đó?

Khả năng sử dụng các phần tử như vậy là bộ hẹn giờ. Nhưng khái niệm này có thể được sử dụng để tạo biểu đồ hình tròn chỉ với một CSS.

Mặc dù có một số công cụ tuyệt vời để thao tác với biểu đồ hình tròn (chủ yếu bằng JavaScript), tuy nhiên, chúng tôi sẽ tạo một phần tử như vậy chỉ trong CSS và thậm chí tạo hiệu ứng cho nó bằng một vài thủ thuật.

Ngữ nghĩa của mã sẽ như vậy! Nhưng phần đệm có thể được thực hiện khá thuận tiện.

Html

Chúng ta cần 3 yếu tố khác nhau:

  • spinner: một nửa của một vòng tròn sẽ xoay;
  • mặt nạ: phần tử này ẩn vòng tròn quay trong 50% đầu tiên của hoạt ảnh;
  • phụ: phần tử này lấp đầy vòng tròn trong 50% cuối cùng của hoạt ảnh.

Và cả ba phần tử phải có cùng một phần tử gốc để định vị tuyệt đối:

Vì spinner và filler là hai nửa của cùng một vòng tròn, chúng tôi sẽ sử dụng lớp .pie cho chúng.

CSS

Cấp độ gốc nhận được các thứ nguyên và vị trí tuyệt đối của ngữ cảnh cho bộ đếm thời gian:

Bao bọc (chiều rộng: 250px; chiều cao: 250px; vị trí: tương đối; nền: trắng;)

Điều quan trọng là chiều rộng và chiều cao bằng nhau để có được hình tròn và mọi thứ hoạt động.

Các phần tử con quay và phần phụ sử dụng mã CSS này:

Hình tròn (chiều rộng: 50%; chiều cao: 100%; vị trí: tuyệt đối; nền: # 08C; đường viền: 10px rgba đặc (0,0,0,0.4);)

Chúng có chiều rộng bằng 50% của phần tử mẹ, vì vậy chúng là hai phần của cùng một hình tròn và chiều cao của chúng bằng chiều cao của phần tử mẹ. Chúng tôi cũng xác định màu sắc và khung giống nhau cho chúng.

Yếu tố Spinner

Spinner (border-radius: 125px 0 0 125px; z-index: 200; border-right: none; animation: rota 10s tuyến tính vô hạn;)

Biến nó thành hình bán nguyệt bằng cách sử dụng thuộc tính border-radius ở các góc trên cùng bên trái và dưới cùng bên trái. Chúng tôi cũng xác định một chỉ số z dương để định vị nó trên đầu phần tử tô màu, nhưng bên dưới mặt nạ.

Sau đó, thêm hoạt ảnh trong 10 giây. Chúng ta sẽ nói về hoạt hình sau.

Phần tử chất độn

Filler (border-radius: 0 125px 125px 0; z-index: 100; border-left: none; animation: lấp đầy các bước 10 giây (1, end) vô hạn; left: 50%; opacity: 0;)

Đối với phần tử này, hãy đặt bán kính đường viền và chỉ số z, xóa đường viền bên trái và tạo hoạt ảnh cho nó trong 10 giây. Đối với một phần tử đã cho, hàm định thời gian hoạt ảnh không nhận giá trị tuyến tính mà là các bước (1, kết thúc). Điều này có nghĩa là hoạt ảnh sẽ chạy ngay lập tức.

Vì phần tử tô màu không được hiển thị trong nửa đầu của hoạt ảnh, độ mờ của phần tử này sẽ là 0 và vị trí của phần tử này sẽ là 50% chiều rộng của phần tử mẹ.

Phần tử "mặt nạ"

Mặt nạ (chiều rộng: 50%; chiều cao: 100%; vị trí: tuyệt đối; chỉ số z: 300; độ mờ: 1; nền: kế thừa; hoạt ảnh: mặt nạ bước 10 giây (1, kết thúc) vô hạn;)

Mặt nạ hiện diện từ đầu hoạt ảnh, vì vậy độ mờ của nó được đặt thành 1 và nền được kế thừa từ nền gốc (để nó ẩn). Để che phần tử xoay, nó sẽ có cùng kích thước và thuộc tính z-index được đặt thành 300.

Khung hoạt hình

@keyframes rota (0% (biến đổi: xoay (0deg);) 100% (biến đổi: xoay (360deg);)) @keyframes lấp đầy (0% (độ mờ: 0;) 50%, 100% (độ mờ: 1;) ) Mặt nạ @keyframes (0% (độ mờ: 1;) 50%, 100% (độ mờ: 0;))

Hoạt ảnh đầu tiên (rota) được sử dụng cho phần tử spinner. Nó quay dần từ 0 đến 360 độ trong 10 giây.

Hoạt ảnh thứ hai (lấp đầy) được sử dụng cho phần tử phụ. Nó ngay lập tức thay đổi độ mờ từ 0 thành 1 sau 5 giây.

Hoạt ảnh cuối cùng (mặt nạ) được sử dụng cho phần tử mặt nạ. Nó ngay lập tức thay đổi độ mờ từ 1 thành 0 sau 5 giây.

Hoạt ảnh trông như thế này:

  • T0- con quay bên trái, bị che khuất bởi mặt nạ. Phần tử phụ bị ẩn.
  • T1- con quay bắt đầu quay theo chiều kim đồng hồ và từ từ xuất hiện từ phía sau mặt nạ.
  • T2- con quay r được xoay 360/10 * 2 = 72 ° và tiếp tục quay.
  • T3- con quay được xoay 360/10 * 3 = 108 ° và tiếp tục quay.
  • T4- con quay được xoay 360/10 * 4 = 144 ° tiếp tục quay.
  • T5- con quay được xoay 360/10 * 5 = 180 ° và tiếp tục quay. Tại thời điểm này, phần tử chất làm đầy sẽ hiển thị ngay lập tức và mặt nạ được ẩn đi.
  • T6- con quay được xoay 360/10 * 6 = 216 ° và tiếp tục quay.
  • T7- con quay được xoay 360/10 * 7 = 252 ° và tiếp tục quay.
  • T8- con quay được xoay 360/10 * 8 = 288 ° và tiếp tục quay.
  • T9- con quay được xoay 360/10 * 9 = 324 ° và tiếp tục quay.
  • T10- con quay xoay 360 °. Chúng tôi quay trở lại điểm xuất phát. Đặt lại hoạt ảnh. Mặt nạ xuất hiện và phần tử tô màu bị ẩn.

Tặng kem

Một vài thủ thuật bổ sung.

Tạm dừng khi di chuột

Wrapper: hover .filler, .wrapper: hover .spinner, .wrapper: hover .mask (animation-play-state: tạm dừng;)

Với mã này, bạn có thể dừng tất cả hoạt ảnh khi di chuột qua phần tử mẹ.

Chèn nội dung

Nhờ thuộc tính z-index, chúng ta có thể dễ dàng thêm một số nội dung vào con quay và làm cho nó quay. Hãy thử mã sau:

Spinner: after (content: ""; position: Absol; width: 10px; height: 10px; border-radius: 50%; top: 10px; right: 10px; background: #fff; border: 1px solid rgba (0,0 , 0,0.4); box-shadow: inset 0 0 3px rgba (0,0,0,0.2);)

Bộ tiền xử lý hoặc các biến CSS

Hiện tại, mã này rất khó bảo trì. Nhưng nếu chúng ta sử dụng các biến (trong bộ tiền xử lý hoặc các biến CSS nội bộ dự kiến), mọi thứ có thể trở nên dễ dàng hơn nhiều. Ví dụ: bạn có thể thêm các biến để kiểm soát thời lượng thay vì sửa mã trong 3 định nghĩa hoạt ảnh.

Nếu bạn muốn cải thiện khả năng bảo trì mã của mình mà không cần sử dụng bộ tiền xử lý, bạn có thể tạo một lớp với một điều khiển thời lượng hoạt ảnh và thêm nó vào 3 lớp con. Ví dụ như thế này:

Thời lượng hoạt ảnh (thời lượng hoạt ảnh: 10 giây;)

nhược điểm

Kỹ thuật này có một số nhược điểm:

  • Gradients không được hỗ trợ.
  • Bóng không được hỗ trợ.
  • Không có khả năng thích ứng. Nếu phần tử mẹ được thay đổi kích thước, thì mọi thứ sẽ ổn, ngoại trừ bán kính đường viền. Nó sẽ phải được thay đổi thủ công.
  • Không có ngữ nghĩa (4 yếu tố cho một hoạt ảnh).

Hỗ trợ trình duyệt

Vì chúng tôi đang sử dụng hoạt ảnh CSS, hỗ trợ trình duyệt khá kém:

  • Internet Explorer 10
  • Firefox 12+
  • Trình duyệt Chrome
  • Safari 5+
  • Opera 12+
  • iOS Safari 3+
  • Android 2+

Đối với một nhà phát triển front-end, có vô số cách để tạo biểu đồ hình tròn - nhiều thư viện, plugin, khả năng đồ họa SVG tuyệt vời, v.v. Tuy nhiên, có lẽ nên xem xét cách đơn giản nhất để tạo biểu đồ "hình tròn", có thể hữu ích khi nhiệm vụ được đặt càng đơn giản càng tốt và không có nhu cầu hoặc cơ hội sử dụng các công cụ bổ sung. Dưới đây chúng tôi sẽ nói về một ví dụ về cách triển khai như vậy.

Giả sử bạn có dữ liệu ban đầu ở dạng mảng mà bạn muốn biểu diễn trong biểu đồ hình tròn:

Tập dữ liệu Var = [(giá trị: 5, màu: "# dc3912"), (giá trị: 40, màu: "# ff9900"), (giá trị: 30, màu: "# 109618"), (giá trị: 25, màu: "# 990099")];

value là giá trị phần trăm, color là màu khu vực.

Đầu tiên, hãy tạo một vùng chứa sẽ trở thành vòng tròn của sơ đồ và sẽ chứa các phần tử của các cung:

Hãy tạo kiểu cho nó nữa:

Vùng chứa (chiều rộng: 300px; chiều cao: 300px; tràn: ẩn; bán kính đường viền: 50%; vị trí: tương đối;)

Kết quả là, chúng tôi nhận được một vòng tròn như vậy. Mọi thứ vượt ra ngoài ranh giới của nó (được hiển thị bằng một đường chấm) sẽ bị ẩn.

Tiếp theo, câu hỏi được đặt ra một cách tự nhiên - làm cách nào để biến các phần tử div hình chữ nhật thành các cung của một hình tròn và làm thế nào để tạo cho chúng một góc mong muốn? Trên thực tế, đối với mục đích đầu tiên, thuộc tính tràn: ẩn đã được đặt cho vùng chứa, vì điều này cho phép chúng tôi ẩn một phần của phần tử, làm cho nó được làm tròn và lần thứ hai, chúng tôi sẽ được hỗ trợ bởi các phép biến đổi CSS. Dưới đây là một ví dụ cho một lĩnh vực.

Thêm một div với lớp sector bên trong vùng chứa.

CSS:

Khu vực (chiều rộng: 50%; chiều cao: 50%; vị trí: tuyệt đối; trái: 50%; trên cùng: 0; biến đổi-gốc: dưới cùng bên trái; nền: # 000;)

Do đó, chúng tôi nhận được một sector có giá trị là 90 độ, bắt đầu từ 0 độ.

Để thiết lập góc mong muốn cho khu vực này, chúng tôi sẽ áp dụng phép chuyển đổi CSS xiên. Phép biến hình này làm dịch chuyển cạnh bên phải của hình vuông dọc theo trục y để các cạnh nằm ngang tạo thành một góc nhất định với vị trí ban đầu của chúng:

Giá trị giá trị trong phần tử đầu tiên của mảng tập dữ liệu là 5, chuyển đổi sang độ, chúng ta nhận được 18. Để độ nghiêng xảy ra theo hướng mong muốn, chúng ta sẽ thêm 90 độ vào tất cả các góc.

Như vậy, góc biến đổi = 90 + 18 = 108.

biến đổi: xiênY (108deg);

Để xoay một góc nhất định, chúng ta sẽ sử dụng phép biến đổi xoay. Điều quan trọng là phép chuyển đổi quay được áp dụng trước, chỉ sau đó phép chuyển đổi độ nghiêng mới được áp dụng.

Biến đổi: xoay (45deg) xiênY (108deg);

Phương pháp này có một nhược điểm - như bạn có thể thấy trong hình minh họa các giá trị của phép biến đổi xiên Y, vì vậy bạn có thể mô tả chính xác các cung có giá trị không quá 90 độ. Do đó, để hiển thị các giá trị lớn hơn 90, bạn sẽ phải vẽ một số cung cùng màu. Ví dụ: nếu giá trị góc là 100 độ, chúng ta sẽ hiển thị 2 cung: 90 độ và 10. Nếu giá trị là 200 độ, chúng ta sẽ nhận được 3 cung - 90, 90 và 20 độ, v.v.

Kết quả là, chúng tôi nhận được mã sau để thêm động các sector:

Var maxValue = 25; var container = $ (". container"); var addSector = function (data, startAngle, sập) (var sectorDeg = 3.6 * data.value; var perfwDeg = 90 + sectorDeg; var luân phiên

", (" lớp ":" khu vực ")). css ((" nền ": data.color," biến đổi ":" xoay ("+ xoayDeg +" độ) xiênY ("+ xiênDeg +" độ) ")) ; containerner.append (sector); return startAngle + sectorDeg;); dataset.reduce (function (pres, curr) (return (function addPart (data, angle) (if (data.value)<= maxValue) { return addSector(data, angle, false); } return addPart({ value: data.value - maxValue, color: data.color }, addSector({ value: maxValue, color: data.color, }, angle, true)); })(curr, prev); }, 0);

Kết quả:

Bạn có thể dễ dàng biến biểu đồ "hình tròn" như vậy thành biểu đồ "bánh rán" bằng cách thêm kiểu cho phần tử giả vào vùng chứa:

Vùng chứa: sau (nội dung: ""; vị trí: tuyệt đối; chiều rộng: 50%; chiều cao: 50%; nền: #fff; bán kính viền: 50%; trên cùng: 25%; trái: 25%;)