Skip to content

Commit

Permalink
refs andredumas#100: Added a method to enable nearest tick value calc…
Browse files Browse the repository at this point in the history
…ulation
  • Loading branch information
andredumas committed Dec 20, 2015
1 parent a235a06 commit aa37731
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 9 deletions.
27 changes: 20 additions & 7 deletions src/scale/financetime.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
and weekends respectively. When plot, is done so without weekend gaps.
*/
module.exports = function(d3_scale_linear, d3_time, d3_bisect, techan_util_rebindCallback, scale_widen, zoomable) { // Injected dependencies
function financetime(index, domain, padding, outerPadding, zoomLimit) {
function financetime(index, domain, padding, outerPadding, zoomLimit, closestTicks) {
var dateIndexMap,
tickState = { tickFormat: dailyTickMethod[dailyTickMethod.length-1][2] },
band = 3;
Expand All @@ -16,6 +16,7 @@ module.exports = function(d3_scale_linear, d3_time, d3_bisect, techan_util_rebin
padding = padding === undefined ? 0.2 : padding;
outerPadding = outerPadding === undefined ? 0.65 : outerPadding;
zoomLimit = zoomLimit || index.domain();
closestTicks = closestTicks || false;

/**
* Scales the value to domain. If the value is not within the domain, will currently brutally round the data:
Expand Down Expand Up @@ -112,7 +113,7 @@ module.exports = function(d3_scale_linear, d3_time, d3_bisect, techan_util_rebin
}

scale.copy = function() {
return financetime(index.copy(), domain, padding, outerPadding, zoomLimit);
return financetime(index.copy(), domain, padding, outerPadding, zoomLimit, closestTicks);
};

/**
Expand Down Expand Up @@ -177,9 +178,21 @@ module.exports = function(d3_scale_linear, d3_time, d3_bisect, techan_util_rebin

var intervalRange = interval.range(visibleDomain[0], +visibleDomain[visibleDomain.length-1]+1, steps);

return intervalRange // Interval, possibly contains values not in domain
.map(domainTicks(visibleDomain)) // Line up interval ticks with domain, possibly adding duplicates
.reduce(sequentialDuplicates, []); // Filter out duplicates, produce new 'reduced' array
return intervalRange // Interval, possibly contains values not in domain
.map(domainTicks(visibleDomain, closestTicks)) // Line up interval ticks with domain, possibly adding duplicates
.reduce(sequentialDuplicates, []); // Filter out duplicates, produce new 'reduced' array
};

/**
* By default `ticks()` will generate tick values greater than the nearest domain interval value, which may not be
* best value, particularly for irregular intraday domains. Setting this to true will cause tick generation to choose
* values closest to the corresponding domain value for the calculated interval.
* @param _ Optional `boolean` value. If argument is passed, sets the value and returns this instance, if no argument, returns the current value
*/
scale.closestTicks = function(_) {
if(!arguments.length) return closestTicks;
closestTicks = _;
return scale;
};

/**
Expand Down Expand Up @@ -302,14 +315,14 @@ module.exports = function(d3_scale_linear, d3_time, d3_bisect, techan_util_rebin
return lookup;
}

function domainTicks(visibleDomain) {
function domainTicks(visibleDomain, closest) {
var visibleDomainLookup = lookupIndex(visibleDomain); // Quickly lookup index of the domain

return function(d) {
var value = visibleDomainLookup[+d];
if (value !== undefined) return visibleDomain[value];
var index = d3_bisect(visibleDomain, d);
if (index > 0) {
if (closest && index > 0) {
// d3_bisect gets the index of the closest value that is the greater than d,
// which may not be the value that is closest to d.
// If the closest value that is smaller than d is closer, choose that instead.
Expand Down
36 changes: 34 additions & 2 deletions test/spec/bundle/scale/financetimeSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,6 @@ techanModule('scale/financetime', function(specBuilder) {

it('Then ticks with specified interval and step count returns that number', function() {
expect(financetime.ticks(d3.time.day, 2)).toEqual([
new Date(2012,4,18),
new Date(2012,4,21),
new Date(2012,4,23),
new Date(2012,4,25),
Expand All @@ -200,6 +199,24 @@ techanModule('scale/financetime', function(specBuilder) {
]);
});

describe('And closestTicks is true', function() {
beforeEach(function() {
financetime.closestTicks(true);
});

it('Then ticks with specified interval and step count returns that number', function() {
expect(financetime.ticks(d3.time.day, 2)).toEqual([
new Date(2012,4,18),
new Date(2012,4,21),
new Date(2012,4,23),
new Date(2012,4,25),
new Date(2012,4,29),
new Date(2012,4,31),
new Date(2012,5,1)
]);
});
});

it('Then default tickFormat should be yearly', function() {
expect(financetime.tickFormat()(new Date(2012,0,20))).toEqual('2012');
});
Expand Down Expand Up @@ -426,14 +443,29 @@ techanModule('scale/financetime', function(specBuilder) {

it('Then ticks with specified interval and step count returns that number', function() {
expect(financetime.ticks(d3.time.day, 2)).toEqual([
new Date(2012,4,18),
new Date(2012,4,21),
new Date(2012,4,23),
new Date(2012,4,25),
new Date(2012,4,29)
]);
});

describe('And closestTicks is true', function() {
beforeEach(function() {
financetime.closestTicks(true);
});

it('Then ticks with specified interval and step count returns that number', function() {
expect(financetime.ticks(d3.time.day, 2)).toEqual([
new Date(2012,4,18),
new Date(2012,4,21),
new Date(2012,4,23),
new Date(2012,4,25),
new Date(2012,4,29)
]);
});
});

describe('And copied', function() {
var cloned;

Expand Down

0 comments on commit aa37731

Please sign in to comment.