Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2ba8f80

Browse files
committed
split up histogram index
1 parent 7f1801e commit 2ba8f80

File tree

6 files changed

+325
-273
lines changed

6 files changed

+325
-273
lines changed

src/traces/histogram/average.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* Copyright 2012-2015, Plotly, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
10+
'use strict';
11+
12+
13+
module.exports = function doAvg(size, counts) {
14+
var nMax = size.length,
15+
total = 0;
16+
for(var i=0; i<nMax; i++) {
17+
if(counts[i]) {
18+
size[i] /= counts[i];
19+
total += size[i];
20+
}
21+
else size[i] = null;
22+
}
23+
return total;
24+
};

src/traces/histogram/bin_functions.js

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/**
2+
* Copyright 2012-2015, Plotly, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
10+
'use strict';
11+
12+
var isNumeric = require('fast-isnumeric');
13+
14+
15+
module.exports = {
16+
count: function(n, i, size) {
17+
size[n]++;
18+
return 1;
19+
},
20+
21+
sum: function(n, i, size, counterData) {
22+
var v = counterData[i];
23+
if(isNumeric(v)) {
24+
v = Number(v);
25+
size[n] += v;
26+
return v;
27+
}
28+
return 0;
29+
},
30+
31+
avg: function(n, i, size, counterData, counts) {
32+
var v = counterData[i];
33+
if(isNumeric(v)) {
34+
v = Number(v);
35+
size[n] += v;
36+
counts[n]++;
37+
}
38+
return 0;
39+
},
40+
41+
min: function(n, i, size, counterData) {
42+
var v = counterData[i];
43+
if(isNumeric(v)) {
44+
v = Number(v);
45+
if(!isNumeric(size[n])) {
46+
size[n] = v;
47+
return v;
48+
}
49+
else if(size[n]>v) {
50+
size[n] = v;
51+
return v-size[n];
52+
}
53+
}
54+
return 0;
55+
},
56+
57+
max: function(n, i, size, counterData) {
58+
var v = counterData[i];
59+
if(isNumeric(v)) {
60+
v = Number(v);
61+
if(!isNumeric(size[n])) {
62+
size[n] = v;
63+
return v;
64+
}
65+
else if(size[n]<v) {
66+
size[n] = v;
67+
return v-size[n];
68+
}
69+
}
70+
return 0;
71+
}
72+
};

src/traces/histogram/calc.js

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/**
2+
* Copyright 2012-2015, Plotly, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
10+
'use strict';
11+
12+
var isNumeric = require('fast-isnumeric');
13+
14+
var Plotly = require('../../plotly');
15+
var Lib = require('../../lib');
16+
17+
var binFunctions = require('./bin_functions');
18+
var normFunctions = require('./norm_functions');
19+
var doAvg = require('./average');
20+
21+
22+
module.exports = function calc(gd, trace) {
23+
// ignore as much processing as possible (and including in autorange) if bar is not visible
24+
if(trace.visible !== true) return;
25+
26+
// depending on orientation, set position and size axes and data ranges
27+
// note: this logic for choosing orientation is duplicated in graph_obj->setstyles
28+
var pos = [],
29+
size = [],
30+
i,
31+
pa = Plotly.Axes.getFromId(gd,
32+
trace.orientation==='h' ? (trace.yaxis || 'y') : (trace.xaxis || 'x')),
33+
maindata = trace.orientation==='h' ? 'y' : 'x',
34+
counterdata = {x: 'y', y: 'x'}[maindata];
35+
36+
// prepare the raw data
37+
var pos0 = pa.makeCalcdata(trace, maindata);
38+
// calculate the bins
39+
if((trace['autobin' + maindata]!==false) || !(maindata + 'bins' in trace)) {
40+
trace[maindata + 'bins'] = Plotly.Axes.autoBin(pos0, pa, trace['nbins' + maindata]);
41+
42+
// copy bin info back to the source data.
43+
trace._input[maindata + 'bins'] = trace[maindata + 'bins'];
44+
}
45+
46+
var binspec = trace[maindata + 'bins'],
47+
allbins = typeof binspec.size === 'string',
48+
bins = allbins ? [] : binspec,
49+
// make the empty bin array
50+
i2,
51+
binend,
52+
n,
53+
inc = [],
54+
counts = [],
55+
total = 0,
56+
norm = trace.histnorm,
57+
func = trace.histfunc,
58+
densitynorm = norm.indexOf('density')!==-1,
59+
extremefunc = func==='max' || func==='min',
60+
sizeinit = extremefunc ? null : 0,
61+
binfunc = binFunctions.count,
62+
normfunc = normFunctions[norm],
63+
doavg = false,
64+
rawCounterData;
65+
66+
if(Array.isArray(trace[counterdata]) && func!=='count') {
67+
rawCounterData = trace[counterdata];
68+
doavg = func==='avg';
69+
binfunc = binFunctions[func];
70+
}
71+
72+
// create the bins (and any extra arrays needed)
73+
// assume more than 5000 bins is an error, so we don't crash the browser
74+
i = binspec.start;
75+
// decrease end a little in case of rounding errors
76+
binend = binspec.end +
77+
(binspec.start - Plotly.Axes.tickIncrement(binspec.start, binspec.size)) / 1e6;
78+
while(i<binend && pos.length<5000) {
79+
i2 = Plotly.Axes.tickIncrement(i, binspec.size);
80+
pos.push((i + i2) / 2);
81+
size.push(sizeinit);
82+
// nonuniform bins (like months) we need to search,
83+
// rather than straight calculate the bin we're in
84+
if(allbins) bins.push(i);
85+
// nonuniform bins also need nonuniform normalization factors
86+
if(densitynorm) inc.push(1 / (i2 - i));
87+
if(doavg) counts.push(0);
88+
i = i2;
89+
}
90+
91+
var nMax = size.length;
92+
// bin the data
93+
for(i=0; i<pos0.length; i++) {
94+
n = Lib.findBin(pos0[i], bins);
95+
if(n>=0 && n<nMax) total += binfunc(n, i, size, rawCounterData, counts);
96+
}
97+
98+
// average and/or normalize the data, if needed
99+
if(doavg) total = doAvg(size, counts);
100+
if(normfunc) normfunc(size, total, inc);
101+
102+
var serieslen = Math.min(pos.length, size.length),
103+
cd = [],
104+
firstNonzero = 0,
105+
lastNonzero = serieslen-1;
106+
// look for empty bins at the ends to remove, so autoscale omits them
107+
for(i=0; i<serieslen; i++) {
108+
if(size[i]) {
109+
firstNonzero = i;
110+
break;
111+
}
112+
}
113+
for(i=serieslen-1; i>firstNonzero; i--) {
114+
if(size[i]) {
115+
lastNonzero = i;
116+
break;
117+
}
118+
}
119+
120+
// create the "calculated data" to plot
121+
for(i=firstNonzero; i<=lastNonzero; i++) {
122+
if((isNumeric(pos[i]) && isNumeric(size[i]))) {
123+
cd.push({p: pos[i], s: size[i], b: 0});
124+
}
125+
}
126+
127+
return cd;
128+
};

src/traces/histogram/defaults.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/**
2+
* Copyright 2012-2015, Plotly, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
10+
'use strict';
11+
12+
var Plotly = require('../../plotly');
13+
var Lib = require('../../lib');
14+
15+
var attributes = require('./attributes');
16+
17+
18+
module.exports = function(traceIn, traceOut) {
19+
function coerce(attr, dflt) {
20+
return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);
21+
}
22+
23+
var binDirections = ['x'],
24+
hasAggregationData,
25+
x = coerce('x'),
26+
y = coerce('y');
27+
28+
if(Plotly.Plots.traceIs(traceOut, '2dMap')) {
29+
// we could try to accept x0 and dx, etc...
30+
// but that's a pretty weird use case.
31+
// for now require both x and y explicitly specified.
32+
if(!(x && x.length && y && y.length)) {
33+
traceOut.visible = false;
34+
return;
35+
}
36+
37+
// if marker.color is an array, we can use it in aggregation instead of z
38+
hasAggregationData = coerce('z') || coerce('marker.color');
39+
40+
binDirections = ['x','y'];
41+
} else {
42+
var orientation = coerce('orientation', (y && !x) ? 'h' : 'v'),
43+
sample = traceOut[orientation==='v' ? 'x' : 'y'];
44+
45+
if(!(sample && sample.length)) {
46+
traceOut.visible = false;
47+
return;
48+
}
49+
50+
if(orientation==='h') binDirections = ['y'];
51+
52+
hasAggregationData = traceOut[orientation==='h' ? 'x' : 'y'];
53+
}
54+
55+
if(hasAggregationData) coerce('histfunc');
56+
coerce('histnorm');
57+
58+
binDirections.forEach(function(binDirection) {
59+
// data being binned - note that even though it's a little weird,
60+
// it's possible to have bins without data, if there's inferred data
61+
var binstrt = coerce(binDirection + 'bins.start'),
62+
binend = coerce(binDirection + 'bins.end'),
63+
autobin = coerce('autobin' + binDirection, !(binstrt && binend));
64+
65+
if(autobin) coerce('nbins' + binDirection);
66+
else coerce(binDirection + 'bins.size');
67+
});
68+
};

0 commit comments

Comments
 (0)