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

Interchange time and linear scaling depending on user selection

本文关键字:取决于 用户 选择 缩放 线性 时间 交换      更新时间:2023-09-26

我正在构建一个小部件,让用户决定要根据什么量绘制什么量(在bl.ocks上构建这个动画散点图。这对数字量很好,但我也有日期量,我希望用户也能以同样的方式根据非日期量绘制这些量。

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

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函数中修改这些全局变量,甚至改变缩放的性质,这也会反馈到轴变量中,所以我把它放在了点击函数中:

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。上面(完整的代码在这里,小部件在这里,有问题的日期类型存储在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("cx",函数(d){return xScale(d[0]);//圆圈的X})

因此,我假设xScale在转换为时间刻度时根本不起作用。我做错了什么?感谢您的任何更正或故障排除建议。

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);
    }

希望这能有所帮助!