为什么在数据更新后调用d3.scale.linear.domain来收集规模?

时间:2014-12-23 21:32:13

标签: javascript d3.js

我使用d3js作为交互式图表,您可以在其中输入数据,图表值将会更新。该图表是具有{date,value}对的基本二维折线图。这是我每次有新数据更新时使用的代码,用于刷新图表:

function fetchLatest()
{
    // get data from server
    $.getJSON('/dataset',
    function(data)
    {
        var data_etl = [];
        data_etl = data.map(function(d){
            return { x: parseDate(d.date), y: d.value };
        });

        var xScale = d3.scale.ordinal().rangeRoundPoints([0, options.width - 97]);
        var yScale = d3.scale.linear();

        chart     
        .width($('.livechart').width())
        .height(300)
        .x(xScale.domain(data_etl.map(function(d){ return d.x; })));
        .y(yScale.domain([0, d3.max(data_etl, function(d) { return d.y;} )+1])); // PROBLEM LINE

        chart.replaceSeries(data_etl);

        chart.render();
    }); 
}

问题在于,虽然图表在第一次加载时看起来很完美,但在重新加载(新数据更新)时,y比例完全被压扁(因此线条变为平坦的水平线)。我做了一些调试,并将问题精确定位到这一行:

.y(yScale.domain([0, d3.max(data_etl, function(d) { return d.y;} )+1]));

如果在更新,我不会调用此行,那么图表会更新。但是,如果我将其调用,则会导致上述问题。有谁知道为什么会这样?

修改来自meetamit的每条记事,没有足够的信息。我也添加了图表对象代码:

function lineChart(insertionPoint) {
var _chart = {};

var tip = d3.tip()
    .attr('class', 'd3-tip')
    .offset([-10, 0])
    .html(function(d) {
        var tip_date = "<span style='color:#f78b20'>" + formatDate(d.x) + ": </span>";
        var tip_activity = d.y;

        return tip_date + tip_activity;
    });

var _width = 600, _height = 300,
        _margins = {top: 40, left: 40, right: 40, bottom: 40},
        _x, _y,
        _data = [],
        _colors = d3.scale.ordinal().range([
                '#33ccff', '#f78b20', '#99dc2a', '#57d4d3'
            ]),
        _svg,
        _bodyG,
        _line;

_chart.render = function () {
    if (!_svg) {
        _svg = d3.select(insertionPoint).append("svg") // <-2B
                .attr("height", _height)
                .attr("width", _width);

        renderAxes(_svg);

        defineBodyClip(_svg);
    }

    renderBody(_svg);

    _svg.call(tip);
};


function renderAxes(svg) {
    var axesG = svg.append("g")
            .attr("class", "axes");

    renderXAxis(axesG);

    renderYAxis(axesG);
}

function renderXAxis(axesG){
    // xAxis
    var xAxis = d3.svg.axis()
            //.scale(_x.range([0, quadrantWidth()]))
            .scale(_x)
            .orient("bottom")
            .tickFormat(d3.time.format("%m-%d"));        

    axesG.append("g")
            .attr("class", "x axis")
            .attr("transform", function () {
                return "translate(" + xStart() + "," + yStart() + ")";
            })
            .call(xAxis);
}

function renderYAxis(axesG){
    //yAxis
    var yAxis = d3.svg.axis()
            .scale(_y.range([quadrantHeight(), 0]))
            .orient("left");

    axesG.append("g")
            .attr("class", "y axis")
            .attr("transform", function () {
                return "translate(" + xStart() + "," + yEnd() + ")";
            })
            .call(yAxis);
}

function defineBodyClip(svg) {
    var padding = 5;

    svg.append("defs")
            .append("clipPath")
            .attr("id", "body-clip")
            .append("rect")
            .attr("x", 0 - padding)
            .attr("y", 0)
            .attr("width", quadrantWidth() + 2 * padding)
            .attr("height", quadrantHeight());
}

function renderBody(svg) {
    if (!_bodyG)
        _bodyG = svg.append("g")
                .attr("class", "body")
                .attr("transform", "translate(" 
                    + xStart() + "," 
                    + yEnd() + ")") // <-2E
                .attr("clip-path", "url(#body-clip)");        

    renderLines();

    renderDots();
}

function renderLines() {
    _line = d3.svg.line()
                    .x(function (d) { return _x(d.x); })
                    .y(function (d) { return _y(d.y); });

    _bodyG.selectAll("path.line")
                .data(_data)
            .enter() 
            .append("path")                
            .style("stroke", function (d, i) { 
                return _colors(i);
            })
            .attr("class", "line");

    _bodyG.selectAll("path.line")
            .data(_data)
            .transition()
            .attr("d", function (d) { return _line(d); });
}

function renderDots() {
    _data.forEach(function (list, i) {
        _bodyG.selectAll("circle._" + i)
                    .data(list)
                .enter()
                .append("circle")
                .attr("class", "dot _" + i)
                .on('mouseover', tip.show)
                .on('mouseout', tip.hide)
                .on('click', function(d, i){ 
                    showTotalActivities(d.x);
                });

        _bodyG.selectAll("circle._" + i)
                .data(list)                    
                .style("stroke", function (d) { 
                    return _colors(i); //<-4F
                })
                .transition() //<-4G
                .attr("cx", function (d) { 
                    return _x(d.x); })
                .attr("cy", function (d) { 
                    //console.log("dy: " + _y(d.y));
                    return _y(d.y); })
                .attr("r", 4.5);

    });
}

function xStart() {
    return _margins.left;
}

function yStart() {
    return _height - _margins.bottom;
}

function xEnd() {
    return _width - _margins.right;
}

function yEnd() {
    return _margins.top;
}

function quadrantWidth() {
    return _width - _margins.left - _margins.right;
}

function quadrantHeight() {
    return _height - _margins.top - _margins.bottom;
}

_chart.width = function (w) {
    if (!arguments.length) return _width;
    _width = w;
    return _chart;
};

_chart.height = function (h) {
    if (!arguments.length) return _height;
    _height = h;
    return _chart;
};

_chart.margins = function (m) {
    if (!arguments.length) return _margins;
    _margins = m;
    return _chart;
};

_chart.colors = function (c) {
    if (!arguments.length) return _colors;
    _colors = c;
    return _chart;
};

_chart.x = function (x) {
    if (!arguments.length) return _x;
    _x = x;
    return _chart;
};

_chart.y = function (y) {
    if (!arguments.length) return _y;
    _y = y;
    return _chart;
};

_chart.addSeries = function (series) {
    _data.push(series);
    return _chart;
};

 _chart.replaceSeries = function (series) {
    _data = [];
    _data.push(series);
    return _chart;
};

return _chart;
}

0 个答案:

没有答案