モスクワ地下鉄のインタラクティブなベクトル図を作成します

モスクワの地下鉄は変化しています。 たとえば、1945年にスキームを想像したい人は、オープンソースからデータを簡単に収集します。 質問は結果の表示に残ります-円グラフで表示しないでください。 記事では、例えば74歳の5月1日(左)または深さ30メートル以上の駅(右)の地下鉄スキームを表示できる概念実証 サービスを作成する主な手順について説明します。







要件を策定します



  1. 選択した日付範囲の駅と路線を表示する

  2. 美しさ-「Lebedev Studio」は素晴らしいスキームを開発しました。 基礎としてそれを取る。
  3. 使いやすさ。

    • 値を入力するために、 範囲スライダーを使用することにしました。 それらを使用して、双方向性と変更をオンザフライで実現します。
    • 縮尺の変更と地図の移動を可能にする地図作成サービスの機能に慣れています。 さらに、実際には、このスキームはマップです。
    • 選択へのリンクを共有する機能を追加します。




読者は少なくともJavaScriptに表面的に精通しており、ベクターグラフィックスの概念を持ち、一般的によくできていることを前提としています(エラーまたは最適でないソリューションに気づき、コメントに最適なオプションを提供するのが面倒ではありません)



スキームを表示します



回路をインタラクティブにするために、最初に、回路自体が必要です。 私たちが欲しいものを見て、絵を簡単な要素にしましょう。





図で最も重要なのはステーションであるため、それらから始めましょう。 ファイナル、インターチェンジ、通常の3つのタイプのみ。 2つの長方形と円。 何がもっと簡単だろうか? それらをキャンバス上に慎重に配置し、いくつかも回転させます。



1チップ
スキームを画像として保存し、低い透明度を設定して、同じサイズを設定するsvg-canvasの下に配置します。 これにより、ステーションの配置が簡素化されます。


このようなものを入手してください




快適に移動するために、ステーションのプロパティにインデックス(数値)とラインも追加しました-少し下がれば、なぜこれが行われるのか理解できます。



2チップ
概念実証以外のことをしている場合は、ステーションをドラッグアンドドロップしてそのプロパティを示す機能を備えたエディターを書くのに数時間を割く必要はありません。 あなたのカードを提供することは、桁違いに簡単になります。 便宜性は、ステーションの数とその特性に直接比例します。





ラインとは何ですか? これは、ステーション間のセグメントのセットです。 座標、インデックス、ステーションラインがあるため、セグメントを簡単に描画できます。 駅を歩いていくと、各駅について次のロジックがガイドされます。同じラインの駅があり、インデックスが1より古い場合は、それらの間にセグメントを描画します。



を見て、描画されない2つのセグメントを答えてみてください。



答え
1.ステーションインデックスに応じて「ジュニア」と「シニア」を接続するリング上のセグメント

2.「展示」と「キエフ」の間のセグメント



後で説明するように、セグメントの開始と終了は、必要なとおりに正確に進みません。 3種類のステーションごとに、実験的に計算されたオフセットを追加します。 セグメントも直線に設定されていますが、線自体は多くの場所で奇妙に湾曲しています。 おそらく、これはプロジェクトの最も骨の折れる部分です。いくつかのセグメントでは、動作に例外を追加しています。 幸いなことに、構文は単純です。



中間バージョンです




遷移



Svgグラフィックはレイヤーモデルを使用します。つまり、目的の結果を得るために、2つの曲線を使用して各トランジションを作成します。太いストロークの色を低く、白のストロークを薄くします。 要素の全体的な配置は、下から上に次のとおりです。線、太い太いアウトラインのある遷移セグメント、駅、細い白いストロークのある遷移セグメント、駅名の下敷き、駅名。



駅名と背景



text-anchorプロパティを使用して、名前を表示し、テキストを揃えます。 残念ながら、追加の要素を作成しない限り、行の折り返しを実行する方法はありません。



テキスト素材を通常の半透明の長方形にします。 getBBoxを使用して取得するテキストのサイズと座標。



3つのヒント
テキスト素材に対するよりエレガントなソリューションを探してしばらく時間を費やした後、stackoverflowでフィルターを使用するためのプラスの提案が見つかります。 このソリューションは、グラフィックスが1つだけ表示される場合にのみ使用することをお勧めします。 グラフィックスをさらに操作することが想定される場合、フィルターは正しく動作しません。



塗り直し



線の色としてステーションのデフォルトの色を選択しました。 しかし、任意のグラデーションに従ってすべての色を変更したい場合はどうでしょうか? 見た目ほど難しくありません。



ある色から別の色への任意のグラデーションがあります。便宜上、チャンネル、ステーション値(たとえば、深さ23メートル)、最大値と最小値(地上局の場合は0、最深部の「勝利公園」の場合は80)を使用します。 極値の差に対するステーション値のパーセンテージ比を計算し、結果の比は各チャネルの値の差に適用できます。 これが私たちの色です。



ページ上の残りの要素をグラデーションで色付けし、ステーションの座標と色を用意します-それが必要なのはそれだけです。



フィルタリング



