Как я могу масштабировать систему координат SVG без масштабирования шрифтов? - PullRequest
1 голос
/ 11 марта 2019

Я делаю визуализацию данных примерно так:

enter image description here

и было бы удобно использовать viewBox для масштабирования SVG, чтобы ширина графика масштабировалась до ширины диапазона данных.

Моя точка данных в этом примере - 12 549, и поэтому я хочу, чтобы диапазон работал от 0 до 14 000, и отрендерил это в viewBox шириной 14 000, используя rect шириной 12 549. Другими словами, использовать натуральные единицы для моих данных.

Но когда я это делаю, шрифт на моей оси также масштабируется, а шрифт 10px также масштабируется и становится настолько маленьким, что его не видно.

Так что мне нужен способ масштабирования блоков рисования без масштабирования блоков шрифта, но я не вижу способа сделать это.

Обновление

Вот код, о котором идет речь:

<svg width="960" height="50" class="bullet2" style="margin-top: 10px;">
  <svg viewBox="0 0 14000 25" preserveAspectRatio="none" width="100%" height="25" class="bars">
<rect x="0" y="0" width="14000" height="25" class="background"/>
<rect x="0" y="0" height="12.5" width="12549" class="item player"/>
<rect x="0" y="12.5" height="12.5" width="3750" class="item team-average"/>
<line x1="2000" x2="2000" y1="0" y2="25" class="marker" style="stroke-width: 29.1667px;"/>
  </svg>
  <g class="axis">
<g transform="translate(0, 25)" class="tick" style="opacity: 1;">
  <line y1="0" y2="5"/>
  <text text-anchor="middle" dy="1em" y="6">0</text>
</g>
<g transform="translate(140, 25)" class="tick" style="opacity: 1;">
  <line y1="0" y2="5"/>
  <text text-anchor="middle" dy="1em" y="6">2000</text>
</g>
<g transform="translate(280, 25)" class="tick" style="opacity: 1;">
  <line y1="0" y2="5"/>
  <text text-anchor="middle" dy="1em" y="6">4000</text>
</g>
<g transform="translate(420, 25)" class="tick" style="opacity: 1;">
  <line y1="0" y2="5"/>
  <text text-anchor="middle" dy="1em" y="6">6000</text>
</g>
<g transform="translate(560, 25)" class="tick" style="opacity: 1;">
  <line y1="0" y2="5"/>
  <text text-anchor="middle" dy="1em" y="6">8000</text>
</g>
<g transform="translate(700, 25)" class="tick" style="opacity: 1;">
  <line y1="0" y2="5"/>
  <text text-anchor="middle" dy="1em" y="6">10000</text>
</g>
<g transform="translate(840, 25)" class="tick" style="opacity: 1;">
  <line y1="0" y2="5"/>
  <text text-anchor="middle" dy="1em" y="6">12000</text>
</g>
<g transform="translate(980, 25)" class="tick" style="opacity: 1;">
  <line y1="0" y2="5"/>
  <text text-anchor="middle" dy="1em" y="6">14000</text>
</g>
  </g>
</svg>

Обратите внимание на viewBox на внутреннем элементе svg, масштабируя его, как описано. Я попробовал это с тем же масштабированием на внешнем элементе svg, который также включает ось, но когда я делаю это, изображение выглядит так:

enter image description here

Метки осей есть, но они также масштабированы, а шрифт 10px из 14000 пикселей масштабирования настолько мал, что вы его не видите.

Ответы [ 2 ]

1 голос
/ 12 марта 2019

Это моё решение вашего вопроса. Я рекомендую прочитать о SVGPoint и createSVGPoint. Я считаю особенно полезной информацию, найденную в этой книге: Использование SVG с CSS3 и HTML5: векторная графика для веб-дизайна

function init(){
  // a function called on resize
  // the function get the new font-size and set the new value of the "font-size"
  let fontSize = 25;
  let newSize = getValue(fontSize);
  // reset the font size
  theText.setAttributeNS(null,"font-size",newSize.x)
}


setTimeout(function() {
		init();
		addEventListener('resize', init, false);
}, 15);


// a function used to recalculate the font size on resize
function getValue(size){
var p = svg.createSVGPoint();
p.x = size;
p.y = 0;
p = p.matrixTransform(svg.getScreenCTM().inverse());
return p
}
svg{border:1px solid;}
<svg id="svg" viewBox="0 0 1000 100">
  <line x1="50" x2="950" y1="50" y2="50" stroke-width="20" stroke="skyblue" />
  
  <line x1="500" x2="500" y1="30" y2="70" stroke-width="1" stroke="#999" />
  <text id="theText"  dominant-baseline="middle" text-anchor="middle" x="500" y="85" font-size="16" >middle</text>
</svg>

Обновление

Можете ли вы объяснить, как работает это решение?

Есть комментарии в коде. Я также добавляю цитату из Использование SVG с CSS3 и HTML5: векторная графика для веб-дизайна :

Каждый элемент SVG, который может принимать преобразование [....], имеет метод getScreenCTM (). CMT обозначает совокупную матрицу преобразования . Экран CMT [....] определяет, как вы можете преобразовать точки в этой системе координат элемента обратно в исходную немасштабированную нетрансформированную систему координат окна документа. Он включает преобразования этого элемента и его предков, а также масштабирование viewBox.

Надеюсь, это полезно. Однако я думаю, что вам нужно прочитать всю главу 18 книги, чтобы полностью понять код.

0 голосов
/ 11 марта 2019

Пожалуйста, приведите Минимальный, Полный и Проверяемый пример .

Существует два подхода к вашей неопределенной / общей проблеме масштабирования:

  • 1) Поместите масштабируемый SVG внутрь контейнера SVG? штабелирования; и никогда не масштабируйте контейнер, в котором размещены шрифты, относительно процента child SVG в пределах.

  • 2) сообщает здесь , что шрифты можно масштабировать с использованием абсолютных px или относительных em единиц. Пожалуйста, смотрите здесь для правильной длины .

    Я не вижу возможности установки устройства rem, но если это так, попробуйте, если это работает?

(я часто работаю с SVG и CSS, поэтому в моих предложениях могут быть пробелы)

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