@@ -17,7 +17,18 @@ function getSize(_selection, _dimension) {
17
17
18
18
var FIND_TEX = / ( [ ^ $ ] * ) ( [ $ ] + [ ^ $ ] * [ $ ] + ) ( [ ^ $ ] * ) / ;
19
19
20
- exports . convertToTspans = function ( _context , gd , _callback ) {
20
+ /**
21
+ * Converts to <tspan /> SVG element.
22
+ * @param {* } _context Context
23
+ * @param {* } gd Graph DIV
24
+ * @param {* } options All props are needed to wrap.
25
+ * [axLength]?: number
26
+ * [orientation]?: 'v' | 'h'
27
+ * [wrap]?: boolean
28
+ * @param {Function } _callback Callback function.
29
+ * @returns Modified `_context`.
30
+ */
31
+ exports . convertToTspans = function ( _context , gd , options , _callback ) {
21
32
var str = _context . text ( ) ;
22
33
23
34
// Until we get tex integrated more fully (so it can be used along with non-tex)
@@ -50,7 +61,7 @@ exports.convertToTspans = function(_context, gd, _callback) {
50
61
_context . text ( '' )
51
62
. style ( 'white-space' , 'pre' ) ;
52
63
53
- var hasLink = buildSVGText ( _context . node ( ) , str ) ;
64
+ var hasLink = buildSVGText ( _context . node ( ) , str , options ) ;
54
65
55
66
if ( hasLink ) {
56
67
// at least in Chrome, pointer-events does not seem
@@ -428,24 +439,24 @@ function fromCodePoint(code) {
428
439
) ;
429
440
}
430
441
431
- /*
432
- * buildSVGText: convert our pseudo-html into SVG tspan elements, and attach these
433
- * to containerNode
442
+ /**
443
+ * Converts SVG `<tspan />` elements from pseudo-html into, and attach these to `containerNode`.
434
444
*
435
445
* @param {svg text element } containerNode: the <text> node to insert this text into
436
446
* @param {string } str: the pseudo-html string to convert to svg
437
- *
447
+ * @param { { axLength: number, axOrientation: 'v' | 'h', wrap?: boolean } } options
438
448
* @returns {bool }: does the result contain any links? We need to handle the text element
439
449
* somewhat differently if it does, so just keep track of this when it happens.
440
450
*/
441
- function buildSVGText ( containerNode , str ) {
451
+ function buildSVGText ( containerNode , str , options ) {
442
452
/*
443
453
* Normalize behavior between IE and others wrt newlines and whitespace:pre
444
454
* this combination makes IE barf https://github.com/plotly/plotly.js/issues/746
445
455
* Chrome and FF display \n, \r, or \r\n as a space in this mode.
446
456
* I feel like at some point we turned these into <br> but currently we don't so
447
457
* I'm just going to cement what we do now in Chrome and FF
448
458
*/
459
+ str = options && options . axOrientation === 'v' ? 'One very long string that is soo long, that<br>I dont get it!' : str ;
449
460
str = str . replace ( NEWLINES , ' ' ) ;
450
461
451
462
var hasLink = false ;
@@ -530,7 +541,11 @@ function buildSVGText(containerNode, str) {
530
541
}
531
542
532
543
function addTextNode ( node , text ) {
533
- node . appendChild ( document . createTextNode ( text ) ) ;
544
+ return node . appendChild ( document . createTextNode ( text ) ) ;
545
+ }
546
+
547
+ function removeTextNode ( node , child ) {
548
+ node . removeChild ( child ) ;
534
549
}
535
550
536
551
function exitNode ( type ) {
@@ -550,16 +565,19 @@ function buildSVGText(containerNode, str) {
550
565
currentNode = nodeStack [ nodeStack . length - 1 ] . node ;
551
566
}
552
567
553
- var hasLines = BR_TAG . test ( str ) ;
568
+ var hasBrLines = BR_TAG . test ( str ) ;
554
569
555
- if ( hasLines ) newLine ( ) ;
570
+ if ( hasBrLines ) newLine ( ) ;
556
571
else {
557
572
currentNode = containerNode ;
558
573
nodeStack = [ { node : containerNode } ] ;
559
574
}
560
575
561
576
var parts = str . split ( SPLIT_TAGS ) ;
562
- for ( var i = 0 ; i < parts . length ; i ++ ) {
577
+ // eslint-disable-next-line no-console
578
+ // options && options.axOrientation === 'v' && console.log(parts);
579
+ var i = 0 ;
580
+ for ( i ; i < parts . length ; i ++ ) {
563
581
var parti = parts [ i ] ;
564
582
var match = parti . match ( ONE_TAG ) ;
565
583
var tagType = match && match [ 2 ] . toLowerCase ( ) ;
@@ -568,7 +586,33 @@ function buildSVGText(containerNode, str) {
568
586
if ( tagType === 'br' ) {
569
587
newLine ( ) ;
570
588
} else if ( tagStyle === undefined ) {
571
- addTextNode ( currentNode , convertEntities ( parti ) ) ;
589
+ // addTextNode(currentNode, convertEntities(parti));
590
+
591
+ if ( options && options . axOrientation === 'v' ) {
592
+ if ( options . wrap ) {
593
+ var wordId = 0 ;
594
+ var wordsArray = parti . split ( ' ' ) ;
595
+ for ( wordId ; wordId < wordsArray . length ; wordId ++ ) {
596
+ var word = wordsArray [ wordId ] ;
597
+ var preSpace = wordId === 0 ? '' : ' ' ;
598
+ var child = addTextNode ( currentNode , convertEntities ( preSpace + word ) ) ;
599
+ if ( currentNode . getBBox ( ) . width > options . axLength ) {
600
+ removeTextNode ( currentNode , child ) ;
601
+ newLine ( ) ;
602
+ addTextNode ( currentNode , convertEntities ( word ) ) ;
603
+ }
604
+ // eslint-disable-next-line no-console
605
+ // console.log(currentNode.getBBox().width);
606
+ }
607
+
608
+ // eslint-disable-next-line no-console
609
+ // options && options.axOrientation === 'v' && console.log(currentNode.getBoundingClientRect().height);
610
+ // eslint-disable-next-line no-console
611
+ // options && options.axOrientation === 'v' && console.log(currentNode.getBBox().width);
612
+ } else {
613
+ addTextNode ( currentNode , convertEntities ( parti ) ) ;
614
+ }
615
+ }
572
616
} else {
573
617
// tag - open or close
574
618
if ( match [ 1 ] ) {
0 commit comments