Heim  >  Artikel  >  Web-Frontend  >  Probleme im Zusammenhang mit der Textvermeidung in Front-End-Algorithmen (ausführliches Tutorial)

Probleme im Zusammenhang mit der Textvermeidung in Front-End-Algorithmen (ausführliches Tutorial)

亚连
亚连Original
2018-06-12 14:34:142523Durchsuche

Dieser Artikel führt Sie hauptsächlich in die relevanten Informationen zur Textvermeidung im Front-End-Algorithmus ein. Ich glaube, viele Freunde kennen dieses Wissen nicht, aber sie werden erstaunt sein, wenn sie die Hauptverwendung von inMap-Text sehen Um diesen Effekt zu erzielen, wird die Vermeidungsfunktion anhand des Beispielcodes in diesem Artikel ausführlich vorgestellt. Lassen Sie uns gemeinsam darauf zurückgreifen.

Vorwort

inMap ist eine auf Leinwand basierende Big-Data-Visualisierungsbibliothek, die sich auf die visuelle Darstellung von Big-Data-Richtungspunkten, -linien und -flächen konzentriert . Unterstützt derzeit Scatter-, Fence-, Thermal-, Grid-, Aggregation- und andere Methoden, die darauf abzielen, die Visualisierung großer Datenmengen einfach und benutzerfreundlich zu gestalten.

GitHub-Adresse: https://github.com/TalkingData/inmap (lokaler Download)

Dokumentadresse: http://inmap.talkingdata.com/

at Bei der Visualisierung geografischer Informationen müssen wir häufig Text auf der Karte markieren. Das Folgende zeigt den Effekt eines beliebten Diagrammrahmens:

Der anzuzeigende Textbereich Wenn dies nicht ausreicht, führt dies zu überlappendem Text und einer verwirrenden Anzeige, was die Benutzererfahrung sehr unfreundlich macht.

Wie kann dieses Problem gelöst werden? Wir verwenden einen Textvermeidungsalgorithmus, um dieses Betrugsproblem zu lösen.

Das Folgende zeigt den inMap-Textvermeidungseffekt:

Der Textanmerkungsalgorithmus ist eines der komplexesten Probleme in GIS (gehört zum NP-Komplexitätsproblem, daher kann normalerweise nicht die optimale Lösung gefunden werden, sondern nur die bessere Lösung).

Der inMap-Vermeidungsalgorithmus verwendet den Quartilmodellalgorithmus. Als nächstes werde ich Ihnen Schritt für Schritt beibringen, wie Sie den Vermeidungsalgorithmus schreiben.

Daten vorbereiten

inMap empfängt die Breiten- und Längengraddaten und muss sie den Pixelkoordinaten der Leinwand zuordnen, die Mercator Conversion verwendet Der Algorithmus von Mercator ist sehr kompliziert, und wir werden in Zukunft einen separaten Artikel veröffentlichen, um seine Prinzipien zu erläutern. Nach der Konvertierung sollten die Daten, die Sie erhalten, wie folgt aussehen:

[
 {
 "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
 }
 },
...
]

Okay, jetzt, da wir die konvertierten Pixelkoordinatendaten (x, y) haben, können wir Folgendes tun.

Ermitteln Sie die tatsächliche Größe jedes Textrechtecks

measureText() ist eine integrierte Methode von Canvas, die die Pixeleinheit von zurückgibt die Schriftbreite:

let ctx = this.container.getContext('2d'); // canvas 上下文
let width= ctx.measureText(name).width;

Wir ermitteln die Breite jedes Textes durch „measureText“. Canvas verfügt nicht über eine direkte Methode, um den Text zu ermitteln. Wie erhält man also die Höhe des Textes?

Durch wiederholte Tests haben wir festgestellt, dass die Texthöhe etwa das 1,1-fache der Schriftgröße beträgt, wenn die Canvas-Schriftart der Schriftart „13px Arial“ entspricht (andere Schriftarten können nicht garantiert werden).

Der Code lautet also wie folgt:

let fontSize = parseInt(ctx.font);
let height = fontSize * 1.1;

Nachdem die Breite und Höhe des Texts ermittelt wurden, können wir das Koordinatensystem des Textrechtecks ​​erstellen.

Erstellen Sie ein Quartilmodell

Das sogenannte Quartilmodell, jeder Markierungspunkt hat Es gibt Vier Stellen für Text oben, unten, links und rechts. Wenn Sie es nicht auf der linken Seite platzieren können, versuchen Sie es mit der Platzierung auf der rechten Seite So weiter. Das Prinzip ist so einfach, haha.

Erstellen Sie eine Beschreibung der Koordinaten des virtuellen Rechtecks ​​auf der rechten Seite:

Die Beschreibung der Koordinaten des virtuellen Rechtecks ​​auf der rechten Seite enthält auch Punkte um zu verhindern, dass sich Text und Punkte überlappen.

Bei der Berechnung der Höhe des virtuellen Rechtecks ​​gibt es einige Fallstricke. Die Größe des Punkts ist nicht festgelegt, sondern wird je nach Benutzer dynamisch konfiguriert. Der Durchmesser des Punkts kann größer sein als die Höhe des Daher legen wir die Höhe des virtuellen Rechtecks ​​auf immer fest. Es ist das größte und erfordert eine spezielle Handhabung.

Der Code lautet wie folgt:

_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
  };
}

Und so weiter und beschreibt die Koordinaten des virtuellen Rechtecks ​​unten, links und oben.

Kollision beurteilen

Beurteilen Sie, ob sich zwei Rechtecke überdecken und schneiden, basierend auf minX, maxX, minY, maxY Das Prinzip ist relativ einfach, der Code lautet wie folgt:

/**
 * 判断分位是否相交
 * @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;
}

Erstellen Sie ein virtuelles Textsammlungsobjekt

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);
});

Durchlaufen Sie das rekursiv Virtuelle Textsammlung und bestimmen Sie, ob sie sich mit anderen überschneidet. Verschieben Sie einfach die aktuelle Textposition, bis sie sich nicht mehr überschneiden. Wenn Sie keinen geeigneten Ort finden, können Sie den aktuellen Text ausblenden.

Der Code lautet wie folgt:

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);

Text malen

labels.forEach(function (item) {
  if (item.show) { //是否显示
    let pixel = item.getCurrentRect();
    ctx.beginPath();
    ctx.fillText(item.text, pixel.x, pixel.y);
    ctx.fill();
  }
});

Der Textvermeidungsalgorithmus wurde bisher eingeführt. und die entsprechende inMap-Dateiadresse Es ist https://github.com/TalkingData/inmap/blob/master/src/worker/helper/Label.js Ich werde auch in Zukunft nützliche Informationen mit Ihnen teilen.

Ich habe das Obige für Sie zusammengestellt und hoffe, dass es Ihnen in Zukunft hilfreich sein wird.

Verwandte Artikel:

So implementieren Sie einen festen Tabellenkopf und eine feste erste Spalte in Vue

Wie Express+Multer die Bild-Upload-Funktion implementiert

Nativ So implementieren Sie einen Musikplayer in JS

So legen Sie Benutzerberechtigungen in VueJS fest

So verwenden Sie die ScrollTab-Komponente von YDUI im WeChat-Applet

Das obige ist der detaillierte Inhalt vonProbleme im Zusammenhang mit der Textvermeidung in Front-End-Algorithmen (ausführliches Tutorial). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn