Example #1
0
function isClose(actual, expected, precision) {
    if(isNumeric(actual) && isNumeric(expected)) {
        return Math.abs(actual - expected) < precision;
    }

    return actual === expected;
}
Example #2
0
function calcOneAxis(calcTrace, trace, axis, coord) {
    var opts = trace['error_' + coord] || {},
        isVisible = (opts.visible && ['linear', 'log'].indexOf(axis.type) !== -1),
        vals = [];

    if(!isVisible) return;

    var computeError = makeComputeError(opts);

    for(var i = 0; i < calcTrace.length; i++) {
        var calcPt = calcTrace[i],
            calcCoord = calcPt[coord];

        if(!isNumeric(axis.c2l(calcCoord))) continue;

        var errors = computeError(calcCoord, i);
        if(isNumeric(errors[0]) && isNumeric(errors[1])) {
            var shoe = calcPt[coord + 's'] = calcCoord - errors[0],
                hat = calcPt[coord + 'h'] = calcCoord + errors[1];
            vals.push(shoe, hat);
        }
    }

    Axes.expand(axis, vals, {padded: true});
}
Example #3
0
module.exports = function colorbar(gd, cd) {
    var trace = cd[0].trace,
        cbId = 'cb' + trace.uid,
        scl = getColorscale(trace.colorscale),
        zmin = trace.zmin,
        zmax = trace.zmax;

    if(!isNumeric(zmin)) zmin = Lib.aggNums(Math.min, null, trace.z);
    if(!isNumeric(zmax)) zmax = Lib.aggNums(Math.max, null, trace.z);

    gd._fullLayout._infolayer.selectAll('.' + cbId).remove();

    if(!trace.showscale){
        Plots.autoMargin(gd, cbId);
        return;
    }

    var cb = cd[0].t.cb = drawColorbar(gd, cbId);
    cb.fillcolor(d3.scale.linear()
            .domain(scl.map(function(v){ return zmin + v[0]*(zmax-zmin); }))
            .range(scl.map(function(v){ return v[1]; })))
        .filllevels({start: zmin, end: zmax, size: (zmax-zmin)/254})
        .options(trace.colorbar)();

    Lib.markTime('done colorbar');
};
Example #4
0
module.exports = function colorbar(gd, cd) {
    var trace = cd[0].trace,
        marker = trace.marker,
        cbId = 'cb' + trace.uid;

    gd._fullLayout._infolayer.selectAll('.' + cbId).remove();

    // TODO make Colorbar.draw support multiple colorbar per trace

    if((marker === undefined) || !marker.showscale) {
        Plots.autoMargin(gd, cbId);
        return;
    }

    var vals = marker.color,
        cmin = marker.cmin,
        cmax = marker.cmax;

    if(!isNumeric(cmin)) cmin = Lib.aggNums(Math.min, null, vals);
    if(!isNumeric(cmax)) cmax = Lib.aggNums(Math.max, null, vals);

    var cb = cd[0].t.cb = drawColorbar(gd, cbId);
    var sclFunc = Colorscale.makeColorScaleFunc(
        Colorscale.extractScale(
            marker.colorscale,
            cmin,
            cmax
        ),
        { noNumericCheck: true }
    );

    cb.fillcolor(sclFunc)
        .filllevels({start: cmin, end: cmax, size: (cmax - cmin) / 254})
        .options(marker.colorbar)();
};
Example #5
0
        bars.each(function(di) {
            var bar = d3.select(this);

            var rp0 = di.rp0 = radialAxis.c2p(di.s0);
            var rp1 = di.rp1 = radialAxis.c2p(di.s1);
            var thetag0 = di.thetag0 = angularAxis.c2g(di.p0);
            var thetag1 = di.thetag1 = angularAxis.c2g(di.p1);

            var dPath;

            if(!isNumeric(rp0) || !isNumeric(rp1) ||
                !isNumeric(thetag0) || !isNumeric(thetag1) ||
                rp0 === rp1 || thetag0 === thetag1
            ) {
                // do not remove blank bars, to keep data-to-node
                // mapping intact during radial drag, that we
                // can skip calling _module.style during interactions
                dPath = 'M0,0Z';
            } else {
                // this 'center' pt is used for selections and hover labels
                var rg1 = radialAxis.c2g(di.s1);
                var thetagMid = (thetag0 + thetag1) / 2;
                di.ct = [
                    xa.c2p(rg1 * Math.cos(thetagMid)),
                    ya.c2p(rg1 * Math.sin(thetagMid))
                ];

                dPath = pathFn(rp0, rp1, thetag0, thetag1);
            }

            Lib.ensureSingle(bar, 'path').attr('d', dPath);
        });
