交换时间和线性缩放取决于用户选择

时间:2015-11-16 21:41:58

标签: javascript d3.js

我正在构建一个小部件,让用户根据bl.ocks来决定绘制数量的数量(在{b}上建立animated scatter plot。这对数字量很好,但我也有日期数量,而且我希望用户能够以相同的方式和非日期数量进行绘图。

原始线性缩放和轴的设置与全局函数类似:

var xScale = d3.scale.linear()  // xScale is width of graphic
    .domain([0, d3.max(dataset, function(d) {
        return d[0];  // input domain
    })])
    .range([padding, canvas_width - padding * 2]); // output range

var yScale = d3.scale.linear()  // yScale is height of graphic
    .domain([0, d3.max(dataset, function(d) {
        return d[1];  // input domain
    })])
    .range([canvas_height - padding, padding]);  // remember y starts on top going down so we flip

// Define X axis
var xAxis = d3.svg.axis()
    .scale(xScale)
    .orient("bottom")
    .ticks(5);

// Define Y axis
var yAxis = d3.svg.axis()
    .scale(yScale)
    .orient("left")
    .ticks(5);

我希望我可以在click函数中修改这些全局变量,甚至可以改变缩放的性质,并且这也会反馈到轴变量中,所以我把它放在click函数中:

if(types[xName]==3){
    console.log("resetting x scale to time type");
    xScale = d3.time.scale().range([padding, canvas_width - padding * 2]); // output range      
}
else{
    // Create scale functions
    xScale = d3.scale.linear()  // xScale is width of graphic
    .domain([0, d3.max(dataset, function(d) {
        return d[0];  // input domain
    })])
    .range([padding, canvas_width - padding * 2]); // output range


}

    xScale.domain([0, d3.max(dataset, function(d) {
        return d[0]; })]);
if(types[xName] == 1){
        xScale.domain([d3.max(dataset, function(d) {
    return d[0]; }), 0]);
}

if(types[yName]==3){
    console.log("resetting y scale to time type");
    yScale = d3.time.scale().range([canvas_height - padding, padding]);  // remember y starts on top going down so we flip
}
else {
    yScale = d3.scale.linear()  // yScale is height of graphic
    .domain([0, d3.max(dataset, function(d) {
        return d[1];  // input domain
    })])
    .range([canvas_height - padding, padding]);  // remember y starts on top going down so we flip
}

    yScale.domain([0, d3.max(dataset, function(d) {
        return d[1]; })]);
if(types[yName] == 1){
        yScale.domain([d3.max(dataset, function(d) {
    return d[1]; }), 0]);
}

我还在数据的日期数据时使用parseDate。以上(以及完整代码为herewidget here,有问题的日期类型存储在Created)中,当我在图表中时,所有点都位于图表的一条直线上选择日期类型,更糟糕的是仍会产生以下错误:

Error: Invalid value for <circle> attribute cx="naN" where I assume this is giving an error from the following code:

    svg.selectAll("circle")
        .data(dataset)  // Update with new data
        .transition()  // Transition from old to new

...             .attr(&#34; cx&#34;,function(d){                 return xScale(d [0]); //圈X.             })

所以我认为xScale在转换为时间尺度时根本不起作用。我究竟做错了什么?感谢您提供任何更正或故障排除建议。

1 个答案:

答案 0 :(得分:0)

cx计算为NaN,因为您正在存储创建的数据,作为时间戳示例:"created":1447686953并且您正在编写解析日期函数。

var parseDate = d3.time.format("%Y%m%d").parse;

这是不正确的,因为日期不是20151223格式。

因此,您建议的比例计算错误。

if(types[xName]== 3){
newNumber1 = parseDate(String(data[i][xName]));//this is wrong
}
var newNumber2 = data[i][yName]/divisor[types[yName]]//Math.floor(Math.random() * maxRange);  // New random integer
if(types[yName]== 3){
newNumber2 = parseDate(String(data[i][yName]));//this is wrong
}

所以你需要这样才能转换成日期:

    if(types[xName]== 3){
    newNumber1 = new Date(data[i][xName]*1000);
    }

    var newNumber2 = data[i][yName]/divisor[types[yName]]//Math.floor(Math.random() * maxRange);  // New random integer
    if(types[yName]== 3){
    newNumber2 = new Date(data[i][yName]*1000);
    }

希望这有帮助!