2014-06-26 87 views
4

我對SVG完全陌生,所以請耐心等待。我閱讀了很多關於這個主題的文章,每個人都在指出像d3.js這樣的解決方案,在我看來,這是對於我所擁有的簡單任務來說很複雜的方法。笛卡爾座標系的簡單可縮放SVG圖形

我需要使用笛卡爾座標系製作一個圖,其中(0,0)位於左下角。它需要以百分比表示寬度,高度和數據,因此所有內容都與頁面成比例。

所以,這裏是我的代碼(使事情變得簡單,只有圖的一部分是存在的):

<style> 
.grid {stroke: white; stroke-width: 1; stroke-dasharray: 1 2} 
.label{font-family: courier new; fill: white; font-size: 14px} 
.data {stroke: white; stroke-width: 1} 
</style> 

<svg width="100%" height="100%"> 
<g class="x grid"> 
    <line x1="0%" x2="0%" y1="80%" y2="100%"></line> 
    <line x1="10%" x2="10%" y1="80%" y2="100%"></line> 
    <line x1="20%" x2="20%" y1="80%" y2="100%"></line> 
</g> 
<g class="y grid"> 
    <line x1="0%" x2="20%" y1="80%" y2="80%" ></line> 
    <line x1="0%" x2="20%" y1="90%" y2="90%" ></line> 
    <line x1="0%" x2="20%" y1="100%" y2="100%"></line> 
</g> 
<g class="x label"> 
    <text x="10%" y="100%"> 1 minute </text> 
    <text x="20%" y="100%"> 2 minutes</text> 
</g> 
<g class="y label"> 
    <text x="0%" y="80%"> 20% </text> 
    <text x="0%" y="90%"> 10% </text> 
</g> 
<g class="data"> 
    <line x1="0%" x2="10%" y1="85%" y2="92%" ></line> 
    <line x1="10%" x2="20%" y1="92%" y2="88%" ></line> 
</g> 
</svg> 

我想使用的數據polygonpath,這樣我就可以填寫下面的區域曲線,但它不喜歡百分比作爲值。有人建議使用viewbox將百分比轉換爲像素,然後使用像素,但這會弄亂我的網格。我還想在左下角有(0,0),這樣我的CGI就不需要對所有需要顯示的點進行數學運算。我嘗試了transform="translate(0,100) scale(1,-1)",但這不適用於百分比。我也嘗試transform="rotate(270)",但是當你減少窗口寬度,圖形高度降低...

那麼,有人可以啓動我在這裏,並幫助我建立一個流暢的,可調整大小的圖形,其起點在左下角曲線下方的彩色區域?

回答

8

您需要使用viewBox,因爲正如您發現的那樣,轉換組件不佔用百分比。使用viewBox,您仍然可以使用百分比來表示座標。但是,您需要選擇一個與最終圖形相似的縱橫比的視圖框。否則,您網頁上的物品可能會被擠壓或拉伸,這是不理想的。

<svg width="100%" height="100%" viewBox="0 0 500 500"> 
    <g id="cartesian" transform="translate(0,500) scale(1,-1)"> 
    <g class="data"> 
     <line x1="0%" y1="75%" x2="50%" y2="40%" ></line> 
     <line x1="50%" y1="40%" x2="100%" y2="60%"></line> 
    </g> 
    </g> 
</svg> 

不幸的翻轉座標系有副作用。如果翻轉的所有對象,包括文本,你可以看到,如果我們增加一些:

<svg width="100%" height="100%" viewBox="0 0 500 500"> 
    <g id="cartesian" transform="translate(0,500) scale(1,-1)"> 
    <g class="data"> 
     <line x1="0%" y1="75%" x2="50%" y2="40%" ></line> 
     <line x1="50%" y1="40%" x2="100%" y2="60%"></line> 
    </g> 
    <g class="y label"> 
     <text x="0%" y="50%"> 10% </text> 
     <text x="0%" y="90%"> 20% </text> 
    </g> 
    </g> 
</svg> 

Demo here

所以你需要通過再次翻轉文本備份正確的方式來解決這個問題。

<svg width="100%" height="100%" viewBox="0 0 500 500"> 
    <g id="cartesian" transform="translate(0,500) scale(1,-1)"> 
    <g class="data"> 
     <line x1="0%" y1="75%" x2="50%" y2="40%" ></line> 
     <line x1="50%" y1="40%" x2="100%" y2="60%"></line> 
    </g> 
    <g class="y label"> 
     <text x="0%" y="50%" font-size="16" 
      transform="translate(0,500) scale(1,-1)"> 10% </text> 
     <text x="0%" y="90%" font-size="16" 
      transform="translate(0,900) scale(1,-1)"> 20% </text> 
    </g> 
    </g> 
</svg> 

不幸的是,正如您所看到的,這種混亂使我們能夠用百分比座標乾淨地定位標籤。如果我們想在<text>元素上使用百分比座標,我們必須調整每個標籤的變換。

這個問題的最佳解決辦法可能是將您的所有標籤放在<defs>中,並使用<use>來引用它們。這樣我們可以用正確的方式將它們翻轉用百分比座標來定位它們。

<svg width="100%" height="100%" viewBox="0 0 500 500"> 
    <defs> 
    <text id="label1" font-size="16" transform="scale(1,-1)"> 10% </text> 
    <text id="label2" font-size="16" transform="scale(1,-1)"> 20% </text> 
    </defs> 
    <g id="cartesian" transform="translate(0,500) scale(1,-1)"> 
    <g class="data"> 
     <line x1="0%" y1="75%" x2="50%" y2="40%" ></line> 
     <line x1="50%" y1="40%" x2="100%" y2="60%"></line> 
    </g> 
    <g class="y label"> 
     <use xlink:href="#label1" x="0%" y="50%"/> 
     <use xlink:href="#label2" x="0%" y="90%"/> 
    </g> 
    </g> 
</svg> 

Demo here

+0

謝謝你,你的答案是非常有益的。我發現,如果網格和標籤是靜態的,它們不需要在笛卡爾的'g'範圍內,它使代碼更簡單和更清晰。但還有一件事我想解決,但我不知道如何解決。我不需要保持寬高比。我希望圖形填充頁面(或父'div')並且靈活。用'viewport'可以實現嗎? – Ulrik

+0

是的。使用''。 –

+0

幾乎在那裏(我試圖自己做,但似乎我需要最後的和平拼圖) - 有什麼方法可以讓標籤保持比例? – Ulrik