ここでも、大胆不敵です。 ステーション値が選択範囲内にあるかどうかを確認し、そうでない場合はステーションを非表示にします。 ステーションを扱うとき、残りの要素の処理方法を理解します。ステーションが非表示の場合、名前もトランジションもブランチのセグメントも表示されません。



4チップ
不透明度は要素を非表示にしますが、選択可能およびクリック可能のままにするため、可視性プロパティを使用します。


一部のステーションには同じ名前があることもわかります。 したがって、名前を非表示にする必要があるのは、この名前に関連付けられている最後のステーションが非表示になっている場合のみです。



好みの範囲スライダーを設定するために残ります。 特定の理由で、私は私のものを書きました。 怠け者の適切な人、たとえばこの助言します。



スケーリングと移動



これに対する責任は、 viewBoxプロパティによって引き受けられます。 Microsoftのスタッフは、例を挙げて素晴らしい記事を書きました。 スクロールをインターセプトするために、 jQuery Mousewheelを使用しました。 確かに、これは最も簡単なタスクではありません。スケールを変更する場合、対応するズームファクターを使用して、初期位置に対する相対的なシフトを考慮する必要があるためです。



ほとんどすべて



私はモジュラーアーキテクチャを使用し(約12個のモジュールが出てきました)Snap.svgを手伝いました。 データは動的にロード、計算され、いくつかのことはプロミス を使用して行われたため(jqueryを使用したため、そこから取得しました) 、すべてがロードされている間に単純な進行状況バーを追加することさえできました。



喜びは、私が電話に行くことに決めたまで続きました...非常に賢いルミア1020では、サービスのロードに30分以上かかりました。 私は、domを操作する価格を絶対に忘れていました。 1秒間で1000を超える要素があります! また、モバイルデバイスでviewBoxを使用した操作は正常に機能しませんでした。



バグを修正します



クライアントからサーバーへ



自由意志による決定では、毎回カウントしないように、ロジックをサーバーに転送し、出力をキャッシュします。 これで、クライアントでSnap.svgをオプトアウトできます!



いえいえ、できません
svgの自己記述型グラデーションジェネレーターは重量がなく、エレガントでしたが、時には機能しませんでした。一部の要素にはグラデーションが適用されず、色のみが適用されました。 同時に、グラデーションは他の要素でもまったく問題なく機能しました。 「ブラックマジック」にうんざりして、ライブラリをシステムに戻しました。 それでも、私は「製品」ではなく、操作性の証拠を書いています。



スケーリングとモバイルでの移動機能に関する問題を解決する必要があります。 これをどのように処理するかを考えてください。



私はそうしました
ライブラリの検索から始め( hammer.jsで停止しました )、ドキュメントに精通しましたが、TRIZについては覚えていました。 ハインリッヒ・アルトシュラーは、理想的なオブジェクトを存在しないオブジェクトとして定義し、その機能が実行されます。



ウェアラブルデバイスは、既にスケーリングとシフトをサポートしています。 そう...はい、携帯電話とタブレットのviewBoxプロパティの操作を削減しました。



キャリーインナンバーは何をもたらしましたか?











結論



Mozilla Firefoxの問題



その過程で、「Mozilla Firefox」が再最適化されたことが判明しました。 他の人はすべてのグラフィックを定期的に表示しますが、「Mozilla」では、要素がユーザーに表示されない場合、要素のレンダリングをスキップできます。要素は、上部またはモニターの範囲外のdivによって閉じられます。 意識的な市民として、私は未確認のバグを追加しました。 可能な限りシンプルなテストケースを提供するという要求を満たすことができないため、すべてが少数の要素で正常に機能し、プロジェクトへのリンクが明らかに不十分です。



Mozillaの代表者がこれを読んだら、Guys、それはプラットフォーム(windows / mac)とバージョン(古いバージョンで観察された) 、チェスロボに関係なく曲がって動作します。



結論として



html5には多少の湿気がありましたが、それを使用する時が来ました。 昨日、フロントエンド開発者向けのメーリングリストに既に存在していた2つおきのサイトに「ファッショナブルな」効果を追加して、ユーザープロセッサを読み込む必要はありません。



しかし、今は便利な交通手段とインタラクティブな製品をあらゆるデバイスから利用できるようにするときです。



YandexがY. Metroをどこでも機能する新しい公式スキームに移行しない理由はわかりません。 モバイルデバイスのユーザーは、アプリケーションへのリンクを表示することを好みます。 店舗(アプリケーション)はソーシャルネットワークや大規模なサイトの顧客でいっぱいであり、私の意見では、これには何か問題があります。



UPD



各プロジェクトの作業には、理想がある程度期待されていますが、現実は冷静です。

ここでいくつかの点をとる必要があると考えました。

1.フィードバックと私の練習での最初の寄付に感謝します。 著者(特に私)にとって、これは本当に重要です。

2.既存の独立したフォームでは、プロジェクトは更新されません。

私は多くの間違いを犯しましたが、多くの改善を行うことができます。 それらの実装は、私が現在取り組んでいるものを放棄させ、メトロの継続的な開発はプロセスを無限にします。

3.実装に関する質問に回答するか、既存の情報があれば提供します。 コメントで質問してください。



All Articles