Javascript Dynamic SVG с маркером - PullRequest
       1

Javascript Dynamic SVG с маркером

0 голосов
/ 23 января 2019

У меня есть некоторый javascript, который генерирует SVG-пути поверх некоторых данных, чтобы показать прогресс работы.У меня есть работающие линии, которые показывают связь между одним блоком к другому, но я не могу добавить стрелку маркера.

Я ссылаюсь на свою стрелку, используя следующую структуру:

<svg id="svg1" width="0" height="0">
  <defs>
      <marker id="Triangle" viewBox="0 0 10 10" refX="1" refY="5" 
              markerUnits="strokeWidth" markerWidth="4" markerHeight="3"
              orient="auto">
        <path d="M 0 0 L 10 5 L 0 10 z" fill="context-stroke"/>
      </marker>
    </defs>
    <path id="path1" class="path" marker-end="url(#Triangle)" fill="none" stroke-width="10"/>
</svg>

Проблема в том, что он не генерирует треугольник правильно и почти выглядит как его отрезанный квадрат?Треугольник должен быть в правом нижнем углу, поскольку путь соединяет верхний блок с нижним блоком.

enter image description here

JS Fiddle:

http://jsfiddle.net/qLhunt7k/

Есть идеи, почему это не похоже на треугольник, который я ожидаю?

1 Ответ

0 голосов
/ 24 января 2019

Ваша проблема связана с рядом факторов:

  1. Маркер находится внизу SVG, потому что ваша линия заканчивается в нижней части SVG.Смещение маркера (refX и refY) находится у основания стрелки.Таким образом, маркер нарисован так, что его основание (самая широкая часть) размещено там, где заканчивается линия.Таким образом, вы можете видеть только его верхний пиксель.

  2. Вы можете предотвратить отсечение и сделать маркер видимым, установив overflow: visible в SVG.Но вы также должны сделать то же самое с #svgContainer контейнером div.

    #svgContainer {
      ...
      overflow: visible;
    }
    
    #svgContainer svg {
      overflow: visible;
    }
    

    Альтернативой может быть не рисовать линию до самого дна.Так что вы оставляете место внизу для маркера, который будет нарисован.Например.измените генератор пути на что-то вроде:

    " V" + (endY-30));
    

    Я использовал 30 здесь, потому что он соответствует stroke-width из 0.7em.Я бы порекомендовал изменить ваш CSS для использования значения px для stroke-width.В противном случае изменение размера шрифта в будущем может привести к повторному нарушению маркеров.

    Если вы выберете этот подход, вам также потребуется разрешить горизонтальное пространство для маркера при расчете ширины SVG.Например:

    if (svg.getAttribute("width") < (endX + stroke * 3))
       svg.setAttribute("width", (endX + stroke * 3));
    
  3. Далее, правило path {} вызывает проблемы.Это общее определение для path переопределяет атрибут fill="context-stroke" в вашем определении маркера.Это приводит к тому, что маркер имеет большой штрих, который снова выходит за границы маркера и делает его похожим на прямоугольник.Исправление состоит в том, чтобы избавиться от стиля path {}.

    path {
    }
    
  4. Последней оставшейся проблемой является fill="context-stroke".Это новая вещь SVG2, которая пока не очень хорошо поддерживается.Например, он работает в Chrome, но пока не работает в Firefox.Итак, на данный момент, я рекомендую просто использовать простую заливку в определении маркера.

    <marker id="Triangle" viewBox="0 0 10 10" refX="0" refY="5" 
            markerUnits="strokeWidth" markerWidth="4" markerHeight="3"
            orient="auto">
      <path d="M 0 0 L 10 5 L 0 10 z" fill="#000"/>
    </marker>
    

Fiddle: http://jsfiddle.net/ptLc1gyx/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...