這篇文章主要為大家介紹了關於前端演算法之文字避讓的相關資料,對於這個知識相信很多的朋友都不知道,但看到效果會驚嘆不已,實現這一個效果主要利用的是inMap文字避讓功能,文中透過範例程式碼介紹的非常詳細,需要的朋友可以參考借鑒,下面來一起學習學習吧。
前言
inMap 是基於 canvas 的大數據視覺化函式庫,專注於大數據方向點線面的視覺化效果展示。目前支援散點、圍欄、熱力、網格、聚合等方式;致力於讓大數據視覺化變得簡單易用。
GitHub 網址:https://github.com/TalkingData/inmap(本機下載)
文件網址:http://inmap.talkingdata.com/
在在地理資訊視覺化中,我們常會遇到在地圖上標記文字的需求,下面展示的是某流行chart 圖錶框架的效果:
要顯示的文字空間不夠時,就會造成文字重疊顯示混亂,使用者體驗很不友善。
怎麼解決這個問題呢?我們採用文字避讓演算法,解決這種坑爹的問題。
下面展示的是inMap 文字避讓效果:
文字標註演算法是GIS 中最複雜的問題之一(屬於NP 複雜度問題,所以通常無法找到最優解,只能找到較優解)。
inMap 避讓演算法採用的是四分位模型演算法,接下來手把手教你寫避讓演算法,老司機帶你裝逼帶你飛。
準備資料
inMap 接收的是經緯度數據,需要把它映射到canvas 的像素座標,這就用到了墨卡托轉換,墨卡托演算法很複雜,以後我們會有單獨的一篇文章來講講他的原理。經過轉換,你得到的資料應該是這樣的:
[ { "name": "海门",//要显示的文字 "lng": 121.15, "lat": 31.89, "count": 7, "pixel": { //像素坐标 "x": 968, "y": 736 } }, { "name": "鄂尔多斯", "lng": 109.781327, "lat": 39.608266, "count": 5, "pixel": { "x": 659, "y": 478 } }, ... ]
好了,我們得到轉換後的像素座標資料(x、y),就可以做下面的事情了。
求出每段文字矩形的實際大小
#measureText() 是canvas 內建的方法,傳回字體寬度的像素單位:
let ctx = this.container.getContext('2d'); // canvas 上下文 let width= ctx.measureText(name).width;
我們透過measureText 得到每個文字的寬度,canvas 並沒有直接取得文字的方法,那文字的高度如何的得到呢?
我們透過反覆測試發現 canvas 的 font 等於 “13px Arial” 字體(別的字體不敢保證)的時候,文字的高度大概是 fontSize 的 1.1 倍。
所以程式碼如下:
let fontSize = parseInt(ctx.font); let height = fontSize * 1.1;
文字的寬度和高度得到後,我們就可以建立文字矩形的座標係了。
建立四分位模型
#所謂四分位模型,每個標記點都有上下左右四個放文字的位子,如果左邊放不下,那就放右邊試試,還不行就放到下面試試,以此類推,原理就這麼簡單,哈哈。
建立右側虛擬矩形座標描述:
右邊虛擬矩形座標的描述把圓點也包含在內了,是為了防止文字和圓點重疊。
在計算虛擬矩形的高度時有些坑,圓點大小不是固定的,是根據使用者動態配置的,圓點的直徑可能大於文字的高度,我們就設定虛擬矩形的高度永遠都是最大的那個,需要做一些特殊處理。
程式碼如下:
_getLeftAnchor() { let x = this.center.x - this.radius - this.textReact.width, y = this.center.y - this.textReact.height / 2, diam = this.radius * 2, maxH = diam > this.textReact.height ? diam : this.textReact.height; //矩形的高度 return { x, y, minX: x, maxX: this.center.x + this.radius, minY: this.center.y - maxH / 2, maxY: this.center.y + maxH / 2 }; }
以此類推,描述下面、左面、上面的虛擬矩形座標。
判斷碰撞
判斷兩個矩形是否覆蓋相交,根據矩形的minX,maxX,minY,maxY 判斷相交,原理比較簡單,程式碼如下:
/** * 判断分位是否相交 * @param {*} target */ isAnchorMeet(target) { let react = this.getCurrentRect(), targetReact = target.getCurrentRect(); if ((react.minX < targetReact.maxX) && (targetReact.minX < react.maxX) && (react.minY < targetReact.maxY) && (targetReact.minY < react.maxY)) { return true; } return false; }
建立虛擬文字集合物件
#let labels = pixels.map((val) => { let radius = val.pixel.radius + this.style.normal.borderWidth; //圆点半径 return new Label(val.pixel.x, val.pixel.y, radius, fontSize, byteWidth, val.name); });
遞歸遍歷虛擬文字集合、判斷是否與其他相交,如果有相交就移動目前文字位子,直到不相交為止。當找不到合適位置時,就選擇隱藏目前文字。
程式碼如下:
do { var meet = false; //本轮是否有相交 for (let i = 0; i < labels.length; i++) { let temp = labels[i]; for (let j = 0; j < labels.length; j++) { if (i != j && temp.show && temp.isAnchorMeet(labels[j])) { temp.next(); meet = true; break; } } } } while (meet);
繪畫文字
#labels.forEach(function (item) { if (item.show) { //是否显示 let pixel = item.getCurrentRect(); ctx.beginPath(); ctx.fillText(item.text, pixel.x, pixel.y); ctx.fill(); } });
文字避讓演算法到目前介紹完了,對應的inMap 檔案位址為https://github.com/TalkingData/inmap/blob/master/src/worker/helper/Label.js,接下來也會繼續跟大家分享乾貨。
上面是我整理給大家的,希望今後對大家有幫助。
相關文章:
以上是前端演算法中有關文字避讓的問題(詳細教學)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

Node.js擅長於高效I/O,這在很大程度上要歸功於流。 流媒體匯總處理數據,避免內存過載 - 大型文件,網絡任務和實時應用程序的理想。將流與打字稿的類型安全結合起來創建POWE

Python和JavaScript在性能和效率方面的差異主要體現在:1)Python作為解釋型語言,運行速度較慢,但開發效率高,適合快速原型開發;2)JavaScript在瀏覽器中受限於單線程,但在Node.js中可利用多線程和異步I/O提升性能,兩者在實際項目中各有優勢。

JavaScript起源於1995年,由布蘭登·艾克創造,實現語言為C語言。 1.C語言為JavaScript提供了高性能和系統級編程能力。 2.JavaScript的內存管理和性能優化依賴於C語言。 3.C語言的跨平台特性幫助JavaScript在不同操作系統上高效運行。

JavaScript在瀏覽器和Node.js環境中運行,依賴JavaScript引擎解析和執行代碼。 1)解析階段生成抽象語法樹(AST);2)編譯階段將AST轉換為字節碼或機器碼;3)執行階段執行編譯後的代碼。