Example #6
0
module.exports = function hasColorscale(trace, containerStr) {
    var container = containerStr ?
            Lib.nestedProperty(trace, containerStr).get() || {} :
            trace,
        color = container.color,
        isArrayWithOneNumber = false;

    if(Array.isArray(color)) {
        for(var i = 0; i < color.length; i++) {
            if(isNumeric(color[i])) {
                isArrayWithOneNumber = true;
                break;
            }
        }
    }

    return (
        Lib.isPlainObject(container) && (
            isArrayWithOneNumber ||
            container.showscale === true ||
            (isNumeric(container.cmin) && isNumeric(container.cmax)) ||
            isValidScale(container.colorscale) ||
            Lib.isPlainObject(container.colorbar)
        )
    );
};
Example #7
0
drawing.tryColorscale = function(cont, contIn, prefix) {
    var colorArray = Plotly.Lib.nestedProperty(cont, prefix + 'color').get(),
        scl = Plotly.Lib.nestedProperty(cont, prefix + 'colorscale').get(),
        auto = Plotly.Lib.nestedProperty(cont, prefix + 'cauto').get(),
        minProp = Plotly.Lib.nestedProperty(cont, prefix + 'cmin'),
        maxProp = Plotly.Lib.nestedProperty(cont, prefix + 'cmax'),
        min = minProp.get(),
        max = maxProp.get();

    // TODO handle this in Colorscale.calc
    if(scl && Array.isArray(colorArray)) {
        if(auto || !isNumeric(min) || !isNumeric(max)) {
            min = Infinity;
            max = -Infinity;
            colorArray.forEach(function(color) {
                if(isNumeric(color)) {
                    if(min > color) min = +color;
                    if(max < color) max = +color;
                }
            });
            if(min > max) {
                min = 0;
                max = 1;
            }
            minProp.set(min);
            maxProp.set(max);
            Plotly.Lib.nestedProperty(contIn, prefix + 'cmin').set(min);
            Plotly.Lib.nestedProperty(contIn, prefix + 'cmax').set(max);
        }
        return Plotly.Colorscale.makeScaleFunction(scl, min, max);
    }
    else return Plotly.Lib.identity;
};
Example #8
0
// compute the coordinates of the error-bar objects
function errorCoords(d, xa, ya) {
    var out = {
        x: xa.c2p(d.x),
        y: ya.c2p(d.y)
    };

    // calculate the error bar size and hat and shoe locations
    if(d.yh !== undefined) {
        out.yh = ya.c2p(d.yh);
        out.ys = ya.c2p(d.ys);

        // if the shoes go off-scale (ie log scale, error bars past zero)
        // clip the bar and hide the shoes
        if(!isNumeric(out.ys)) {
            out.noYS = true;
            out.ys = ya.c2p(d.ys, true);
        }
    }

    if(d.xh !== undefined) {
        out.xh = xa.c2p(d.xh);
        out.xs = xa.c2p(d.xs);

        if(!isNumeric(out.xs)) {
            out.noXS = true;
            out.xs = xa.c2p(d.xs, true);
        }
    }

    return out;
}
Example #9
0
module.exports = function colorbar(gd, cd) {
    var trace = cd[0].trace,
        marker = trace.marker,
        cbId = 'cb' + trace.uid;

    gd._fullLayout._infolayer.selectAll('.' + cbId).remove();

    // TODO unify Scatter.colorbar and Heatmap.colorbar
    // TODO make Plotly[module].colorbar support multiple colorbar per trace

    if((marker === undefined) || !marker.showscale) {
        Plots.autoMargin(gd, cbId);
        return;
    }

    var scl = getColorscale(marker.colorscale),
        vals = marker.color,
        cmin = marker.cmin,
        cmax = marker.cmax;

    if(!isNumeric(cmin)) cmin = Lib.aggNums(Math.min, null, vals);
    if(!isNumeric(cmax)) cmax = Lib.aggNums(Math.max, null, vals);

    var cb = cd[0].t.cb = drawColorbar(gd, cbId);

    cb.fillcolor(d3.scale.linear()
            .domain(scl.map(function(v) { return cmin + v[0] * (cmax - cmin); }))
            .range(scl.map(function(v) { return v[1]; })))
        .filllevels({start: cmin, end: cmax, size: (cmax - cmin) / 254})
        .options(marker.colorbar)();

    Lib.markTime('done colorbar');
};
Example #10
0
module.exports = function colorbar(gd, cd) {
    var trace = cd[0].trace,
        cbId = 'cb' + trace.uid,
        cmin = trace.cmin,
        cmax = trace.cmax,
        vals = trace.surfacecolor || trace.z;

    if(!isNumeric(cmin)) cmin = Lib.aggNums(Math.min, null, vals);
    if(!isNumeric(cmax)) cmax = Lib.aggNums(Math.max, null, vals);

    gd._fullLayout._infolayer.selectAll('.' + cbId).remove();

    if(!trace.showscale) {
        Plots.autoMargin(gd, cbId);
        return;
    }

    var cb = cd[0].t.cb = drawColorbar(gd, cbId);
    var sclFunc = Colorscale.makeColorScaleFunc(
        Colorscale.extractScale(
            trace.colorscale,
            cmin,
            cmax
        ),
        { noNumericCheck: true }
    );

    cb.fillcolor(sclFunc)
        .filllevels({start: cmin, end: cmax, size: (cmax - cmin) / 254})
        .options(trace.colorbar)();
};
Example #11
0
 Object.keys(pm).forEach(function(k2) {
     if(isNumeric(pl) && pm[k2].r) {
         var fr = pm[k2].r.val,
             pr = pm[k2].r.size;
         if(fr > fl) {
             var newl = (pl * fr +
                     (pr - fullLayout.width) * fl) / (fr - fl),
                 newr = (pr * (1 - fl) +
                     (pl - fullLayout.width) * (1 - fr)) / (fr - fl);
             if(newl >= 0 && newr >= 0 && newl + newr > ml + mr) {
                 ml = newl;
                 mr = newr;
             }
         }
     }
     if(isNumeric(pb) && pm[k2].t) {
         var ft = pm[k2].t.val,
             pt = pm[k2].t.size;
         if(ft > fb) {
             var newb = (pb * ft +
                     (pt - fullLayout.height) * fb) / (ft - fb),
                 newt = (pt * (1 - fb) +
                     (pb - fullLayout.height) * (1 - ft)) / (ft - fb);
             if(newb >= 0 && newt >= 0 && newb + newt > mb + mt) {
                 mb = newb;
                 mt = newt;
             }
         }
     }
 });
