@@ -24,7 +24,9 @@ var cleanTicks = require('./clean_ticks');
2424
2525var constants = require ( '../../constants/numerical' ) ;
2626var ONEAVGYEAR = constants . ONEAVGYEAR ;
27+ var ONEAVGQUARTER = constants . ONEAVGQUARTER ;
2728var ONEAVGMONTH = constants . ONEAVGMONTH ;
29+ var ONEWEEK = constants . ONEWEEK ;
2830var ONEDAY = constants . ONEDAY ;
2931var ONEHOUR = constants . ONEHOUR ;
3032var ONEMIN = constants . ONEMIN ;
@@ -695,23 +697,51 @@ axes.calcTicks = function calcTicks(ax, opts) {
695697
696698 var definedDelta ;
697699 if ( isPeriod && ax . tickformat ) {
698- var _has = function ( str ) {
699- return ax . tickformat . indexOf ( str ) !== - 1 ;
700- } ;
701-
702700 if (
703- ! _has ( '%f' ) &&
704- ! _has ( '%H' ) &&
705- ! _has ( '%I' ) &&
706- ! _has ( '%L' ) &&
707- ! _has ( '%Q' ) &&
708- ! _has ( '%S' ) &&
709- ! _has ( '%s' ) &&
710- ! _has ( '%X' )
701+ ! ( / % [ f L Q s S M H I p X ] / . test ( ax . tickformat ) )
702+ // %f: microseconds as a decimal number [000000, 999999]
703+ // %L: milliseconds as a decimal number [000, 999]
704+ // %Q: milliseconds since UNIX epoch
705+ // %s: seconds since UNIX epoch
706+ // %S: second as a decimal number [00,61]
707+ // %M: minute as a decimal number [00,59]
708+ // %H: hour (24-hour clock) as a decimal number [00,23]
709+ // %I: hour (12-hour clock) as a decimal number [01,12]
710+ // %p: either AM or PM
711+ // %X: the locale’s time, such as %-I:%M:%S %p
711712 ) {
712- if ( _has ( '%x' ) || _has ( '%d' ) || _has ( '%e' ) || _has ( '%j' ) ) definedDelta = ONEDAY ;
713- else if ( _has ( '%B' ) || _has ( '%b' ) || _has ( '%m' ) ) definedDelta = ONEAVGMONTH ;
714- else if ( _has ( '%Y' ) || _has ( '%y' ) ) definedDelta = ONEAVGYEAR ;
713+ if (
714+ / % [ A a d e j u w x ] / . test ( ax . tickformat )
715+ // %A: full weekday name
716+ // %a: abbreviated weekday name
717+ // %d: zero-padded day of the month as a decimal number [01,31]
718+ // %e: space-padded day of the month as a decimal number [ 1,31]
719+ // %j: day of the year as a decimal number [001,366]
720+ // %u: Monday-based (ISO 8601) weekday as a decimal number [1,7]
721+ // %w: Sunday-based weekday as a decimal number [0,6]
722+ // %x: the locale’s date, such as %-m/%-d/%Y
723+ ) definedDelta = ONEDAY ;
724+ else if (
725+ / % [ U V W ] / . test ( ax . tickformat )
726+ // %U: Sunday-based week of the year as a decimal number [00,53]
727+ // %V: ISO 8601 week of the year as a decimal number [01, 53]
728+ // %W: Monday-based week of the year as a decimal number [00,53]
729+ ) definedDelta = ONEWEEK ;
730+ else if (
731+ / % [ B b m ] / . test ( ax . tickformat )
732+ // %B: full month name
733+ // %b: abbreviated month name
734+ // %m: month as a decimal number [01,12]
735+ ) definedDelta = ONEAVGMONTH ;
736+ else if (
737+ / % [ q ] / . test ( ax . tickformat )
738+ // %q: quarter of the year as a decimal number [1,4]
739+ ) definedDelta = ONEAVGQUARTER ;
740+ else if (
741+ / % [ Y y ] / . test ( ax . tickformat )
742+ // %Y: year with century as a decimal number, such as 1999
743+ // %y: year without century as a decimal number [00,99]
744+ ) definedDelta = ONEAVGYEAR ;
715745 }
716746 }
717747
@@ -748,8 +778,12 @@ axes.calcTicks = function calcTicks(ax, opts) {
748778 var delta = definedDelta || Math . abs ( B - A ) ;
749779 if ( delta >= ONEDAY * 365 ) { // Years could have days less than ONEAVGYEAR period
750780 v += ONEAVGYEAR / 2 ;
781+ } else if ( delta >= ONEAVGQUARTER ) {
782+ v += ONEAVGQUARTER / 2 ;
751783 } else if ( delta >= ONEDAY * 28 ) { // Months could have days less than ONEAVGMONTH period
752784 v += ONEAVGMONTH / 2 ;
785+ } else if ( delta >= ONEWEEK ) {
786+ v += ONEWEEK / 2 ;
753787 } else if ( delta >= ONEDAY ) {
754788 v += ONEDAY / 2 ;
755789 }
@@ -764,7 +798,7 @@ axes.calcTicks = function calcTicks(ax, opts) {
764798 }
765799
766800 if ( removedPreTick0Label ) {
767- for ( i = 1 ; i < ticksOut . length ; i ++ ) {
801+ for ( i = 0 ; i < ticksOut . length ; i ++ ) {
768802 if ( ticksOut [ i ] . periodX <= maxRange && ticksOut [ i ] . periodX >= minRange ) {
769803 // redo first visible tick
770804 ax . _prevDateHead = '' ;
@@ -882,6 +916,13 @@ axes.autoTicks = function(ax, roughDTick) {
882916 // this will also move the base tick off 2000-01-01 if dtick is
883917 // 2 or 3 days... but that's a weird enough case that we'll ignore it.
884918 ax . tick0 = Lib . dateTick0 ( ax . calendar , true ) ;
919+
920+ if ( / % [ u V W ] / . test ( ax . tickformat ) ) {
921+ // replace Sunday with Monday for ISO and Monday-based formats
922+ var len = ax . tick0 . length ;
923+ var lastD = + ax . tick0 [ len - 1 ] ;
924+ ax . tick0 = ax . tick0 . substring ( 0 , len - 2 ) + String ( lastD + 1 ) ;
925+ }
885926 } else if ( roughX2 > ONEHOUR ) {
886927 ax . dtick = roundDTick ( roughDTick , ONEHOUR , roundBase24 ) ;
887928 } else if ( roughX2 > ONEMIN ) {
0 commit comments