2015-11-16 3 views
0

Я создаю виджет, чтобы пользователи могли выбирать, какие количества рассчитывать против каких количеств (построение этого animated scatter plot на 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 в зависимости от обстоятельств на данных, когда это данные о дате. Вышеуказанный (и полный код here с widget 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 ("се", функция (d) { возвращение XScale (d [0]); X // Круг })

Так что я предполагаю, что xScale просто не работает, когда он был преобразован в шкалу времени. Что я делаю не так? Благодарим за любые исправления или рекомендации по устранению неполадок.

ответ

0

СЙ вычисляют, как NaN, поскольку данные, которые вы хранение созданы, как время, например штамп: "created":1447686953 и вы пишете функцию даты синтаксического анализа.

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

Это неверно, так как дата не в формате 20151223.

Таким образом, шкала, как вы предлагаете, рассчитывается неправильно.

Так что вам нужно сделать это для преобразования в дату:

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

Надеется, что это помогает!

Смежные вопросы