Als ich vor zwei Tagen nach Inspiration für Echarts suchte, sah ich viele ähnliche Beispiele für Karten, Kartenpositionierung usw., aber es schien keine U-Bahn-Karte zu geben, also habe ich einige Zeit damit verbracht, an dieser interaktiven U-Bahn-Kartendemo herumzubasteln Punkte auf der U-Bahn-Linie wurden zufällig aus dem Internet heruntergeladen. In diesem Artikel werden einige meiner Gewinne (schließlich bin ich noch ein Neuling) und die Implementierung des Codes aufgeführt. Ich hoffe, er kann einigen Freunden helfen. Wenn Sie eine Meinung haben, können Sie sie mir natürlich direkt mitteilen. Nur wenn wir gemeinsam kommunizieren, können wir Fortschritte machen.
Darstellungen
http://www.hightopo.com/demo/subway/index.html
Die Karte hat etwas zu viel Inhalt, die Schriftarten erscheinen etwas klein, aber das macht nichts. Sie können nach Bedarf hinein- oder herauszoomen. Die Schriftarten und gezeichneten Inhalte werden nicht verzerrt . Schließlich werden sie alle mit Vektoren gezeichnet ~
SchnittstellengenerierungDas zugrunde liegende Div wird über die Komponente ht.graph.GraphView generiert. Anschließend können Sie die guten Methoden von HT für Web verwenden und einfach den Canvas-Pinsel aufrufen, um beiläufig zu zeichnen.
var dm = new ht.DataModel();//Datencontainer var gv = new ht.graph.GraphView(dm);//Topologiekomponente gv.addToDOM();//Füge die Topologiediagrammkomponente zum Körper hinzu
Die Funktion addToDOM wird wie folgt deklariert:
addToDOM = function(){ var self = this, view = self.getView(), style = view.style; document.body.appendChild(view); //Füge das zugrunde liegende div der Komponente zum Body hinzu style.left = '0 ';//Die Standardkomponente ist absolut positioniert, also legen Sie die Position fest style.right = '0'; style.top = '0'; window.addEventListener('resize', function () { self.iv(); }, false); //Fensterwechselereignis}
Jetzt kann ich auf diesem Div kritzeln. Zuerst erhalte ich die Punkte auf der heruntergeladenen U-Bahn-Karte und füge sie in die Datei „subway.js“ ein. Diese js-Datei enthält den gesamten heruntergeladenen Inhalt. Ich habe nichts anderes vorgenommen. Die anderen Änderungen dienen hauptsächlich dem Hinzufügen dieser zeigt auf das Array entsprechend der Zeile, wie zum Beispiel:
mark_Point13 = [];//Das Linienarray enthält die Start- und Endkoordinaten der Linie und den Namen der Linie. t_Point13 = [];//Das Stationsarray enthält die Transferstationskoordinaten in der Linie und den Stationsnamen. n_Point13 = [ ];//Das kleine Stationsarray enthält die Koordinaten der kleinen Stationen auf der Linie und die Namen der kleinen Stationen mark_Point13.push({ name: 'Line 13', value: [113.4973,23.1095]}); mark_Point13.push({ name: 'Line 13', value: [113.4155,23.1080]}); t_Point13.push({ name: 'Yu Zhu', value: [113.41548,23.10547 ]} ); n_Point13.push({ name: 'Yufengwei', Wert: [113.41548,23.10004]});
Als nächstes habe ich zum Zeichnen der U-Bahn-Linien ein Array lineNum deklariert, das die Nummern aller U-Bahn-Linien in js enthält, und ein Farbarray, das die Farben aller U-Bahn-Linien enthält. Der Index dieser Farben ist derselbe wie der der U-Bahn Zeile in lineNum. Die nummerierten Indizes entsprechen eins zu eins:
var lineNum = ['1', '2', '3', '30', '4', '5', '6', '7', '8', '9', '13', '14 ', '32', '18', '21', '22', '60', '68'];var color = ['#f1cd44', '#0060a1', '#ed9b4f', '#ed9b4f', '#007e3a', '#cb0447', '#7a1a57', '#18472c', '#008193', '#83c39e', '#8a8c29', '#82352b', '#82352b', '#09a1e0', '#8a8c29', '#82352b', '#b6d300', '#09a1e0'];
Durchlaufen Sie dann lineNum, übergeben Sie die Elemente und Farben in lineNum an die Funktion createLine und zeichnen Sie die U-Bahn-Linien und die Farbanpassung gemäß diesen beiden Parametern. Schließlich ist die Benennungsmethode in der js-Datei auch regelmäßig die entsprechende Zahl, daher müssen wir nur die Zeichenfolge mit dieser Zahl kombinieren, um das entsprechende Array in js zu erhalten:
let lineName = 'Line' + num; let line = window[lineName]; Die Definition von createLine ist auch sehr einfach, daher sieht es etwas viel aus. Um eine ht.Polyline-Pipeline zu erstellen, können wir dieser Variablen über die Funktion polyline.addPoint() bestimmte Punkte hinzufügen und die Verbindungsmethode der Punkte über setSegments festlegen. function createLine(num, color) {//Eine Kartenlinie zeichnen var polyline = new ht.Polyline();//Polygonpipeline polyline.setTag(num);//Legen Sie die Knoten-Tag-Beschriftung als einzige Beschriftung fest if(num = == '68') polyline.setToolTip('AP M');//Eingabeaufforderungsinformationen festlegen else if(num === '60') polyline.setToolTip('G F'); polyline.setToolTip('Line' + num); if(color) { polyline.s({//s ist die Abkürzung von setStyle, set the style 'shape.border.width': 0.4,//Legen Sie die Rahmenbreite fest das Polygon 'shape .border.color': color,//Legen Sie die Randfarbe des Polygons 'select.width' fest: 0.2,//Setzen Sie die Rahmenbreite des ausgewählten Knotens ein'select.color': color//Legen Sie die Rahmenfarbe des ausgewählten Knotens fest}); for(let i = 0; i < line.length; i++) { for(let j = 0; j < line[i].coords.length; j++) { polyline.addPoint({x: line[i].coords[j][0]*300, y: -line[i].coords[j][1]*300}); if(num === '68'){//APM line (Es gibt zwei, aber die Punkte liegen im selben Array) if(i === 0 && j === 0) { polyline.setSegments([1] } else if(i === 1 &&); j === 0) { polyline.getSegments().push(1); } else { polyline.getSegments().push(2); } } } } polyline.setLayer('0');//Legen Sie die Linie fest Auf der unteren Ebene wird der Punkt auf die Oberseite der oberen Ebene gesetzt dm.add(polyline);//Fügen Sie die Pipeline zur Speicherung zum Datencontainer hinzu, andernfalls befindet sich die Pipeline in einem freien Zustand und wird nicht auf der Rückgabepolylinie der Topologiekarte angezeigt;}
Es gibt mehrere Situationen zum Hinzufügen von Punkten auf der U-Bahn-Linie im obigen Code. Dies liegt daran, dass Line68 beim Festlegen der Linie in js einen Sprungpunkt hat. Für die spezifische Deklaration von Line68 ist der Platz begrenzt Array, siehe metro.js.
Hierbei ist zu beachten, dass die hinzugefügten Punkte standardmäßig mit geraden Linien verbunden werden, wenn Sie die Funktion addPoint verwenden und keine Segmente festlegen. Die Definition von Segmenten lautet wie folgt:
1: moveTo, belegt 1 Punktinformation und stellt den Startpunkt eines neuen Pfads dar
2: lineTo, belegt 1 Punktinformation und stellt die Verbindung vom letzten Punkt zu diesem Punkt dar
3: quadraticCurveTo, belegt 2 Punktinformationen, der erste Punkt wird als Kurvenkontrollpunkt und der zweite Punkt als Kurvenendpunkt verwendet
4: bezierCurveTo, belegt 3 Punktinformationen, der erste und der zweite Punkt werden als Kurvenkontrollpunkte verwendet und der dritte Punkt wird als Kurvenendpunkt verwendet
5: closePath, belegt keine Punktinformationen, stellt das Ende dieser Pfadzeichnung dar und schließt am Anfangspunkt des Pfads
Wenn wir also ein Sprungverhalten durchführen möchten, setzen Sie die Segmente einfach auf 1.
Abschließend werden diese Punkte auf der U-Bahn-Linie gezeichnet. Die Namen beginnen mit mark_Point, t_Point und n_Point. Sie können Ihren Mittelfinger zum Scrollen bewegen hoch, um zu sehen.
Wir fügen an diesen Punkten ht.Node-Knoten hinzu. Wenn die Knoten zum dm-Datencontainer hinzugefügt werden, werden sie auf der Topologiekarte angezeigt. Voraussetzung ist natürlich, dass der von der Topologiekartenkomponente gv festgelegte Datencontainer dieser dm ist . Aus Platzgründen zeige ich nur den Codeteil zum Hinzufügen von Punkten auf der U-Bahn-Linie:
var tName = 't_Point' + num;var tP = window[tName];//Große Station if(tP) {//Einige Linien haben keine Übergabestationen for(let i = 0; i < tP.length; i++) { let node = createNode(tP[i].name, tP[i].value, color[index]);//Knoten hinzufügen node.s({//Knotenstil festlegen style 'label.scale': 0,05,//Textskalierung zur Vermeidung von Browsereinschränkungen Das Problem der minimalen Schriftgröße'label.font': ' fett 12px arial, sans-serif'//Legen Sie die Schriftart des Textes fest }); node.setSize(0.6, 0.6);//Legen Sie die Knotengröße fest. Da der Versatz zwischen den einzelnen Punkten in js zu klein ist, musste ich den Knoten kleiner einstellen node.setImage('images/rotating Arrow.json');//Setze das Bild des Knotens node.a('alarmColor1 ', ' RGB(150, 150, 150)'); //attr-Attribut, Sie können hier alles festlegen, was im JSON des oben eingestellten Bildes festgelegt ist. Weitere Informationen finden Sie im HT for Web Vector Manual (http://www.hightopo . com/guide/guide/core/vector/ht-vector-guide.html#ref_binding) node.a('alarmColor2', 'rgb(150, 150, 150)');//Wie oben node.a('tpNode', true);//Diese Eigenschaftseinstellung wird nur zur Unterscheidung von Übertragungsstandorten und kleinen Standorten verwendet, die später verwendet werden}}
Alle U-Bahnlinien und Stationen wurden hinzugefügt. Aber! Möglicherweise können Sie die von Ihnen gezeichneten Diagramme nicht sehen, da sie zu klein sind. Zu diesem Zeitpunkt können Sie die Funktion „fitContent“ für die Topologiekomponente „graphView“ festlegen. Übrigens stellen wir auch alles im Topologiediagramm auf „unbeweglich“ ein.
gv.fitContent(false, 0.00001);//Adaptive Größe, Parameter 1 ist, ob animiert werden soll, Parameter 2 ist der Füllwert von gv und Grenze gv.setMovableFunc(function(){ return false;//Setze den Knoten auf gv auf unbeweglich sein });
Jetzt kann Ihre U-Bahn-Streckenkarte angezeigt werden. Werfen wir einen Blick auf die Interaktion.
InteraktionDas erste ist das Mausbewegungsereignis, wenn die Maus über eine bestimmte Linie gleitet. Wenn Sie eine Weile mit der Maus darüber fahren, können Sie auch die Nummer dieser Linie sehen Bei einer kleinen Site wird das der Site entsprechende Symbol größer und wenn sich die Farbe ändert, wird auch die Schriftart größer. Wenn Sie die Maus bewegen, kehrt das Symbol zu seiner ursprünglichen Farbe zurück und die Schriftart wird kleiner. Der Unterschied besteht darin, dass sich die Transferstation dreht, wenn die Maus zur Transferstation bewegt wird.
Für das Mausschiebeereignis führe ich das Mausbewegungsereignis direkt basierend auf dem zugrunde liegenden Div von gv aus, übergebe die Ereignisparameter über die von ht gekapselte Funktion getDataAt, erhalte den entsprechenden Knoten unter dem Ereignis und kann den Knoten dann nach Belieben bedienen :
gv.getView().addEventListener('mousemove', function(e) { var data = gv.getDataAt(e);//Übergeben Sie den logischen Koordinatenpunkt oder den Ereignisparameter des interaktiven Ereignisses und geben Sie das Grundelement unter dem aktuellen Punkt zurück if( name ) { originNode(name);//Knoten jederzeit in seiner Originalgröße belassen} if (Dateninstanz von ht.Polyline) {//Bestimmen Sie den Typ des Ereignisknotens dm.sm().ss(data);//Wählen Sie den Pipe-Namen = ''; clearInterval(interval); getTag( ) !== name && data.a('tpNode')) {//Wenn es sich nicht um denselben Knoten handelt und das Mousemove-Ereignisobjekt vom Typ ht.Node ist, legen Sie das Rotationsintervall des Knotens = fest setInterval(function() { data.setRotation(data.getRotation() - Math.PI/16); //Rotieren basierend auf seiner eigenen Rotation}, 100); /Wenn sich die Maus zu einer kleinen Site bewegt, stoppen Sie die Animation. clearInterval(interval); } expandNode(data, Name);////Angepasste Zoomknotenfunktion, relativ einfach, ich halte mich nicht mehr an den Code, Sie können zu http://hightopo.com/ gehen, um dm.sm().ss(data) anzuzeigen; //Setzen Sie den ausgewählten Knotennamen ein = data.getTag();//Als Speichervariable des vorherigen Knotens können Sie den Knoten über diesen Wert abrufen} else {//In allen anderen Fällen wird nichts ausgewählt und die Animation läuft Die Übertragungsstelle wird gelöscht dm.sm( ).ss(null); name = ''; clearInterval(interval }});
Wenn die Maus über einer U-Bahn-Linie schwebt, werden die spezifischen Linieninformationen angezeigt, indem ich den Tooltip einstelle (Hinweis: Der Tooltip-Schalter von gv muss eingeschaltet sein):
gv.enableToolTip();//Schalten Sie den Tooltip-Schalter ein if(num === '68') polyline.setToolTip('AP M');//Legen Sie die Eingabeaufforderungsinformationen fest else if(num === '60') polyline.setToolTip('G F'); else polyline.setToolTip('Line' + num);
Dann verwende ich das Formular in der unteren rechten Ecke, um auf eine bestimmte Zeile im Formular zu klicken, oder doppelklicke auf einen beliebigen Standort oder eine beliebige Zeile auf der Topologiekarte. Die Topologiekarte passt sich dem entsprechenden Teil und dem doppelt angeklickten Teil an wird in der Mitte der Topologiekarte angezeigt.
Ich habe den Deklarationsteil des Formulars anscheinend noch nicht erklärt. . . Das heißt, eine Formularkomponente über die neue Klasse ht.widget.FomePane zu erstellen, das zugrunde liegende Div der Formularkomponente über form.getView() abzurufen, dieses Div in der unteren rechten Ecke des Körpers zu platzieren und dann eine Zeile hinzuzufügen Um das Formular über die Funktion „addRow“ zu bilden, können Sie über „addRow“ eine beliebige Anzahl von Elementen in dieser Zeile hinzufügen Der zweite Parameter der Funktion (ein Array) legt die Breite des hinzugefügten Formularelements fest und der dritte Parameter legt die Höhe der Zeile fest:
function createForm() {//Erstellt das Formular in der unteren rechten Ecke var form = new ht.widget.FormPane(); form.setWidth(200);//Legt die Formularbreite fest form.setHeight(416);// Stellen Sie die Formularhöhe ein let view = form.getView(); document.body.appendChild(view);//Fügen Sie das Formular zum Textkörper hinzu view.style.zIndex = 1000; view.style.bottom = '10px'; // Fast alle HT-Komponenten legen absolute Pfade fest view.style.right = '10px' view.style.background = 'rgba(211, 211, 0.8)'; forEach(function(nameString) { form.addRow([//Eine Zeile zum Formular hinzufügen{//Die erste Formularelementschaltfläche in dieser Zeile: {//Schaltflächensymbol zum Formular hinzufügen: 'images/Line'+nameString.value+'.json',//Legen Sie den Hintergrund des Schaltflächensymbols fest: '',//Legen Sie die Hintergrundfarbe der Schaltfläche fest: '',//Legen Sie fest Rahmenfarbe der anklickbaren Schaltfläche: false//Stellen Sie die Schaltfläche so ein, dass sie nicht anklickbar ist} }, {//Die zweite Formularelementschaltfläche: { label: nameString.name, labelFont: 'bold 14px arial, sans-serif', labelColor: '#fff', Hintergrund: '', borderColor: '', onClicked: function() {//Button click callback event gv.sm().ss(dm.getDataByTag(nameString.value) );//Legen Sie die Zeile fest, die der ausgewählten gedrückten Schaltfläche entspricht gv.fitData(gv.sm().ld(), true, 5);// Zeigt die ausgewählte U-Bahn-Linie in der Mitte der Topologiekarte an} } } ], [0.1, 0.2], 23);//Der zweite Parameter besteht darin, die Breite des Arrays im ersten Parameter auf weniger festzulegen größer als 1 ist das Verhältnis, größer als 1 ist die tatsächliche Breite. Der dritte Parameter ist die Höhe der Zeile});}.
Klicken Sie auf die Site, um die rote Markierung anzuzeigen, doppelklicken Sie auf den Knoten, um ihn adaptiv in der Mitte der Topologiekarte zu platzieren, und doppelklicken Sie auf die leere Stelle, um die rote Markierung auszublenden. Der Inhalt wird durch die Ereignisüberwachung der Topologiekomponente gesteuert gv. Der Code ist sehr klar und leicht zu verstehen:
var node = createRedLight();//Erstelle einen neuen Knoten, der als Rotlichtstil angezeigt wird gv.mi(function(e) {//Ereignisüberwachung in der Topologiekomponente in ht if(e.kind === 'clickData ' && (e.data.a('tpNode') || e.data.a('npNode'))) {//e.kind ruft den aktuellen Ereignistyp ab, e.data ruft den Knoten unter dem aktuellen Ereignis ab node.s('2d.visible', true);//Setzen Sie den Knotenknoten auf sichtbar node.setPosition(e. data.getPosition() .x, e.data.getPosition().y);//Setze die Koordinaten des Knotens auf die Position des Knotens unter dem aktuellen Ereignis} else if(e.kind === 'doubleClickData') {//Doppelklicken Sie auf den Knoten gv.fitData(e.data, false, 10);//Passen Sie den Knoten unter dem Ereignis an die Mitte der Topologiekarte an. Parameter 1 ist der adaptive Knoten, Parameter 2 gibt an, ob animiert werden soll , und Parameter 3 ist Padding of gv and border } else if(e.kind === 'doubleClickBackground') {//Doppelklicken Sie auf das Leerzeichen node.s('2d.visible', false);//Legen Sie die fest Knotenknoten soll unsichtbar sein View HT for Web Style-Handbuch (http://www.hightopo.com/guide/guide/core/theme/ht-theme-guide.html#ref_style) }});
Beachten Sie, dass s (style) und a (attr) wie folgt definiert sind: s sind einige von ht vordefinierte Stilattribute, und a ist ein von unseren Benutzern angepasstes Attribut. Das Ergebnis wird normalerweise durch Aufrufen einer Zeichenfolge aufgerufen eine Konstante oder eine Funktion sein, was sehr flexibel ist.
Abschließend wird ein kleiner Teil erstellt. Wenn eine Site ausgewählt ist, wird über der Site ein rotes Atmungssymbol angezeigt, um die aktuell ausgewählte Site anzuzeigen.
Der Atmungsteil wird mit der setAnimation-Funktion von ht abgeschlossen. Bevor Sie diese Funktion verwenden, müssen Sie zuerst den Animationsschalter des Datencontainers einschalten und dann die Animation einstellen:
dm.enableAnimation();//Aktivieren Sie die Animationsschaltfunktion des Datencontainers createRedLight() { var node = new ht.Node(); node.setImage('images/RedLight.json');//Stellen Sie das Bild ein Knoten des Knotens .setSize(1, 1);//Legen Sie die Größe des Knotens fest node.setLayer('firstTop');//Legen Sie den Knoten fest, der auf der obersten Ebene von gv angezeigt werden soll node.s('2d.visible', false);//Der Knoten ist unsichtbar node.s('select.width', 0);//Der Rand, wenn der Knoten ausgewählt ist, ist 0 und unsichtbar node.s('2d.selectable', false);//Setzen Sie dieses Attribut ein, der Knoten kann nicht ausgewählt werden node.setAnimation({//Weitere Informationen zum Festlegen der Animation finden Sie im HT for Web Animation Manual (http://www.hightopo.com/guide/guide /plugin/animation/ht-animation-guide.html) expandWidth: { property: width,//Legen Sie diese Eigenschaft fest und der accessType ist nicht festgelegt. Standardmäßig wird die Eigenschaft über setWidth/getWidth festgelegt und abgerufen. Die Breite hier und Die unten angegebene Höhe wird verwendet. Sie werden alle durch die zuvor festgelegte Größe erhalten von: 0,5, //Attributwert am Anfang der Animation bis: 1,//Attributwert am Ende der Animation als nächstes: collapWidth//String-Typ, gibt an, was danach ausgeführt werden soll die aktuelle Animation ist abgeschlossen. Die nächste Animation kann mehrere Animationen zusammenführen}, collapWidth: { Eigenschaft: Breite, von: 1, bis: 0,5, weiter: expandWidth }, expandHeight: { Eigenschaft: Höhe, von: 0,5, bis: 1, next: collapHeight }, collapHeight: { property: height, from: 1, to: 0.5, next: expandHeight }, start: [expandWidth, expandHeight]//Array, wird verwendet, um eine oder mehrere zu startende Animationen anzugeben} ) ; dm.add(node); return node;}
Der ganze Code ist vorbei!
ZusammenfassenEs hat mich zwei Tage gekostet, diese Demo zu absolvieren, und ich hatte immer das Gefühl, nicht dazu bereit zu sein. Manchmal kam ich jedoch nicht damit klar und es hat viel Zeit gekostet, aber im Großen und Ganzen habe ich viel gewonnen Solange ich bestanden habe, habe ich einfach getPoints().push verwendet, um dem Polygon Punkte hinzuzufügen. Nachdem ich einen Master um Hilfe gebeten hatte, stellte ich fest, dass diese Methode nicht nur Umwege ist, sondern auch verschiedene Probleme verursacht , müssen Sie bereits Punkte im Polygon haben. Dies ist möglich, aber in vielen Fällen sind die initialisierten Punkte nicht einfach festzulegen und der Code ist sehr umständlich. Punkte werden über die Methode addPoint direkt zur Polygonvariablen hinzugefügt und die Punkte werden standardmäßig durch gerade Linien verbunden. Es ist nicht nötig, Segmente festzulegen, was für eine schöne Funktion.
Da die Standardzoomgröße von ht 20 beträgt und der Abstand meiner Demo sehr klein ist, ist die Anzeige der U-Bahn-Linienkarte auch sehr klein, wenn sie auf das Maximum gezoomt wird. Daher habe ich das Standardattribut zoomMax von ht in htconfig geändert , ändern Dieser Wert muss vor allen ht-Aufrufen stehen, da die in htconfig festgelegten Werte später nicht geändert werden können.
Das Obige ist die interaktive U-Bahn-Linienkarte auf Basis von HTML5 Canvas, die Ihnen der Herausgeber vorstellt. Wenn Sie Fragen haben, hinterlassen Sie mir bitte eine Nachricht und der Herausgeber wird Ihnen rechtzeitig antworten. Ich möchte mich auch bei allen für die Unterstützung der VeVb-Kampfsport-Website bedanken!