Skip to content

Commit 9c68ec3

Browse files
committed
indicator: implementation
1 parent c4b4d0c commit 9c68ec3

File tree

11 files changed

+1098
-1
lines changed

11 files changed

+1098
-1
lines changed

lib/index-finance.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ Plotly.register([
1818
require('./ohlc'),
1919
require('./candlestick'),
2020
require('./funnel'),
21-
require('./waterfall')
21+
require('./waterfall'),
22+
require('./indicator')
2223
]);
2324

2425
module.exports = Plotly;

lib/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ Plotly.register([
4949
require('./scattermapbox'),
5050

5151
require('./sankey'),
52+
require('./indicator'),
5253

5354
require('./table'),
5455

lib/indicator.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* Copyright 2012-2019, 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+
'use strict';
10+
11+
module.exports = require('../src/traces/indicator');

src/constants/delta.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* Copyright 2012-2019, 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+
'use strict';
10+
11+
module.exports = {
12+
INCREASING: {
13+
COLOR: '#3D9970',
14+
SYMBOL: '▲'
15+
},
16+
DECREASING: {
17+
COLOR: '#FF4136',
18+
SYMBOL: '▼'
19+
}
20+
};

src/plot_api/plot_api.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3779,6 +3779,9 @@ function makePlotFramework(gd) {
37793779
// single sunburst layer for the whole plot
37803780
fullLayout._sunburstlayer = fullLayout._paper.append('g').classed('sunburstlayer', true);
37813781

3782+
// single indicator layer for the whole plot
3783+
fullLayout._indicatorlayer = fullLayout._paper.append('g').classed('indicatorlayer', true);
3784+
37823785
// fill in image server scrape-svg
37833786
fullLayout._glimages = fullLayout._paper.append('g').classed('glimages', true);
37843787

src/traces/indicator/base_plot.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/**
2+
* Copyright 2012-2019, 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+
'use strict';
10+
11+
var Registry = require('../../registry');
12+
var getModuleCalcData = require('../../plots/get_data').getModuleCalcData;
13+
14+
var name = exports.name = 'indicator';
15+
16+
exports.plot = function(gd, traces, transitionOpts, makeOnCompleteCallback) {
17+
var _module = Registry.getModule(name);
18+
var cdmodule = getModuleCalcData(gd.calcdata, _module)[0];
19+
_module.plot(gd, cdmodule, transitionOpts, makeOnCompleteCallback);
20+
};
21+
22+
exports.clean = function(newFullData, newFullLayout, oldFullData, oldFullLayout) {
23+
var had = (oldFullLayout._has && oldFullLayout._has(name));
24+
var has = (newFullLayout._has && newFullLayout._has(name));
25+
26+
if(had && !has) {
27+
oldFullLayout._indicatorlayer.selectAll('g.trace').remove();
28+
}
29+
};

src/traces/indicator/calc.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* Copyright 2012-2019, 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+
'use strict';
10+
11+
// var Lib = require('../../lib');
12+
13+
function calc(gd, trace) {
14+
var cd = [];
15+
16+
// var singleValue = len === 1;
17+
// var lastReading = trace.values[len - 1];
18+
// var secondLastReading = singleValue ? lastReading : trace.values[len - 2];
19+
var lastReading = trace.value;
20+
var secondLastReading = trace.delta ? trace.delta.reference : trace._lastValue || trace.value;
21+
cd[0] = {
22+
y: lastReading,
23+
lastY: secondLastReading,
24+
25+
delta: lastReading - secondLastReading,
26+
relativeDelta: (lastReading - secondLastReading) / secondLastReading,
27+
};
28+
return cd;
29+
}
30+
31+
module.exports = {
32+
calc: calc
33+
};

src/traces/indicator/constants.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* Copyright 2012-2019, 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+
'use strict';
10+
11+
module.exports = {
12+
// Defaults for delta
13+
defaultNumberFontSize: 80,
14+
bulletNumberDomainSize: 0.25,
15+
bulletPadding: 0.025,
16+
innerRadius: 0.75,
17+
valueThickness: 0.5, // thickness of value bars relative to full thickness,
18+
titlePadding: 5
19+
};

src/traces/indicator/defaults.js

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
/**
2+
* Copyright 2012-2019, 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+
'use strict';
10+
11+
var Lib = require('../../lib');
12+
var attributes = require('./attributes');
13+
var handleDomainDefaults = require('../../plots/domain').defaults;
14+
var Template = require('../../plot_api/plot_template');
15+
var handleArrayContainerDefaults = require('../../plots/array_container_defaults');
16+
var cn = require('./constants.js');
17+
18+
var handleTickValueDefaults = require('../../plots/cartesian/tick_value_defaults');
19+
var handleTickMarkDefaults = require('../../plots/cartesian/tick_mark_defaults');
20+
var handleTickLabelDefaults = require('../../plots/cartesian/tick_label_defaults');
21+
22+
function supplyDefaults(traceIn, traceOut, defaultColor, layout) {
23+
function coerce(attr, dflt) {
24+
return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);
25+
}
26+
27+
handleDomainDefaults(traceOut, layout, coerce);
28+
29+
// Mode
30+
coerce('mode');
31+
traceOut._hasNumber = traceOut.mode.indexOf('number') !== -1;
32+
traceOut._hasDelta = traceOut.mode.indexOf('delta') !== -1;
33+
traceOut._hasGauge = traceOut.mode.indexOf('gauge') !== -1;
34+
35+
coerce('value');
36+
coerce('vmin');
37+
coerce('vmax', 1.5 * traceOut.value);
38+
39+
// Number attributes
40+
var auto = [];
41+
var bignumberFontSize;
42+
if(traceOut._hasNumber) {
43+
coerce('number.valueformat');
44+
coerce('number.font.color', layout.font.color);
45+
coerce('number.font.family', layout.font.family);
46+
coerce('number.font.size', 'auto');
47+
if(traceOut.number.font.size === 'auto') {
48+
traceOut.number.font.size = cn.defaultNumberFontSize;
49+
auto[0] = true;
50+
}
51+
coerce('number.suffix');
52+
bignumberFontSize = traceOut.number.font.size;
53+
}
54+
55+
// delta attributes
56+
var deltaFontSize;
57+
if(traceOut._hasDelta) {
58+
coerce('delta.font.color', layout.font.color);
59+
coerce('delta.font.family', layout.font.family);
60+
coerce('delta.font.size', 'auto');
61+
if(traceOut.delta.font.size === 'auto') {
62+
traceOut.delta.font.size = (traceOut._hasNumber ? 0.5 : 1) * (bignumberFontSize || cn.defaultNumberFontSize);
63+
auto[1] = true;
64+
}
65+
coerce('delta.reference', traceOut.value);
66+
coerce('delta.relative');
67+
coerce('delta.valueformat', traceOut.delta.relative ? '2%' : '.3s');
68+
coerce('delta.increasing.symbol');
69+
coerce('delta.increasing.color');
70+
coerce('delta.decreasing.symbol');
71+
coerce('delta.decreasing.color');
72+
coerce('delta.position');
73+
deltaFontSize = traceOut.delta.font.size;
74+
}
75+
traceOut._scaleNumbers = (!traceOut._hasNumber || auto[0]) && (!traceOut._hasDelta || auto[1]) || false;
76+
77+
// Title attributes
78+
coerce('title.font.color', layout.font.color);
79+
coerce('title.font.family', layout.font.family);
80+
coerce('title.font.size', 0.25 * (bignumberFontSize || deltaFontSize || cn.defaultNumberFontSize));
81+
coerce('title.text');
82+
83+
// Gauge attributes
84+
var gaugeIn, gaugeOut, axisIn, axisOut;
85+
function coerceGauge(attr, dflt) {
86+
return Lib.coerce(gaugeIn, gaugeOut, attributes.gauge, attr, dflt);
87+
}
88+
function coerceGaugeAxis(attr, dflt) {
89+
return Lib.coerce(axisIn, axisOut, attributes.gauge.axis, attr, dflt);
90+
}
91+
if(traceOut._hasGauge) {
92+
gaugeIn = traceIn.gauge;
93+
gaugeOut = Template.newContainer(traceOut, 'gauge');
94+
coerceGauge('shape');
95+
var isBullet = traceOut._isBullet = traceOut.gauge.shape === 'bullet';
96+
if(!isBullet) {
97+
coerce('title.align', 'center');
98+
}
99+
var isAngular = traceOut._isAngular = traceOut.gauge.shape === 'angular';
100+
if(!isAngular) {
101+
coerce('align', 'center');
102+
}
103+
104+
// gauge background
105+
coerceGauge('bgcolor');
106+
coerceGauge('borderwidth');
107+
coerceGauge('bordercolor');
108+
109+
// gauge value indicator
110+
coerceGauge('value.color');
111+
coerceGauge('value.line.color');
112+
coerceGauge('value.line.width');
113+
var defaultValueThickness = cn.valueThickness * (traceOut.gauge.shape === 'bullet' ? 0.5 : 1);
114+
coerceGauge('value.thickness', defaultValueThickness);
115+
116+
// Gauge steps
117+
if(gaugeIn && gaugeIn.steps) {
118+
handleArrayContainerDefaults(gaugeIn, gaugeOut, {
119+
name: 'steps',
120+
handleItemDefaults: stepDefaults
121+
});
122+
} else {
123+
gaugeOut.steps = [];
124+
}
125+
126+
// Gauge threshold
127+
coerceGauge('threshold.value');
128+
coerceGauge('threshold.thickness');
129+
coerceGauge('threshold.line.width');
130+
coerceGauge('threshold.line.color');
131+
132+
// Gauge axis
133+
axisIn = {};
134+
if(gaugeIn) axisIn = gaugeIn.axis || {};
135+
axisOut = Template.newContainer(gaugeOut, 'axis');
136+
handleTickValueDefaults(axisIn, axisOut, coerceGaugeAxis, 'linear');
137+
138+
var opts = {outerTicks: false, font: layout.font};
139+
handleTickLabelDefaults(axisIn, axisOut, coerceGaugeAxis, 'linear', opts);
140+
handleTickMarkDefaults(axisIn, axisOut, coerceGaugeAxis, 'linear', opts);
141+
} else {
142+
coerce('title.align', 'center');
143+
coerce('align', 'center');
144+
traceOut._isAngular = traceOut._isBullet = false;
145+
}
146+
}
147+
148+
function stepDefaults(valueIn, valueOut) {
149+
function coerce(attr, dflt) {
150+
return Lib.coerce(valueIn, valueOut, attributes.gauge.steps, attr, dflt);
151+
}
152+
153+
coerce('color');
154+
coerce('line.color');
155+
coerce('line.width');
156+
coerce('range');
157+
coerce('thickness');
158+
}
159+
160+
module.exports = {
161+
supplyDefaults: supplyDefaults
162+
};

src/traces/indicator/index.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* Copyright 2012-2019, 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+
'use strict';
10+
11+
module.exports = {
12+
moduleType: 'trace',
13+
name: 'indicator',
14+
basePlotModule: require('./base_plot'),
15+
categories: ['svg', 'noOpacity', 'noHover'],
16+
animatable: true,
17+
18+
attributes: require('./attributes'),
19+
supplyDefaults: require('./defaults').supplyDefaults,
20+
21+
calc: require('./calc').calc,
22+
23+
plot: require('./plot'),
24+
25+
meta: {
26+
description: [
27+
'TODO: add description'
28+
].join(' ')
29+
}
30+
};

0 commit comments

Comments
 (0)