Python和JavaScript的未來趨勢包括:1.Python將鞏固在科學計算和AI領域的地位,2.JavaScript將推動Web技術發展,3.跨平台開發將成為熱門,4.性能優化將是重點。兩者都將繼續在各自領域擴展應用場景,並在性能上有更多突破。

Python和JavaScript在開發環境上的選擇都很重要。 1)Python的開發環境包括PyCharm、JupyterNotebook和Anaconda,適合數據科學和快速原型開發。 2)JavaScript的開發環境包括Node.js、VSCode和Webpack,適用於前端和後端開發。根據項目需求選擇合適的工具可以提高開發效率和項目成功率。

是的,JavaScript的引擎核心是用C語言編寫的。 1)C語言提供了高效性能和底層控制,適合JavaScript引擎的開發。 2)以V8引擎為例,其核心用C 編寫,結合了C的效率和麵向對象特性。 3)JavaScript引擎的工作原理包括解析、編譯和執行,C語言在這些過程中發揮關鍵作用。

JavaScript是現代網站的核心,因為它增強了網頁的交互性和動態性。 1)它允許在不刷新頁面的情況下改變內容,2)通過DOMAPI操作網頁,3)支持複雜的交互效果如動畫和拖放,4)優化性能和最佳實踐提高用戶體驗。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

SublimeText3漢化版
中文版,非常好用

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能