散点图中的y比例缩放y轴与y值D3.js不同

时间:2017-09-26 04:59:44

标签: javascript d3.js data-visualization

我制作的散点图有一个正确的y轴从0到5000左右,但正在绘制的节点远远超过它们的值。

问题(我认为)是y尺度的领域。我尝试过使用extent(),min和max以及硬编码值。(这些尝试都在那里并被注释掉)。我已经调整了输入y量表的值,它们似乎没问题,它们应该达到图表的顶部,但它们几乎没有上升一半。

将节点置于图表顶部的唯一方法是将y标度域的最大值硬编码为3000,这甚至不接近最大值y值4600左右。 picture of chart

<!-- 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>

1 个答案:

答案 0 :(得分:0)

我建议您在发布评论不佳的长代码时可能需要考虑人们的感受。

你的问题是你没有意识到y指向底部的SVG坐标系。以下是一点修改:

import jxl.*                                // import library
import jxl.write.*
def fr = new File(“D:\\data1.xls”)
Workbook wk = Workbook.getWorkbook(fr);
def s1 = wk.getSheet(0);
def r = s1.getRows();
for(def i=0;i<r;i++)
{
def c1 = s1.getCell(0, i) 
def c2 = s1.getCell(1, i)
testRunner.testCase.testSteps["Properties"].setPropertyValue  ("num1",c1.getContents())
testRunner.testCase.testSteps["Properties"].setPropertyValue("num2",c2.getContents())
} 

由于您不提供详细数据,我无法检查。希望它会有所帮助!