Example #12
0
 ax.isValidRange = function(range) {
     return (
         Array.isArray(range) &&
         range.length === 2 &&
         isNumeric(ax.r2l(range[0])) &&
         isNumeric(ax.r2l(range[1]))
     );
 };
Example #13
0
    ax.setScale = function() {
        var gs = ax._gd._fullLayout._size,
            i;

        // TODO cleaner way to handle this case
        if(!ax._categories) ax._categories = [];

        // make sure we have a domain (pull it in from the axis
        // this one is overlaying if necessary)
        if(ax.overlaying) {
            var ax2 = axisIds.getFromId(ax._gd, ax.overlaying);
            ax.domain = ax2.domain;
        }

        // make sure we have a range (linearized data values)
        // and that it stays away from the limits of javascript numbers
        if(!ax.range || ax.range.length!==2 || ax.range[0]===ax.range[1]) {
            ax.range = [-1,1];
        }
        for(i=0; i<2; i++) {
            if(!isNumeric(ax.range[i])) {
                ax.range[i] = isNumeric(ax.range[1-i]) ?
                    (ax.range[1-i] * (i ? 10 : 0.1)) :
                    (i ? 1 : -1);
            }

            if(ax.range[i]<-(Number.MAX_VALUE/2)) {
                ax.range[i] = -(Number.MAX_VALUE/2);
            }
            else if(ax.range[i]>Number.MAX_VALUE/2) {
                ax.range[i] = Number.MAX_VALUE/2;
            }

        }

        if(ax._id.charAt(0)==='y') {
            ax._offset = gs.t+(1-ax.domain[1])*gs.h;
            ax._length = gs.h*(ax.domain[1]-ax.domain[0]);
            ax._m = ax._length/(ax.range[0]-ax.range[1]);
            ax._b = -ax._m*ax.range[1];
        }
        else {
            ax._offset = gs.l+ax.domain[0]*gs.w;
            ax._length = gs.w*(ax.domain[1]-ax.domain[0]);
            ax._m = ax._length/(ax.range[1]-ax.range[0]);
            ax._b = -ax._m*ax.range[0];
        }

        if(!isFinite(ax._m) || !isFinite(ax._b)) {
            Lib.notifier(
                'Something went wrong with axis scaling',
                'long');
            ax._gd._replotting = false;
            throw new Error('axis scaling');
        }
    };
