Skip to content

Commit

Permalink
closes #141: Major dependency update to d3 v4
Browse files Browse the repository at this point in the history
Potentially breaking changes:
* axisannotation requires `axisannotation.orient` (new member) to be set as this is no longer exposed by `d3.axis`, and cannot be auto calculated.
* `financetime.zoomable` returns a persistent version zoomable, 1 instance per financetime. Previously returning a new instance per call. Previous functionality can be obtained by calling `financetime.zoomable().copy()`
  • Loading branch information
andredumas committed Sep 27, 2016
1 parent afe31e0 commit a422cc6
Show file tree
Hide file tree
Showing 69 changed files with 342 additions and 322 deletions.
2 changes: 1 addition & 1 deletion Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ module.exports = function(grunt) {
main: {
options: {
patterns: [
{ match: /http:\/\/d3js\.org\/d3\.v3\.min\.js/g, replacement: '/bower_components/d3/d3.js' },
{ match: /http:\/\/d3js\.org\/d3.*.js/g, replacement: '/bower_components/d3/d3.js' },
{ match: /http:\/\/techanjs\.org\/techan\.min\.js/g, replacement: '/<%= watchify.dev.dest %>' },
// Append the livereload script to the end of the example files
{ match: /^<\/script>/m, replacement: '</script>\n<script src="//localhost:35729/livereload.js"></script>' }
Expand Down
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@
"examples"
],
"dependencies": {
"d3": "~3.5.17"
"d3": "~4.2.6"
}
}
2 changes: 1 addition & 1 deletion examples/indicator/adx
Submodule adx updated from f50511 to d1f5ef
2 changes: 1 addition & 1 deletion examples/indicator/aroon
Submodule aroon updated from d792ad to fe34a7
2 changes: 1 addition & 1 deletion examples/indicator/atr
Submodule atr updated from f3d5af to ecc22d
2 changes: 1 addition & 1 deletion examples/indicator/atrtrailingstop
Submodule atrtrailingstop updated from 14dabe to d3aebc
2 changes: 1 addition & 1 deletion examples/indicator/bollinger
Submodule bollinger updated from 16daf4 to 9a24b4
2 changes: 1 addition & 1 deletion examples/indicator/heikinashi
Submodule heikinashi updated from 3e8b7d to f6e23b
2 changes: 1 addition & 1 deletion examples/indicator/ichimoku
Submodule ichimoku updated from 3a559b to d0aad1
2 changes: 1 addition & 1 deletion examples/indicator/macd
Submodule macd updated from 79e14a to f91508
2 changes: 1 addition & 1 deletion examples/indicator/rsi
Submodule rsi updated from 6ab929 to 2cc9e9
2 changes: 1 addition & 1 deletion examples/indicator/stochastic
Submodule stochastic updated from 76865d to 1c6501
2 changes: 1 addition & 1 deletion examples/indicator/williams
Submodule williams updated from c3405f to a88e06
2 changes: 1 addition & 1 deletion examples/node/candlestick
Submodule candlestick updated from f3bb47 to b34752
2 changes: 1 addition & 1 deletion examples/plot/axisannotation
Submodule axisannotation updated from f4ea9e to f53148
2 changes: 1 addition & 1 deletion examples/plot/candlestick
Submodule candlestick updated from a05a1e to ca6191
2 changes: 1 addition & 1 deletion examples/plot/close
Submodule close updated from fdc9b5 to cc7ff3
2 changes: 1 addition & 1 deletion examples/plot/crosshair
Submodule crosshair updated from 028403 to f64245
2 changes: 1 addition & 1 deletion examples/plot/feed
Submodule feed updated from 96712e to 0c2971
2 changes: 1 addition & 1 deletion examples/plot/multiplots
Submodule multiplots updated from 8c12c7 to 2633bd
2 changes: 1 addition & 1 deletion examples/plot/ohlc
Submodule ohlc updated from 684fed to 18576d
2 changes: 1 addition & 1 deletion examples/plot/plots
Submodule plots updated from 64c674 to c55248
2 changes: 1 addition & 1 deletion examples/plot/supstance
Submodule supstance updated from 683b79 to ca7067
2 changes: 1 addition & 1 deletion examples/plot/tick
Submodule tick updated from 65c1e8 to fe4a42
2 changes: 1 addition & 1 deletion examples/plot/tradearrow
Submodule tradearrow updated from 67aa53 to e84983
2 changes: 1 addition & 1 deletion examples/plot/trendline
Submodule trendline updated from 6c0ac3 to 3c58c3
2 changes: 1 addition & 1 deletion examples/plot/volume
Submodule volume updated from 08af43 to 50127a
2 changes: 1 addition & 1 deletion examples/scale/brush
Submodule brush updated from bbc413 to 7d3727
2 changes: 1 addition & 1 deletion examples/scale/financetime
Submodule financetime updated from 098706 to ff5b71
2 changes: 1 addition & 1 deletion examples/scale/zoom
Submodule zoom updated from 1ea271 to e83a01
2 changes: 1 addition & 1 deletion examples/scale/zoom-d3-scale
Submodule zoom-d3-scale updated from 162120 to b90062
2 changes: 1 addition & 1 deletion examples/svg/arrow
Submodule arrow updated from b7e56e to 020df9
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "techan",
"version": "0.7.0",
"version": "0.8.0-0",
"description": "A visual, technical analysis and charting (Candlestick, OHLC, indicators) library built on D3.",
"keywords": [
"technical analysis",
Expand All @@ -26,7 +26,7 @@
},
"license" : "MIT",
"dependencies": {
"d3": "~3.5.17"
"d3": "~4.2.6"
},
"devDependencies": {
"bower": "~1.7.9",
Expand Down
55 changes: 30 additions & 25 deletions src/plot/axisannotation.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@
/**
* TODO Refactor this to techan.plot.annotation.axis()?
*/
module.exports = function(d3_svg_axis, accessor_value, plot, plotMixin) { // Injected dependencies
module.exports = function(d3_svg_axis, d3_scale_linear, accessor_value, plot, plotMixin) { // Injected dependencies
return function() { // Closure function
var p = {},
axis = d3_svg_axis(),
axis = d3_svg_axis(d3_scale_linear()),
format,
point = 4,
height = 14,
width = 50,
translate = [0, 0];
translate = [0, 0],
orient = 'bottom';

function annotation(g) {
var group = p.dataSelector.mapper(filterInvalidValues(p.accessor, axis.scale()))(g);
Expand All @@ -24,7 +25,7 @@ module.exports = function(d3_svg_axis, accessor_value, plot, plotMixin) { // In

annotation.refresh = function(g) {
var fmt = format ? format : (axis.tickFormat() ? axis.tickFormat() : axis.scale().tickFormat());
refresh(p.dataSelector.select(g), p.accessor, axis, fmt, height, width, point, translate);
refresh(p.dataSelector.select(g), p.accessor, axis, orient, fmt, height, width, point, translate);
};

annotation.axis = function(_) {
Expand All @@ -33,6 +34,12 @@ module.exports = function(d3_svg_axis, accessor_value, plot, plotMixin) { // In
return annotation;
};

annotation.orient = function(_) {
if(!arguments.length) return orient;
orient = _;
return annotation;
};

annotation.format = function(_) {
if(!arguments.length) return format;
format = _;
Expand Down Expand Up @@ -63,12 +70,12 @@ module.exports = function(d3_svg_axis, accessor_value, plot, plotMixin) { // In
};
};

function refresh(selection, accessor, axis, format, height, width, point, translate) {
var neg = axis.orient() === 'left' || axis.orient() === 'top' ? -1 : 1;
function refresh(selection, accessor, axis, orient, format, height, width, point, translate) {
var neg = orient === 'left' || orient === 'top' ? -1 : 1;

selection.attr('transform', 'translate(' + translate[0] + ',' + translate[1] + ')');
selection.select('path').attr('d', backgroundPath(accessor, axis, height, width, point, neg));
selection.select('text').text(textValue(accessor, format)).call(textAttributes, accessor, axis, neg);
selection.select('path').attr('d', backgroundPath(accessor, axis, orient, height, width, point, neg));
selection.select('text').text(textValue(accessor, format)).call(textAttributes, accessor, axis, orient, neg);
}

function filterInvalidValues(accessor, scale) {
Expand All @@ -87,25 +94,23 @@ function filterInvalidValues(accessor, scale) {
};
}

function textAttributes(text, accessor, axis, neg) {
function textAttributes(text, accessor, axis, orient, neg) {
var scale = axis.scale();

switch(axis.orient()) {
switch(orient) {
case 'left':
case 'right':
text.attr({
x: neg*(Math.max(axis.innerTickSize(), 0) + axis.tickPadding()),
y: textPosition(accessor, scale),
dy: '.32em'
}).style('text-anchor', neg < 0 ? 'end' : 'start');
text.attr('x', neg*(Math.max(axis.tickSizeInner(), 0) + axis.tickPadding()))
.attr('y', textPosition(accessor, scale))
.attr('dy', '.32em')
.style('text-anchor', neg < 0 ? 'end' : 'start');
break;
case 'top':
case 'bottom':
text.attr({
x: textPosition(accessor, scale),
y: neg*(Math.max(axis.innerTickSize(), 0) + axis.tickPadding()),
dy: neg < 0 ? '0em' : '.72em'
}).style('text-anchor', 'middle');
text.attr('x', textPosition(accessor, scale))
.attr('y', neg*(Math.max(axis.tickSizeInner(), 0) + axis.tickPadding()))
.attr('dy', neg < 0 ? '0em' : '.72em')
.style('text-anchor', 'middle');
break;
}
}
Expand All @@ -122,21 +127,21 @@ function textValue(accessor, format) {
};
}

function backgroundPath(accessor, axis, height, width, point, neg) {
function backgroundPath(accessor, axis, orient, height, width, point, neg) {
return function(d) {
var scale = axis.scale(),
value = scale(accessor(d)),
pt = point;

switch(axis.orient()) {
switch(orient) {
case 'left':
case 'right':
var h = 0;

if(height/2 < point) pt = height/2;
else h = height/2-point;

return 'M 0 ' + value + ' l ' + (neg*Math.max(axis.innerTickSize(), 1)) + ' ' + (-pt) +
return 'M 0 ' + value + ' l ' + (neg*Math.max(axis.tickSizeInner(), 1)) + ' ' + (-pt) +
' l 0 ' + (-h) + ' l ' + (neg*width) + ' 0 l 0 ' + height +
' l ' + (neg*-width) + ' 0 l 0 ' + (-h);
case 'top':
Expand All @@ -146,10 +151,10 @@ function backgroundPath(accessor, axis, height, width, point, neg) {
if(width/2 < point) pt = width/2;
else w = width/2-point;

return 'M ' + value + ' 0 l ' + (-pt) + ' ' + (neg*Math.max(axis.innerTickSize(), 1)) +
return 'M ' + value + ' 0 l ' + (-pt) + ' ' + (neg*Math.max(axis.tickSizeInner(), 1)) +
' l ' + (-w) + ' 0 l 0 ' + (neg*height) + ' l ' + width + ' 0 l 0 ' + (neg*-height) +
' l ' + (-w) + ' 0';
default: throw "Unsupported axis.orient() = " + axis.orient();
default: throw "Unsupported orient value: axisannotation.orient(" + orient + "). Set to one of: 'top', 'bottom', 'left', 'right'";
}
};
}
19 changes: 9 additions & 10 deletions src/plot/crosshair.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ module.exports = function(d3_select, d3_event, d3_mouse, d3_dispatch, accessor_c
group.entry.append('g').attr('class', 'axisannotation x').call(xAnnotationComposer);
group.entry.append('g').attr('class', 'axisannotation y').call(yAnnotationComposer);

g.selectAll('rect').data([undefined]).enter().append('rect').style({ fill: 'none', 'pointer-events': 'all' });
g.selectAll('rect').data([undefined]).enter().append('rect').style('fill', 'none').style('pointer-events', 'all');

crosshair.refresh(g);
}
Expand All @@ -34,17 +34,16 @@ module.exports = function(d3_select, d3_event, d3_mouse, d3_dispatch, accessor_c
xAnnotationSelection = group.select('g.axisannotation.x'),
yAnnotationSelection = group.select('g.axisannotation.y');

g.selectAll('rect').attr({
x: Math.min.apply(null, xRange),
y: Math.min.apply(null, yRange),
height: Math.abs(yRange[yRange.length-1] - yRange[0]),
width: Math.abs(xRange[xRange.length-1] - xRange[0])
})
g.selectAll('rect')
.attr('x', Math.min.apply(null, xRange))
.attr('y', Math.min.apply(null, yRange))
.attr('height', Math.abs(yRange[yRange.length-1] - yRange[0]))
.attr('width', Math.abs(xRange[xRange.length-1] - xRange[0]))
.on('mouseenter', function() {
dispatcher.enter();
dispatcher.call('enter', this);
})
.on('mouseout', function() {
dispatcher.out();
dispatcher.call('out', this);
// Redraw with null values to ensure when we enter again, there is nothing cached when redisplayed
delete group.node().__coord__;
initialiseWire(group.datum()); // Mutating data, don't need to manually pass down
Expand Down Expand Up @@ -77,7 +76,7 @@ module.exports = function(d3_select, d3_event, d3_mouse, d3_dispatch, accessor_c

p.accessor.xv(d, xNew);
p.accessor.yv(d, yNew);
if(dispatch) dispatcher.move(d);
if(dispatch) dispatcher.call('move', selection.node(), d);
}

// Just before draw, convert the coords to
Expand Down
14 changes: 7 additions & 7 deletions src/plot/ichimoku.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

module.exports = function(d3_svg_area, accessor_ichimoku, plot, plotMixin) { // Injected dependencies
module.exports = function(d3_svg_area, d3_line_interpolate, accessor_ichimoku, plot, plotMixin) { // Injected dependencies
return function() { // Closure function
var p = {}, // Container for private, direct access mixed in variables
kumoClip = kumoClipArea(),
Expand All @@ -16,10 +16,10 @@ module.exports = function(d3_svg_area, accessor_ichimoku, plot, plotMixin) { //
clipUpId = 'kumoclipup-' + randomID(),
clipDownId = 'kumoclipdown-' + randomID();

group.entry.append('clipPath').attr({ id: clipDownId, class: 'kumoclipdown' }).append('path');
group.entry.append('clipPath').attr({ id: clipUpId, class: 'kumoclipup' }).append('path');
group.entry.append('path').attr({ class: 'kumo down', 'clip-path': 'url(#' + clipDownId + ')' });
group.entry.append('path').attr({ class: 'kumo up', 'clip-path':'url(#' + clipUpId + ')' });
group.entry.append('clipPath').attr('id', clipDownId).attr('class', 'kumoclipdown').append('path');
group.entry.append('clipPath').attr('id', clipUpId).attr('class', 'kumoclipup').append('path');
group.entry.append('path').attr('class', 'kumo down').attr('clip-path', 'url(#' + clipDownId + ')');
group.entry.append('path').attr('class', 'kumo up').attr('clip-path', 'url(#' + clipUpId + ')');
group.entry.append('path').attr('class', 'senkouspanb');
group.entry.append('path').attr('class', 'senkouspana');

Expand Down Expand Up @@ -56,14 +56,14 @@ module.exports = function(d3_svg_area, accessor_ichimoku, plot, plotMixin) { //
}

function kumoClipArea() {
return d3_svg_area().interpolate('monotone')
return d3_svg_area().curve(d3_line_interpolate)
.defined(function(d) { return p.accessor.sb(d) !== null; })
.x(function(d) { return p.xScale(p.accessor.d(d), p.accessor.pks(d)); } )
.y0(function(d) { return p.yScale(p.accessor.sb(d)); } );
}

function kumoPathArea() {
return d3_svg_area().interpolate('monotone')
return d3_svg_area().curve(d3_line_interpolate)
.defined(function(d) { return p.accessor.sa(d) !== null && p.accessor.sb(d) !== null; })
.x(function(d) { return p.xScale(p.accessor.d(d), p.accessor.pks(d)); } )
.y0(function(d) { return p.yScale(p.accessor.sa(d)); } )
Expand Down
21 changes: 11 additions & 10 deletions src/plot/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,35 @@
module.exports = function(d3) {
var scale = require('../scale')(d3),
accessor = require('../accessor')(),
plot = require('./plot')(d3.svg.line, d3.svg.area, d3.select),
plotMixin = require('./plotmixin')(d3.scale.linear, d3.functor, scale.financetime, plot.dataSelector, plot.barWidth),
candlestick = require('./candlestick')(d3.scale.linear, d3.extent, accessor.ohlc, plot, plotMixin),
plot = require('./plot')(d3.line, d3.area, d3.curveMonotoneX, d3.select),
d3_functor = require('../util')().functor,
plotMixin = require('./plotmixin')(d3.scaleLinear, d3_functor, scale.financetime, plot.dataSelector, plot.barWidth),
candlestick = require('./candlestick')(d3.scaleLinear, d3.extent, accessor.ohlc, plot, plotMixin),
line = require('./line'),
axisannotation = require('./axisannotation')(d3.svg.axis, accessor.value, plot, plotMixin),
axisannotation = require('./axisannotation')(d3.axisTop, d3.scaleLinear, accessor.value, plot, plotMixin),
svg = require('../svg')(d3);

return {
tradearrow: require('./tradearrow')(d3.select, d3.functor, d3.mouse, d3.dispatch, accessor.trade, plot, plotMixin, svg.arrow),
tradearrow: require('./tradearrow')(d3.select, d3_functor, d3.mouse, d3.dispatch, accessor.trade, plot, plotMixin, svg.arrow),
atr: line(accessor.value, plot, plotMixin),
atrtrailingstop: require('./atrtrailingstop')(accessor.atrtrailingstop, plot, plotMixin),
axisannotation: axisannotation,
candlestick: candlestick,
crosshair: require('./crosshair')(d3.select, d3_event, d3.mouse, d3.dispatch, accessor.crosshair, plot, plotMixin),
ema: line(accessor.value, plot, plotMixin),
heikinashi: candlestick,
ichimoku: require('./ichimoku')(d3.svg.area, accessor.ichimoku, plot, plotMixin),
ohlc: require('./ohlc')(d3.scale.linear, d3.extent, accessor.ohlc, plot, plotMixin),
tick: require('./tick')(d3.scale.linear, d3.extent, accessor.tick, plot, plotMixin),
ichimoku: require('./ichimoku')(d3.area, d3.curveMonotoneX, accessor.ichimoku, plot, plotMixin),
ohlc: require('./ohlc')(d3.scaleLinear, d3.extent, accessor.ohlc, plot, plotMixin),
tick: require('./tick')(d3.scaleLinear, d3.extent, accessor.tick, plot, plotMixin),
close: line(accessor.ohlc, plot, plotMixin),
volume: require('./volume')(accessor.volume, plot, plotMixin),
rsi: require('./rsi')(accessor.rsi, plot, plotMixin),
macd: require('./macd')(accessor.macd, plot, plotMixin),
momentum: line(accessor.value, plot, plotMixin, true),
moneyflow: line(accessor.value, plot, plotMixin, true),
sma: line(accessor.value, plot, plotMixin),
supstance: require('./supstance')(d3.behavior.drag, d3_event, d3.select, d3.dispatch, accessor.supstance, plot, plotMixin),
trendline: require('./trendline')(d3.behavior.drag, d3_event, d3.select, d3.dispatch, accessor.trendline, plot, plotMixin),
supstance: require('./supstance')(d3.drag, d3_event, d3.select, d3.dispatch, accessor.supstance, plot, plotMixin),
trendline: require('./trendline')(d3.drag, d3_event, d3.select, d3.dispatch, accessor.trendline, plot, plotMixin),
wilderma: line(accessor.value, plot, plotMixin),
adx: require('./adx')(accessor.adx, plot, plotMixin),
aroon: require('./aroon')(accessor.aroon, plot, plotMixin),
Expand Down
Loading

0 comments on commit a422cc6

Please sign in to comment.