2017-09-26 7 views
0

제가 만드는 산점도는 0에서 5000 정도까지 올바른 Y 축을 가지지 만, 그려지는 노드는 값에 미치지 못합니다.산점도의 y 축척이 y 축의 y 축과 다르게 스케일됩니다. D3.js

문제는 (나는 생각합니다) y 규모의 도메인입니다. ext(), min 및 max 및 하드 코딩 값을 사용하여 시도했습니다. (이러한 시도가 있고 주석 처리되었습니다.) 나는 y 축척으로 먹이를주는 값을 디버깅했습니다. 그리고 그들은 괜찮을 것 같습니다, 그들은이 차트의 꼭대기에 도달해야합니다. 그러나 그들은 겨우 반쯤 올라옵니다. 내가 주변에 4600 picture of chart

있는 최대 Y 값 근처에도없는 3000,로 Y 규모 도메인의 최대 하드 코딩 경우

차트의 정상에 노드를 얻을 수있는 유일한 방법입니다

<!-- STACK OVERFLOW This code at the top is simple HTML/HTTP request stuff, you can 
scroll down till my other comments to start looking at the problem. 
I left this code here so people can run the chart on their browser.--> 

<meta charset="utf-8"> 
<title>Template Loading D3</title> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.12/d3.min.js"></script> 

<style media="screen"> 
    .axis path, 
    .axis line { 
     fill: none; 
     stroke: black; 
     shape-rendering: crispEdges; 
    } 
</style> 

</head> 
<body> 

<h1>Bitcoin BTC</h1> 

<script type="text/javascript"> 

var xhr = new XMLHttpRequest(); 

function makeRequest(){ 
    xhr.open("GET", "https://api.coindesk.com/v1/bpi/historical/close.json?start=2010-07-17&end=2017-09-11", true); 
    xhr.send(); 
    xhr.onreadystatechange = processRequest; 
} 

function processRequest(){ 
    console.log("testing, state: ", xhr.readyState) 
    if(xhr.readyState == 4 && xhr.status == 200){ 
     let response = JSON.parse(xhr.responseText); 
     makeChart(response); 
    } 
} 

// STACK OVERFLOW -- code above this can be ignored since it's just making HTTP request. 
// I'm leaving it here so people can serve this code on their own machine and 
// see it working in their browser. D3 code is below 

