在
之前的文章《淺析javascript中Reflect內建物件(程式碼詳解)》中,給大家介紹了解了JS中Reflect內建物件。以下這篇文章跟大家介紹怎麼使用SVG實現畫走勢圖,有需要的朋友可以參考一下,希望對你們有所助。
先說說viewBox
是幹嘛的,就是比例縮放視圖的。用圖形表示
<svg width="300" height="200" style="border:1px solid #ddd"> <rect width="80" height="70" style="fill:#BDC9FF"></rect> </svg>
#加上viewBox="0,0,80,70"
<svg width="300" height="200" style="border:1px solid #ddd" viewBox="0,0,80,70"> <rect width="80" height="70" style="fill:#BDC9FF"></rect> </svg>
#當然還有可以配合preserveAspectRatio
屬性來使用,其取值有xMin,xMid,xMax,yMin,yMid,yMax,meet
(保持縱橫比縮放),slice
(保持縱橫比同時比例小的方向放大填滿viewport) 就是縮放的時候是起始和結束的依據點。如:preserveAspectRatio="xMidyMin meet"
就是以x,y
最小值為起點保持比例縮放
上面說的是試圖縮放,接下來要說的是:如何把大象放進冰箱,要幾個步驟?
首先說明我要做什麼:根據資料畫行情走勢圖。就是畫曲線,只畫曲線,所以不用canvas
,採用SVG
的polyline
來實現,相對較容易的多了。
最後要得到如下:
拿到的資料是這樣的:
BTC:[6612.775,6610.77,6585.72,6590.54,6587.38,6570.685,6565.215,6561.175,6557.735,6585.975,6601.18,6620,6596.5,6594.82,6594.5,6595.245,6599.005,6586.52,6582.12,6600.805,6614.515,6617.725,6614,6605.97,6631.715,6644.725,6596.355,6586.575,6594.175,6597.23,6592.285,6586.33,6579.57,6589.08,6576.42,6582.405,6609.89,6596.29,6586.145,6604.79,6594.375,6583.645,6580.32,6589.915,6594.555,6583.585,6599.6,6599.345,6572.185,6495.02,6476.98,6484.14,6509.8,6508.965,6479.21,6486.7,6463.08,6465.765,6467.155,6481.5,6528.43,6552.2,6566.19,6559.015,6522.25,6558.81,6573.42,6578.535,6593.305,6605.88,6611.695,6613.765,6611.765,6595.21,6601.5,6583.095,6575.155,6549.715,6590.31,6594.51,6617.565,6623.98,6637.5] ETH:[523.05,520.625,516.555,517.03,516.84,515.375,513.44,510.015,508.075,512.7,514.175,515.915,511.13,510.36,508.24,509.325,511.885,511.71,511.965,514.45,517.81,519.87,519.495,518.035,520.435,522.44,515.38,514.225,515.51,516.16,516.265,514.755,514.165,515.605,515.105,513.76,517.73,517.15,514.695,520.09,519.93,521.21,521.42,521.865,526.23,526.26,528.475,529.21,522.5,517.5,515.31,515.07,518.815,518.935,514.56,516.19,511.925,516.505,517.85,522.03,532.255,537.33,538.505,534.74,530.345,536.19,535.55,538.09,543.155,544.39,549.165,543.73,532.845,532.485,530.815,529.42,529.945,525.42,532.49,535.26,536.9,534.32,539.065] BCT:[5.7627,5.7536,5.7301,5.6882,5.6901,5.6759,5.6588,5.6724,5.7128,5.7375,5.7605,5.7543,5.7301,5.7298,5.7324,5.7121,5.7226,5.71,5.7025,5.7664,5.8049,5.8064,5.7976,5.7972,5.821,5.8486,5.7901,5.7303,5.7405,5.7783,5.7676,5.7358,5.721,5.7361,5.7149,5.7257,5.8168,5.8,5.7458,5.8002,5.7591,5.75,5.6963,5.6838,5.6716,5.6577,5.6724,5.6828,5.6638,5.6113,5.5479,5.5209,5.5457,5.5935,5.5685,5.5767,5.5376,5.5209,5.5,5.5,5.5751,5.659,5.6563,5.6715,5.6,5.6267,5.6437,5.6525,5.6678,5.6903,5.7346,5.7455,5.7435,5.7296,5.7485,5.665,5.6473,5.5814,5.635,5.6435,5.6616,5.6861,5.745]
沒錯,全都是y 座標數值。要利用這些數值在75*26
的(舞台或場景)視圖上畫走勢圖,也就是y
座標最大值為26
, x
座標最大值為75
。
那麼問題來了:
1)只有y
座標數組,沒有x
#座標,如何畫曲線呢?這個可以不用考慮,因為是畫滿畫布,x
,y
座標預設為0
,0
,所以x座標數組為0
,1,2,3....75,y 座標數組為0,1,2,3...26
在y
座標數組長度剛好為75
組的情況下,預設畫滿畫布,顯然所給的資料是大於75
群組的
2)y
座標數組長度大於畫布單位長度,x
座標如何取值?剛好為75
群組的時候,x
一次累加為1
,大於75
群組的時候x
座標累加值為x=75 / BTC.length
這時候x
,y
座標都知道了,那麼開畫吧,透過計算我們得到如下
<svg xmlns="http://www.w3.org/2000/svg" width="75" height="26"> <polyline points="0 6612.775 0.9036144578313253 6610.77 1.8072289156626506 6585.72 2.710843373493976 6590.54 3.6144578313253013 6587.38 4.518072289156627 6570.685 5.421686746987952 6565.215 6.325301204819277 6561.175 7.228915662650602 6557.735 8.132530120481928 6585.975 9.036144578313253 6601.18 9.93975903614458 6620 10.843373493975905 6596.5 11.746987951807231 6594.82 12.650602409638557 6594.5 13.554216867469883 6595.245 14.457831325301209 6599.005 15.361445783132535 6586.52 16.26506024096386 6582.12 17.168674698795183 6600.805 18.072289156626507 6614.515 18.97590361445783 6617.725 19.879518072289155 6614 20.78313253012048 6605.97 21.686746987951803 6631.715 22.590361445783127 6644.725 23.49397590361445 6596.355 24.397590361445776 6586.575 25.3012048192771 6594.175 26.204819277108424 6597.23 27.108433734939748 6592.285 28.012048192771072 6586.33 28.915662650602396 6579.57 29.81927710843372 6589.08 30.722891566265044 6576.42 31.62650602409637 6582.405 32.530120481927696 6609.89 33.43373493975902 6596.29 34.337349397590344 6586.145 35.24096385542167 6604.79 36.14457831325299 6594.375 37.04819277108432 6583.645 37.95180722891564 6580.32 38.855421686746965 6589.915 39.75903614457829 6594.555 40.66265060240961 6583.585 41.56626506024094 6599.6 42.46987951807226 6599.345 43.373493975903585 6572.185 44.27710843373491 6495.02 45.180722891566234 6476.98 46.08433734939756 6484.14 46.98795180722888 6509.8 47.891566265060206 6508.965 48.79518072289153 6479.21 49.698795180722854 6486.7 50.60240963855418 6463.08 51.5060240963855 6465.765 52.409638554216826 6467.155 53.31325301204815 6481.5 54.216867469879475 6528.43 55.1204819277108 6552.2 56.02409638554212 6566.19 56.92771084337345 6559.015 57.83132530120477 6522.25 58.734939759036095 6558.81 59.63855421686742 6573.42 60.54216867469874 6578.535 61.44578313253007 6593.305 62.34939759036139 6605.88 63.253012048192716 6611.695 64.15662650602404 6613.765 65.06024096385536 6611.765 65.96385542168669 6595.21 66.86746987951801 6601.5 67.77108433734934 6583.095 68.67469879518066 6575.155 69.57831325301198 6549.715 70.48192771084331 6590.31 71.38554216867463 6594.51 72.28915662650596 6617.565 73.19277108433728 6623.98 74.0963855421686 6637.5 " style="stroke: rgb(189, 201, 255); stroke-width: 1; fill: none;" ></polyline> </svg>
顯然所得到的結果不是我們期待的,一片空白,看不到數據。為啥?
3)y
座標太大,超出場景最大範圍,那麼要如何把大象放進冰箱呢?縮放y
的比例,然後向上垂直偏移座標,塞回冰箱裡,不讓象的耳朵漏出來。把整體放大10
倍,得到如下
那么这个数据是如何计算出来的呢?
// 数据 //x坐标数组 let s = 750 / BTC.length; //x起始坐标数组 let x = 0; //y坐标最小值 let min = BTC.reduce((x, y) => (x > y ? y : x)); //y坐标最大值 let max = BTC.reduce((x, y) => (x > y ? x : y)); //缩放比例 max-min为曲线幅度 let rodio = 260 / (max - min); // 此处的points 的值就是svg 都polyline 的points 属性的值 let points = ""; //统一处理y坐标,垂直向上偏移,也即是y坐标最高点归零 BTC.forEach((y) => { points += x + " " + (y - min) * rodio + " "; x += s; });
最后还原缩放比例,得到最终想要的样子。
那么这个和viewbox
有什么关联呢。
仔细观察,以上3
组数据BTC,ETH,BTC,发现这些数据都不在同一个波段,显然这个时候 ,如果用viewbox
来缩放视图不可取。当然非要用viewbox
来处理也未尝不可,只是感觉很愚蠢。手动改变数值来达到目的更快而已。这样不管大象有多大,我们都能顺利的塞到冰箱里。
以上是一文講解html中怎麼使用SVG實現畫走勢圖(分享程式碼)的詳細內容。更多資訊請關注PHP中文網其他相關文章!