Когда два дня назад я искал вдохновение в электронных диаграммах, я видел много похожих примеров карт, позиционирования карт и т. д., но карты метро, похоже, не было, поэтому я потратил некоторое время на то, чтобы возиться с этой интерактивной демонстрационной картой метро. точки на линии метро были случайно загружены из Интернета. В этой статье описаны некоторые мои достижения (в конце концов, я все еще новичок) и реализация кода, я надеюсь, что это может помочь некоторым друзьям. Конечно, если у вас есть какие-либо мнения, вы можете сказать мне об этом напрямую. Только общаясь вместе, мы сможем добиться прогресса.
визуализации
http://www.hightopo.com/demo/subway/index.html
На карте слишком много содержимого. Если вы хотите отобразить все это, шрифты будут выглядеть немного мелкими, но это не имеет значения. При необходимости шрифты и нарисованный контент не будут искажаться. .Ведь они все нарисованы векторами~
Генерация интерфейсаБазовый элемент div создается с помощью компонента ht.graph.GraphView. Затем вы можете использовать хорошие методы, предоставляемые HT для Интернета, и просто вызвать кисть холста для рисования. Давайте сначала посмотрим, как создать базовый элемент div:
var dm = new ht.DataModel();//Контейнер данных var gv = new ht.graph.GraphView(dm);//Компонент топологии gv.addToDOM();//Добавляем компонент графа топологии в тело
Функция addToDOM объявлена следующим образом:
addToDOM = function(){ var self = this, view = self.getView(), style = view.style; document.body.appendChild(view); //Добавляем базовый элемент div компонента в тело style.left = '0';//Компонент по умолчанию позиционирован абсолютно, поэтому установите позицию style.right = '0'; style.bottom = '0'; window.addEventListener('resize', function () { self.iv(); }, false); //Событие изменения окна}
Теперь я могу рисовать на этом div~ Сначала я получаю точки на загруженной карте метро и помещаю их в subway.js. Этот js-файл представляет собой весь загруженный контент, я ничего не делал. Другие изменения в основном связаны с добавлением этих. указывает на массив в соответствии с строкой, например:
mark_Point13 = [];//Массив линий содержит координаты начальной и конечной точек линии и имя линии t_Point13 = [];//Массив станций содержит координаты пересадочной станции в линии и имя станции n_Point13 = [];//Масив малых станций содержит координаты малых станций на линии и названия малых станций mark_Point13.push({ name: 'Line 13', value: [113.4973,23.1095]}); mark_Point13.push({ name: 'Строка 13', значение: [113.4155,23.1080]}); t_Point13.push({ name: 'Ю Чжу', значение: [113.41548,23.10547 ]} ); n_Point13.push({имя: 'Юфэнвэй', значение: [113.41548,23.10004]});
Далее, чтобы нарисовать линии метро, я объявил массив lineNum для хранения номеров всех линий метро в js и массив цветов для хранения цветов всех линий метро. Индекс этих цветов такой же, как у метро. строка в строкеNum Нумерованные индексы соответствуют один к одному:
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'];
Затем пройдите по lineNum, передайте элементы и цвета из lineNum в функцию createLine и нарисуйте линии метро и сопоставление цветов в соответствии с этими двумя параметрами. В конце концов, метод именования в js-файле тоже обычный. Какая линия названа в честь Add. соответствующее число, поэтому нам нужно всего лишь объединить строку с этим числом, чтобы получить соответствующий массив в js:
let lineName = 'Line' + num; let line = window[lineName]; Определение createLine также очень простое, поэтому оно выглядит слишком много. Чтобы создать конвейер ht.Polyline, мы можем добавить определенные точки в эту переменную с помощью функции polyline.addPoint() и установить метод соединения точек через setSegments. function createLine(num, color) {//Нарисовать линию карты var Polyline = new ht.Polyline();//Многоугольный конвейер polyline.setTag(num);//Установить метку тега узла как единственную метку if(num = == '68') polyline.setToolTip('AP M');//Установить подсказку else if(num === '60') polyline.setToolTip('G F'); Polyline.setToolTip('Line' + num); if(color) { polyline.s({//s — аббревиатура setStyle, установите стиль shape.border.width: 0,4,//Установите ширину границы многоугольник 'shape.border.color': color,//Установите цвет границы многоугольника 'select.width': 0.2, //Установить ширину границы выбранного узла'select.color': color//Установить цвет границы выбранного узла}); } let lineName = 'Line' + num; let line = window[lineName]; 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 (Их две, но точки находятся в одном массиве) 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');//Установить линию На нижнем слое точка устанавливается на вершине верхнего слоя. dm.add(polyline);//Добавляем конвейер в контейнер данных для хранения, иначе конвейер находится в свободном состоянии и не будет отображаться на карте топологии return полилиния;}
В приведенном выше коде есть несколько ситуаций для добавления точек на линии метро. Это связано с тем, что Line68 имеет точку перехода при настройке линии в js, поэтому мы должны перейти к ней. Пространство ограничено. конкретное объявление массива Line68.
Здесь следует отметить следующее: если вы используете функцию addPoint и не устанавливаете сегменты, добавленные точки по умолчанию будут соединены прямыми линиями. Определение сегментов следующее:
1: moveTo, занимает 1 точку информации, представляющую начальную точку нового пути.
2: lineTo, занимает 1 информацию о точке, представляющую соединение от последней точки до этой точки.
3:quadaticCurveTo, занимает информацию о двух точках, первая точка используется как контрольная точка кривой, а вторая точка используется как конечная точка кривой.
4: bezierCurveTo, занимает информацию о 3 точках, первая и вторая точки используются как контрольные точки кривой, а третья точка используется как конечная точка кривой.
5: closePath, не занимает информацию о точках, представляет конец рисования этого пути и закрывается до начальной точки пути.
Итак, если мы хотим выполнить прыжковое поведение, просто установите для сегментов значение 1.
Наконец, эти точки на линии метро рисуются. Эта часть также разделена в subway.js. Имена начинаются с mark_Point, t_Point и n_Point. Я объяснил эти массивы в предыдущей части отображения js. прокрутите вверх, чтобы увидеть внешний вид.
Мы добавляем узлы ht.Node в эти точки. Когда узлы добавляются в контейнер данных dm, они будут отображаться на карте топологии. Конечно, предполагается, что контейнер данных, установленный компонентом карты топологии gv, является этим dm. . Из-за ограниченности места покажу только часть кода добавления точек на линии метро:
var tName = 't_Point' + num;var tP = window[tName];//Большая станция if(tP) {//На некоторых линиях нет пересадочных станций for(let i = 0; i < tP.length; i++) { let node = createNode(tP[i].name, tP[i].value, color[index]);//Добавить узел node.s({//Установить стиль стиля узла 'label.scale': 0.05,//Масштабирование текста, чтобы избежать ограничений браузера. Проблема с минимальным размером шрифта'label.font': ' жирный шрифт 12px arial, sans-serif'//Установим шрифт текста }); node.setSize(0.6, 0.6);//Установим размер узла. Поскольку смещение между каждой точкой в js слишком мало, мне пришлось установить узел меньше node.setImage('images/rotatingarrow.json');//Установить изображение узла node.a('alarmColor1', ' RGB(150, 150, 150)'); // атрибут attr, здесь вы можете установить что угодно. . com/guide/guide/core/vector/ht-vector-guide.html#ref_binding) node.a('alarmColor2', 'rgb(150, 150, 150)');//То же, что и выше node.a('tpNode', true);//Этот параметр атрибута используется только для различения передающих сайтов и небольших сайтов, которые будут использоваться позже}}
Добавлены все линии и станции метро. но! Возможно, вы не сможете увидеть нарисованные вами графики, потому что они слишком малы. На данный момент вы можете установить функцию fitContent в компоненте топологии GraphView. Кстати, мы также сделали все на графике топологии неподвижным:
gv.fitContent(false, 0.00001);//Адаптивный размер, параметр 1 определяет, следует ли анимировать, параметр 2 — это значение заполнения gv и границы gv.setMovableFunc(function(){ return false;//Установить узел на gv в значение быть неподвижным });
Теперь ваша карта маршрутов метро может быть отображена ~ Давайте посмотрим на взаимодействие.
взаимодействиеПервое — это событие движения мыши. Когда мышь скользит по определенной линии, линия становится толще, и вы можете увидеть номер этой линии, наведя курсор на некоторое время, когда мышь перемещается на сайт переноса или небольшой сайт. , значок, соответствующий сайту, станет больше. При изменении цвета шрифт также станет больше. При перемещении мыши значок вернется к исходному цвету, а шрифт станет меньше. Разница в том, что когда мышь перемещается к станции передачи, станция передачи будет вращаться.
Для события скольжения мыши я непосредственно выполняю событие mousemove на основе базового элемента div gv. Я передаю параметры события через функцию getDataAt, инкапсулированную ht, получаю соответствующий узел в событии, а затем могу управлять узлом. воля:
gv.getView().addEventListener('mousemove', function(e) { var data = gv.getDataAt(e);//Передаем точку логической координаты или параметр события интерактивного события и возвращаем примитив под текущей точкой if( name ) { originNode(name);//Всегда сохранять исходный размер узла} if (data instanceof ht.Polyline) {//Определить тип узла события dm.sm().ss(data);//Выбрать имя канала = '';clearInterval(interval); else if (data instanceof ht.Node) { if(data. getTag( ) !== name && data.a('tpNode')) {//Если это не тот же узел, а объект события mousemove имеет тип ht.Node, то установите интервал вращения узла = setInterval(function() { data.setRotation(data.getRotation() - Math.PI/16); //Поворот на основе собственного вращения}, 100 } if(data.a('npNode')) {/ /Если мышь перемещается на небольшой участок, остановить анимацию. name);////Настраиваемая функция узла масштабирования, относительно простая, я больше не придерживаюсь кода, вы можете перейти на http://hightopo.com/, чтобы просмотреть dm.sm().ss(data); //Устанавливаем имя выбранного узла = data.getTag();//В качестве переменной хранения предыдущего узла вы можете получить узел через это значение} else {//В любом другом случае ничего не выбрано и анимация включена сайт передачи очищен dm.sm( ).ss(null name =); ''; очиститьИнтервал (интервал }});
Когда указатель мыши наведен на линию метро, отображается информация о конкретной линии. Я делаю это, устанавливая всплывающую подсказку (обратите внимание: переключатель всплывающей подсказки gv должен быть включен):
gv.enableToolTip();//Включаем переключатель всплывающей подсказки if(num === '68') Polyline.setToolTip('AP M');//Установляем подсказку else if(num === '60') полилиния. setToolTip('G F'); полилиния.setToolTip('Line' + num);
Затем я использую форму формы в правом нижнем углу, чтобы щелкнуть определенную строку в форме, или дважды щелкнуть любой сайт или линию на карте топологии, и карта топологии адаптируется к соответствующей части, а двойной щелчок часть будет отображаться в центре карты топологии.
Кажется, я еще не объяснил часть декларации формы. . . То есть создать компонент формы формы с помощью нового класса ht.widget.FomePane, получить базовый div компонента формы с помощью form.getView(), поместить этот div в нижний правый угол тела, а затем добавить строку в форма формы через функцию addRow Элементы формы, вы можете добавить любое количество элементов в эту строку через addRow Второй параметр функции (массив) задает ширину добавляемого элемента формы, а через третий параметр задает высоту строки:
function createForm() {//Создаем форму формы в правом нижнем углу var form = new ht.widget.FormPane(); form.setWidth(200);//Установляем ширину формы form.setHeight(416);// Устанавливаем высоту формы let view = form.getView(); document.body.appendChild(view);//Добавляем форму в тело view.style.zIndex = 1000; view.style.bottom = '10px'; // Почти все компоненты ht устанавливают абсолютные пути view.style.right = '10px'; view.style.background = 'rgba(211, 211, 211, 0.8)'; forEach(function(nameString) { form.addRow([//Добавьте строку в форму{//Первая кнопка элемента формы в этой строке: {//Добавить значок кнопки в форму: 'images/Line'+nameString.value+'.json', //Установить фон значка кнопки: '',//Установить фоновый цвет кнопки: '',//Установить цвет границы кнопки, на которую можно нажимать: false//Сделаем кнопку неактивной} }, {//Вторая кнопка элемента формы: { label: nameString.name, labelFont: 'bold 14px arial, sans-serif', labelColor: '#fff', background: '', borderColor: '', onClicked: function() {//Событие обратного вызова при нажатии кнопки gv.sm().ss(dm.getDataByTag(nameString.value) );//Установим строку, соответствующую выбранной нажатой кнопке gv.fitData(gv.sm().ld(), true, 5);//Отображение выбранной линии метро в центре карты топологии} } } ], [0.1, 0.2], 23);//Второй параметр - задать ширину массива в первом параметре, меньше больше 1 — это соотношение, больше 1 — фактическая ширина. Третий параметр — высота строки});}.
Щелкните сайт, чтобы отобразить красную метку, дважды щелкните узел, чтобы адаптивно разместить его в центре карты топологии, и дважды щелкните пустое место, чтобы скрыть красную метку. Содержимое контролируется посредством мониторинга событий компонента топологии. gv. Это очень ясно и легко понять. Код выглядит следующим образом:
var node = createRedLight();//Создаем новый узел, отображаемый в стиле красного света gv.mi(function(e) {//Мониторинг событий в компоненте топологии в ht if(e.kind === 'clickData ' && (e.data.a('tpNode') || e.data.a('npNode'))) {//e.kind получает текущий тип события, e.data получает узел под текущим событием node.s('2d.visible', true);//Сделаем узел узла видимым node.setPosition(e. data.getPosition() .x, e.data.getPosition().y); //Устанавливаем координаты узла в положение узла под текущим событием} else if(e.kind === 'doubleClickData') {//Дважды щелкните узел gv.fitData(e.data, false, 10);//Адаптируйте узел под событием к центру карты топологии. Параметр 1 – адаптивный узел, параметр 2 – нужно ли анимировать. , а параметр 3 — это заполнение gv и границы } else if(e.kind === 'doubleClickBackground') {//Дважды щелкните пустое пространство node.s('2d.visible', false);//Установите узел узел должен быть невидимым Просмотр HT для Интернета Руководство по стилю (http://www.hightopo.com/guide/guide/core/theme/ht-theme-guide.html#ref_style) }});
Обратите внимание, что s (стиль) и a (attr) определяются следующим образом. s — это некоторые атрибуты стиля, предопределенные ht, а a — это атрибут, настроенный нашими пользователями. Результат обычно вызывается путем вызова строки. Эта строка соответствует can. быть константой или функцией, что очень гибко.
Наконец, небольшая часть готова. Когда сайт выбран, над ним отобразится красный значок дыхания, обозначающий выбранный в данный момент сайт.
Часть дыхания завершается с помощью функции setAnimation из ht. Перед использованием этой функции необходимо сначала включить переключатель анимации контейнера данных, а затем установить анимацию:
dm.enableAnimation();//Включаем функцию переключения анимации контейнера данных createRedLight() { var node = new ht.Node(); //SetImage('images/RedLight.json');//Устанавливаем изображение узел узла .setSize(1, 1);//Установим размер узла node.setLayer('firstTop');//Установим узел, который будет отображаться на верхнем слое gv node.s('2d.visible', false);//The узел невидим node.s( 'select.width', 0); //Граница, когда узел выбран, равна 0 и невидима node.s('2d.selectable', false);//Установите этот атрибут, узел не может быть выбран node.setAnimation({//Подробную информацию о настройке анимации см. в руководстве по HT для веб-анимации (http://www.hightopo.com/guide/guide). /plugin/animation/ht-animation-guide.html)expandWidth: { property: width,//Установите это свойство, и если accessType не установлен, ширина здесь и высота ниже устанавливаются и получаются по умолчанию. Все они получаются с помощью ранее установленного размера от: 0,5, //Значение атрибута в начале анимации до: 1, //Значение атрибута в конце анимации далее: свернутьWidth //Тип String, определяет, что выполнять после текущая анимация завершена. Следующая анимация может объединить несколько анимаций}, коллапсWidth: { свойство: ширина, от: 1, до: 0,5, следующая: экспандШидт }, экспандХайт: { свойство: высота, от: 0,5, до: 1, next: коллапсХигхт }, коллапсХигхт: { свойство: высота, от: 1, до: 0,5, следующий: экспандХигхт }, старт: [expandWidth, экспандХайт]//Массив, используется для указания одной или нескольких анимаций, которые нужно запустить} ) ; dm.add(узел); вернуть узел;}
Весь код окончен!
Подвести итогНа создание этой демонстрации у меня ушло два дня, и мне всегда было немного не хочется этого делать. Однако иногда мое мышление не удавалось перевернуть, и это занимало много времени, но в целом я многого добился. думать, что пока я прошел. Просто используйте getPoints().push для добавления точек в многоугольник. Обратившись за помощью к мастеру, я обнаружил, что этот метод не только обходит, но и вызывает различные проблемы. Например, перед получениемPoints. , у вас уже должны быть точки в многоугольнике. Это возможно, но во многих случаях инициализированные точки установить непросто, и код будет очень громоздким. Точки добавляются напрямую в переменную полигона через метод addPoint, а по умолчанию точки соединяются прямыми линиями. Нет необходимости устанавливать сегменты, какая прекрасная функция.
Кроме того, поскольку размер масштабирования ht по умолчанию равен 20, а интервал в моей демонстрации очень мал, отображение карты линий метро также очень маленькое при максимальном масштабировании, поэтому я изменил атрибут ZoomMax по умолчанию для ht в htconfig. , изменить Это значение должно быть перед всеми вызовами ht, поскольку значения, установленные в htconfig, не могут быть изменены позже.
Вышеупомянутая интерактивная карта линий метро на основе HTML5 Canvas, которую представляет вам редактор. Надеюсь, она будет вам полезна. Если у вас есть какие-либо вопросы, оставьте мне сообщение, и редактор ответит вам вовремя. Я также хотел бы поблагодарить всех за поддержку сайта боевых искусств VeVb!