2014-09-04 37 views
2

我在一個陣列從0.00164737到0.0021966管理上的HTML畫布

有一個數據集用於對數陣列數據我所試圖做的就是形狀固定的對數刻度,然後將其標準化以準備在畫布上繪製。說歸到0,100-100,0,100這樣我就可以在像素工作

要簡單地規範(而不做日誌功能)0-100之間的這種可愛的作品在for循環中:

normalized[i] = ((close[i] - min)/dif) * 100; 

DIF是靠近陣列的最大值減去這分鐘toFixed(7)

Normalized

我不是數學家,但我認爲我與日誌部分'有點接近',儘管在規範化過程中我應用日誌功能時我只看到視覺差異。這顯然打亂了正常化,它也能產生無窮大或負無窮大,而且非常不必要的大量

Out of view

注意圖表現在不再管理​​以像素爲單位,因爲它不是坐在畫布上正確,所以看到我做了什麼我想補充150到所有Y點,使其視圖

Pushed into view

所以,當我這樣做,我破壞/通過應用對數函數量變到質變在同一條線上的東西(我知道這部分是錯的)

function logWithBase(n,b){return Math.log(n)/Math.log(b);} 

改變,像這樣的行:

normalized[i] = logWithBase((close[i] - min)/dif , 10) * 100; 

下面是數據的一小部分之前和之後我試圖使它對數:

前:

0: "0.00168927" 
1: "0.00168742" 
2: "0.0016818" 
3: "0.00168124" 
4: "0.00168067" 
5: "0.0016805" 
6: "0.00168657" 
7: "0.00168362" 
8: "0.00166886" 
9: "0.00165052" // < why does 0.00165 cause -Infinity 
10: "0.0016647" 
11: "0.00166251" 
12: "0.00166664" 
13: "0.00167196" 
14: "0.00167084" 
15: "0.00167667" 

同一套後:

0: 38.93017025063121 
1: 36.805636182304255 
2: 29.629674005179268 
3: 28.845120702345767 
4: 28.03173121401521 
5: 27.786162417624155 
6: 35.79352647194307 
7: 32.08579894397015 
8: 6.4429326997987175 
9: -Infinity    // < WOW!! 
10: -4.729377348896662 
11: -12.015082123716525 
12: 0.8395033133056131 
13: 13.225477668471285 
14: 10.8953699275865 
15: 21.850168886727374 

也許有相關線索這裏

如果我得到的最小值和最大值/ 2之差(我可能會得到這樣一個壞的標誌),並把它作爲我的基地(我之前做簡單的標準化)我看到圖表倒掛...

var logclose = []; 

var base = (Math.max.apply(this,close) - Math.min.apply(this,close))/2; 

for(var i = close.length - 1; i >= 0; i--){ 

    logclose[i] = logWithBase(close[i] , base); 

    } 

close=logclose; 

Upside down

結論;我認爲最後一個例子說基地應該與數組範圍有關,因爲它確實有效。

我該如何馴服對數不是可笑的大數,然後規範它適合畫布區域?

請不要推薦我使用一個庫(我喜歡香草JavaScript的地方都可以使用,另外,我也非常想抓住這proccess)

編輯,這裏是代碼:

var close=[data]; // for example data see this question (line: 19) as the full data will not fit here (over 10000 entries) 

//### 

var max=Math.max.apply(this,close); 
var min=Math.min.apply(this,close); 
var dif=(max-min).toFixed(7); 

var normalclose=[]; 
var logAttemptClose=[]; 

function logWithBase(n,b){return Math.log(n)/Math.log(b);} 

for(var i=close.length-1;i>=0;i--){ 

    normalclose[i]=((close[i]-min)/dif)*100; 

    logAttemptClose[i]=logWithBase((close[i] - min)/dif , 10) * 100; // <-- here bad code 
    } 

//drawing to canvas 
var top=100; 
var x=1000-100; 
var pen=[]; 

pen[0]=document.getElementById("chart"); 
pen[0]=pen[0].getContext("2d"); 
pen[0].clearRect(0,0,1000,300); 
pen[0].beginPath(); 
pen[0].moveTo(x,normalclose[normalclose.length-1]+top); 

for(var i=close.length-1;i>=0;i--){ 
    x=x-(2); 
    pen[0].lineTo(x,normalclose[i]+top); 
    } 

pen[0].strokeStyle='#000000'; 
pen[0].stroke(); 
+1

如果你要向下投票,請建設性/專業有關,並給予解釋 – 8DK 2014-09-04 13:37:57

+0

這很難幫你沒有完整的代碼。但是你應該檢查每一步,以驗證你是否有任何'undefined' /'NaN' /'null'值。 – 2014-09-04 13:47:40

+1

這個問題提供了大量的信息,顯示了一個誠實的努力,並被問及,我覺得它有點苛刻,downvote。 (+1) – axelduch 2014-09-13 19:56:21

回答

1

Got Ya !!

好吧,這不是最好的解決方案,但它的工作原理!如果任何人都可以做到這一點更好,請帖子..

加入這個2號線上面的代碼(在評論「###」是):

var Lmax=Math.max.apply(this,close); 
var Lmin=Math.min.apply(this,close); 
var Ldif=(Lmax-Lmin); 
var Logar=[]; 
var infinity=[]; 
for(var i=close.length-1;i>=0;i--){ 
    Logar[i]=Math.log((close[i]-Lmin)/Ldif); 
    if(Logar[i]===-Infinity){infinity.push(i);} 
    } 
close=Logar; 

現在我們必須在對數刻度數組但總是有永遠 - 無窮在那裏,所以我們刪除它。下一行寫...

for(var i=0;i<=infinity.length-1;i++){close.splice(infinity[i],1); 

然後我們就可以繼續在代碼轉移到簡單的正常化,我們有一個很好的新的數圖:

Hacked

0

你的問題是,你將線性空間中的數據標準化(通過減去最小值)並且然後轉換爲對數空間。

不可避免的一個值變爲零,因此log(0) == -Infinity

取而代之,先取非對數數據的對數,然後,然後確定繪圖的Y軸範圍。

http://jsfiddle.net/alnitak/r71s8cex/

+0

logAttemptClose [i] = logWithBase((close [i] - min)/ dif,10)* 100; 然後呢? logAttemptClose [i] = logWithBase(close [i]/dif,10)* 100; – 8DK 2014-09-15 13:25:18

+0

否 - 你需要移動整個「分鐘」/「最大」的東西,直到日誌操作結束。 – Alnitak 2014-09-15 13:43:16

+0

@ 8DK請參閱http://jsfiddle.net/alnitak/r71s8cex/ – Alnitak 2014-09-15 13:49:03