Example #14
0
 s.each(function(d){
     // put xp and yp into d if pixel scaling is already done
     var x = d.xp || xa.c2p(d.x),
         y = d.yp || ya.c2p(d.y),
         p = d3.select(this);
     if(isNumeric(x) && isNumeric(y)) {
         // for multiline text this works better
         if(this.nodeName==='text') p.attr('x',x).attr('y',y);
         else p.attr('transform', 'translate('+x+','+y+')');
     }
     else p.remove();
 });
Example #15
0
module.exports = function cleanBins(trace, ax, binDirection) {
    var axType = ax.type,
        binAttr = binDirection + 'bins',
        bins = trace[binAttr];

    if(!bins) bins = trace[binAttr] = {};

    var cleanBound = (axType === 'date') ?
        function(v) { return (v || v === 0) ? cleanDate(v, BADNUM, bins.calendar) : null; } :
        function(v) { return isNumeric(v) ? Number(v) : null; };

    bins.start = cleanBound(bins.start);
    bins.end = cleanBound(bins.end);

    // logic for bin size is very similar to dtick (cartesian/tick_value_defaults)
    // but without the extra string options for log axes
    // ie the only strings we accept are M<n> for months
    var sizeDflt = (axType === 'date') ? ONEDAY : 1,
        binSize = bins.size;

    if(isNumeric(binSize)) {
        bins.size = (binSize > 0) ? Number(binSize) : sizeDflt;
    }
    else if(typeof binSize !== 'string') {
        bins.size = sizeDflt;
    }
    else {
        // date special case: "M<n>" gives bins every (integer) n months
        var prefix = binSize.charAt(0),
            sizeNum = binSize.substr(1);

        sizeNum = isNumeric(sizeNum) ? Number(sizeNum) : 0;
        if((sizeNum <= 0) || !(
                axType === 'date' && prefix === 'M' && sizeNum === Math.round(sizeNum)
            )) {
            bins.size = sizeDflt;
        }
    }

    var autoBinAttr = 'autobin' + binDirection;

    if(typeof trace[autoBinAttr] !== 'boolean') {
        trace[autoBinAttr] = !(
            (bins.start || bins.start === 0) &&
            (bins.end || bins.end === 0)
        );
    }

    if(!trace[autoBinAttr]) delete trace['nbins' + binDirection];
};
Example #16
0
module.exports = function convertCoords(gd, ax, newType, doExtra) {
    ax = ax || {};

    var toLog = (newType === 'log') && (ax.type === 'linear');
    var fromLog = (newType === 'linear') && (ax.type === 'log');

    if(!(toLog || fromLog)) return;

    var images = gd._fullLayout.images;
    var axLetter = ax._id.charAt(0);
    var image;
    var attrPrefix;

    for(var i = 0; i < images.length; i++) {
        image = images[i];
        attrPrefix = 'images[' + i + '].';

        if(image[axLetter + 'ref'] === ax._id) {
            var currentPos = image[axLetter];
            var currentSize = image['size' + axLetter];
            var newPos = null;
            var newSize = null;

            if(toLog) {
                newPos = toLogRange(currentPos, ax.range);

                // this is the inverse of the conversion we do in fromLog below
                // so that the conversion is reversible (notice the fromLog conversion
                // is like sinh, and this one looks like arcsinh)
                var dx = currentSize / Math.pow(10, newPos) / 2;
                newSize = 2 * Math.log(dx + Math.sqrt(1 + dx * dx)) / Math.LN10;
            }
            else {
                newPos = Math.pow(10, currentPos);
                newSize = newPos * (Math.pow(10, currentSize / 2) - Math.pow(10, -currentSize / 2));
            }

            // if conversion failed, delete the value so it can get a default later on
            if(!isNumeric(newPos)) {
                newPos = null;
                newSize = null;
            }
            else if(!isNumeric(newSize)) newSize = null;

            doExtra(attrPrefix + axLetter, newPos);
            doExtra(attrPrefix + 'size' + axLetter, newSize);
        }
    }
};
Example #17
0
drawing.translatePoint = function(d, sel, xa, ya) {
    // put xp and yp into d if pixel scaling is already done
    var x = d.xp || xa.c2p(d.x),
        y = d.yp || ya.c2p(d.y);

    if(isNumeric(x) && isNumeric(y) && sel.node()) {
        // for multiline text this works better
        if(sel.node().nodeName === 'text') {
            sel.attr('x', x).attr('y', y);
        } else {
            sel.attr('transform', 'translate(' + x + ',' + y + ')');
        }
    }
    else sel.remove();
};
Example #18
0
 max: function(n, i, size, counterData) {
     var v = counterData[i];
     if(isNumeric(v)) {
         v = Number(v);
         if(!isNumeric(size[n])) {
             size[n] = v;
             return v;
         }
         else if(size[n] < v) {
             size[n] = v;
             return v - size[n];
         }
     }
     return 0;
 }
 min: function(n, i, size, counterData) {
     var v = counterData[i];
     if(isNumeric(v)) {
         v = Number(v);
         if(!isNumeric(size[n])) {
             size[n] = v;
             return v;
         }
         else if(size[n] > v) {
             var delta = v - size[n];
             size[n] = v;
             return delta;
         }
     }
     return 0;
 },