// When the HTTP request is finished, this function gets called to draw my chart, 
// this is where D3.js starts. 
function makeChart(response){ 
    var w = window.innerWidth - 100; 
    var h = window.innerHeight - 100; 
    var padding = 20; 
    var Lpadding = 45; 

// makeDatesAndValues is not part of my problem, this formats the dates 
// coming from HTTP request into something easier to feed into D3.js X Scale 
    var makeDatesAndValues = function(input){  
     let dates = []; 
     let values = []; 
     let returnData = []; 

     for(prop in input){ 
      values.push(input[prop]) 

      let counter = 0; 
      let year = []; 
      let month = []; 
      let day = []; 

      for(var j = 0; j < prop.length; j++){ 
       if(lastDate[j] !== "-" && counter == 0){ 
        year.push(prop[j]); 
       } else if(prop[j] == "-"){ 
        counter++; 
       } else if(prop[j] !== "-" && counter == 1){ 
        month.push(prop[j]) 
       } else if(prop[j] !== "-" && counter == 2){ 
        day.push(prop[j]) 
       } 
      } 
      dates.push([Number(year.join("")), Number(month.join("")), Number(day.join(""))]); 

      returnData.push(
       { 
        date: [Number(year.join("")), Number(month.join("")), Number(day.join(""))], 
        value: input[prop] 
       } 
      ) 
     } 
     return returnData; 
    } 

    var inputData = makeDatesAndValues(response.bpi); 

// HERE WE GO, this is where I think the problem is, drawing the actual chart. 
    var svg = d3.select("body") 
       .append("svg") 
       .attr("width", w) 
       .attr("height", h); 

// Here is the problem child, both "y" and the commented out "yScale" are attempts to 
// get the correct y-coordinates for values fed into the scale 
// Both of these will make a correct y Axis, but then screw up the y-coordinates of my data 
// getting fed in, as described on SO 
    var y = d3.scale.linear() 
        .domain([d3.min(inputData, function(d){ return d.value; }), d3.max(inputData, function(d){ return d.value; })]) 
        // .domain([d3.extent(d3.values(inputData, function(d){ return d.value}))]) 
        // .domain([0, 3000]) 
        .range([h - padding, padding]) 

    // var yScale = d3.scale.linear() 
    //     // .domain([0, 5000]) 
    //     .domain([d3.min(inputData, function(d){ return d.value; }), d3.max(inputData, function(d){ return d.value; })]) 
    //     // .domain([d3.extent(d3.values(inputData, function(d){ return d.value}))]) 
    //     .range([0, h]) 

// X scale works fine, no problems here 
    var x = d3.time.scale() 
         .domain([new Date(2010, 7, 18), new Date(2017, 7, 18)]) 
         .range([Lpadding, w]); 

// Both Axes seem to be working fine 
    var xAxis = d3.svg.axis() 
        .scale(x) 
        .orient("bottom") 
        .ticks(8) 

    var yAxis = d3.svg.axis() 
        .scale(y) 
        .orient("left") 
        // .tickSize(-w, 0, 0) 
        .ticks(8) 


    svg.selectAll("circle") 
        .data(inputData) 
        .enter() 
        .append("circle") 
        .attr("cx", function(d){ 
         let thisDate = x(new Date(d.date[0], d.date[1], d.date[2])) 
         return thisDate; 
        }) 
// And here is the other side of the problem. There are different attempts 
// to plot they y-coordinate of my values commented out. 
// None of these are working and I don't understand why it works correctly 
// for the Y Axis, but my plotted values come way short of where they should be. 
        .attr("cy", function(d, i){ 
         console.log("this is with yScale: ", y(d.value)) 
         console.log("Without: ", d.value) 
         // return y((d.value) - padding) 
         // return y(d.value); 
         // return y(d.value) - (h - padding) 
         return h - padding - y(d.value); 
        }) 
        .attr("r", function(d){ 
         return 1; 
        }) 
        .attr("fill", "red") 

    svg.append("g") 
     .attr("class", "x axis") 
     .attr("transform", "translate(" + 0 + ", " + (h - padding) + ")") 
     .call(xAxis); 

    svg.append("g") 
     .attr("class", "y axis") 
     .attr("transform", "translate(" + Lpadding + ", 0)") 
     .call(yAxis); 
} 

makeRequest(); 

</script> 

</body> 

답변

0

잘못된 코드가 포함 된 긴 코드를 게시 할 때 사람들의 감정을 고려해야 할 수도 있습니다.

당신의 문제는 SVG의 좌표계가 y를 가리키는 곳이 아니라는 것입니다. 다음은 약간 수정 한 것입니다.

세부 정보를 제공하지 않으므로 확인할 수 없습니다. 도움이되기를 바랍니다!

+0

도움을 주셔서 감사합니다, 당신의 제안은 내가 벌써 얻고있는 같은 고생 된 결과를 낳는다. 미안하지만, 이건 꽤 표준적인 D3.js 코드라고 생각했지만 지금 코멘트를 추가 할 것입니다. 나는 당신이 그것을 확인할 수 없다고 말하고, 내 코드를 복사하여 복사하고, 아무것도 변경하지 않고 정적으로 제공하고, 브라우저에서 바로 차트를 볼 수 있다는 것에 놀랐다. – iggirex

+0

원하는대로 코드를 변경했습니다. 일반 JavaScript 및 기본 SVG 트릭에 대해 많은 작업을해야합니다. [여기] (http://jsbin.com/natikab/edit?html,js,output)는 jsbin 코드이며 작동합니다. – 1Cr18Ni9

+0

고맙습니다. 코드가 흔들립니다! 예, 저는 JS 프레임 워크를 무시했습니다. 언어에서 더 잘되기를 원하기 때문입니다. 당신은 매우 진보적이며, 저에게 이것을 보여줄 시간을 가져 주셔서 감사합니다. 나는 지금처럼 고차원 함수를 체인화 할 수 있기 위해 공부하고있다. 너무 멋지다 !! 이러한 기본 JS 및 D3 트릭을위한 학습 자료에 대한 제안 사항은 무엇입니까? – iggirex