Example #20
0
function numericSize(size) {
    if(isNumeric(size)) return size;
    if(typeof size === 'string' && size.charAt(0) === 'M') {
        return oneMonth * +(size.substr(1));
    }
    return Infinity;
}
Example #21
0
function validateColor(colorIn) {
    if(isNumeric(colorIn)) return colorDfltRgba;

    var colorOut = rgba(colorIn);

    return colorOut.length ? colorOut : colorDfltRgba;
}
Example #22
0
 function getCategoryPosition(v) {
     // d2l/d2c variant that that won't add categories but will also
     // allow numbers to be mapped to the linearized axis positions
     var index = getCategoryIndex(v);
     if(index !== undefined) return index;
     if(isNumeric(v)) return +v;
 }
Example #23
0
function isValidZ(z) {
    var allRowsAreArrays = true,
        oneRowIsFilled = false,
        hasOneNumber = false,
        zi;

    /*
     * Without this step:
     *
     * hasOneNumber = false breaks contour but not heatmap
     * allRowsAreArrays = false breaks contour but not heatmap
     * oneRowIsFilled = false breaks both
     */

    for(var i = 0; i < z.length; i++) {
        zi = z[i];
        if(!Array.isArray(zi)) {
            allRowsAreArrays = false;
            break;
        }
        if(zi.length > 0) oneRowIsFilled = true;
        for(var j = 0; j < zi.length; j++) {
            if(isNumeric(zi[j])) {
                hasOneNumber = true;
                break;
            }
        }
    }

    return (allRowsAreArrays && oneRowIsFilled && hasOneNumber);
}
Example #24
0
exports.findBin = function(val, bins, linelow) {
    if(isNumeric(bins.start)) {
        return linelow ?
            Math.ceil((val - bins.start) / bins.size) - 1 :
            Math.floor((val - bins.start) / bins.size);
    }
    else {
        var n1 = 0,
            n2 = bins.length,
            c = 0,
            n,
            test;
        if(bins[bins.length - 1] >= bins[0]) {
            test = linelow ? lessThan : lessOrEqual;
        } else {
            test = linelow ? greaterOrEqual : greaterThan;
        }
        // c is just to avoid infinite loops if there's an error
        while(n1 < n2 && c++ < 100){
            n = Math.floor((n1 + n2) / 2);
            if(test(bins[n], val)) n1 = n + 1;
            else n2 = n;
        }
        if(c > 90) console.log('Long binary search...');
        return n1 - 1;
    }
};
Example #25
0
function cleanOne(val) {
    if(isNumeric(val) || typeof val !== 'string') return val;

    var valTrim = val.trim();
    if(valTrim.substr(0, 3) !== 'rgb') return val;

    var match = valTrim.match(/^rgba?\s*\(([^()]*)\)$/);
    if(!match) return val;

    var parts = match[1].trim().split(/\s*[\s,]\s*/),
        rgba = valTrim.charAt(3) === 'a' && parts.length === 4;
    if(!rgba && parts.length !== 3) return val;

    for(var i = 0; i < parts.length; i++) {
        if(!parts[i].length) return val;
        parts[i] = Number(parts[i]);

        // all parts must be non-negative numbers
        if(!(parts[i] >= 0)) return val;
        // alpha>1 gets clipped to 1
        if(i === 3) {
            if(parts[i] > 1) parts[i] = 1;
        }
        // r, g, b must be < 1 (ie 1 itself is not allowed)
        else if(parts[i] >= 1) return val;
    }

    var rgbStr = Math.round(parts[0] * 255) + ', ' +
        Math.round(parts[1] * 255) + ', ' +
        Math.round(parts[2] * 255);

    if(rgba) return 'rgba(' + rgbStr + ', ' + parts[3] + ')';
    return 'rgb(' + rgbStr + ')';
}
Example #26
0
shapes.draw = function(gd, index, opt, value) {
    if(!isNumeric(index) || index === -1) {
        // no index provided - we're operating on ALL shapes
        if(!index && Array.isArray(value)) {
            replaceAllShapes(gd, value);
            return;
        }
        else if(value === 'remove') {
            deleteAllShapes(gd);
            return;
        }
        else if(opt && value !== 'add') {
            updateAllShapes(gd, opt, value);
            return;
        }
        else {
            // add a new empty annotation
            index = gd._fullLayout.shapes.length;
            gd._fullLayout.shapes.push({});
        }
    }

    if(!opt && value) {
        if(value === 'remove') {
            deleteShape(gd, index);
            return;
        }
        else if(value === 'add' || Lib.isPlainObject(value)) {
            insertShape(gd, index, value);
        }
    }

    updateShape(gd, index, opt, value);
};
Example #27
0
function formatTime(x, tr) {
    var timePart = mod(x + 0.05, ONEDAY);

    var timeStr = lpad(Math.floor(timePart / ONEHOUR), 2) + ':' +
        lpad(mod(Math.floor(timePart / ONEMIN), 60), 2);

    if(tr !== 'M') {
        if(!isNumeric(tr)) tr = 0; // should only be 'S'

        /*
         * this is a weird one - and shouldn't come up unless people
         * monkey with tick0 in weird ways, but we need to do something!
         * IN PARTICULAR we had better not display garbage (see below)
         * for numbers we always round to the nearest increment of the
         * precision we're showing, and this seems like the right way to
         * handle seconds and milliseconds, as they have a decimal point
         * and people will interpret that to mean rounding like numbers.
         * but for larger increments we floor the value: it's always
         * 2013 until the ball drops on the new year. We could argue about
         * which field it is where we start rounding (should 12:08:59
         * round to 12:09 if we're stopping at minutes?) but for now I'll
         * say we round seconds but floor everything else. BUT that means
         * we need to never round up to 60 seconds, ie 23:59:60
         */
        var sec = Math.min(mod(x / ONESEC, 60), MAXSECONDS[tr]);

        var secStr = (100 + sec).toFixed(tr).substr(1);
        if(tr > 0) {
            secStr = secStr.replace(/0+$/, '').replace(/[\.]$/, '');
        }

        timeStr += ':' + secStr;
    }
    return timeStr;
}
Example #28
0
exports.manageArrayContainers = function(np, newVal, undoit) {
    var obj = np.obj,
        parts = np.parts,
        pLength = parts.length,
        pLast = parts[pLength - 1];

    var pLastIsNumber = isNumeric(pLast);

    // delete item
    if(pLastIsNumber && newVal === null) {

        // Clear item in array container when new value is null
        var contPath = parts.slice(0, pLength - 1).join('.'),
            cont = Lib.nestedProperty(obj, contPath).get();
        cont.splice(pLast, 1);

        // Note that nested property clears null / undefined at end of
        // array container, but not within them.
    }
    // create item
    else if(pLastIsNumber && np.get() === undefined) {

        // When adding a new item, make sure undo command will remove it
        if(np.get() === undefined) undoit[np.astr] = null;

        np.set(newVal);
    }
    // update item
    else {

        // If the last part of attribute string isn't a number,
        // np.set is all we need.
        np.set(newVal);
    }
};
Example #29
0
proto.handlePick = function(pickResult) {
    var index = pickResult.pointId;

    if(pickResult.object !== this.line || this.connectgaps) {
        index = this.idToIndex[pickResult.pointId];
    }

    var x = this.pickXData[index];

    return {
        trace: this,
        dataCoord: pickResult.dataCoord,
        traceCoord: [
            isNumeric(x) || !Lib.isDateTime(x) ? x : Lib.dateTime2ms(x),
            this.pickYData[index]
        ],
        textLabel: Array.isArray(this.textLabels) ?
            this.textLabels[index] :
            this.textLabels,
        color: Array.isArray(this.color) ?
            this.color[index] :
            this.color,
        name: this.name,
        pointIndex: index,
        hoverinfo: this.hoverinfo
    };
};
Example #30
0
    function binVal(cd, val, pos, posDistinct, dPos) {
        var posDistinctLength = posDistinct.length,
            valLength = val.length,
            valBinned = [],
            bins = [],
            i, p, n, v;

        // store distinct pos in cd, find bins, init. valBinned
        for(i = 0; i < posDistinctLength; ++i) {
            p = posDistinct[i];
            cd[i] = {pos: p};
            bins[i] = p - dPos;
            valBinned[i] = [];
        }
        bins.push(posDistinct[posDistinctLength-1] + dPos);

        // bin the values
        for(i = 0; i < valLength; ++i) {
            v = val[i];
            if(!isNumeric(v)) continue;
            n = Lib.findBin(pos[i], bins);
            if(n>=0 && n<valLength) valBinned[n].push(v);
        }

        return valBinned;
    }