@@ -1074,23 +1074,19 @@ lib.templateString = function (string, obj) {
10741074 } ) ;
10751075} ;
10761076
1077- var hovertemplateWarnings = {
1077+ const hovertemplateWarnings = {
10781078 max : 10 ,
10791079 count : 0 ,
10801080 name : 'hovertemplate'
10811081} ;
1082- lib . hovertemplateString = function ( ) {
1083- return templateFormatString . apply ( hovertemplateWarnings , arguments ) ;
1084- } ;
1082+ lib . hovertemplateString = ( params ) => templateFormatString ( { ...params , opts : hovertemplateWarnings } ) ;
10851083
1086- var texttemplateWarnings = {
1084+ const texttemplateWarnings = {
10871085 max : 10 ,
10881086 count : 0 ,
10891087 name : 'texttemplate'
10901088} ;
1091- lib . texttemplateString = function ( ) {
1092- return templateFormatString . apply ( texttemplateWarnings , arguments ) ;
1093- } ;
1089+ lib . texttemplateString = ( params ) => templateFormatString ( { ...params , opts : texttemplateWarnings } ) ;
10941090
10951091// Regex for parsing multiplication and division operations applied to a template key
10961092// Used for shape.label.texttemplate
@@ -1108,66 +1104,57 @@ var texttemplateWarningsForShapes = {
11081104 name : 'texttemplate' ,
11091105 parseMultDiv : true
11101106} ;
1111- lib . texttemplateStringForShapes = function ( ) {
1112- return templateFormatString . apply ( texttemplateWarningsForShapes , arguments ) ;
1113- } ;
1107+ lib . texttemplateStringForShapes = ( params ) => templateFormatString ( { ...params , opts : texttemplateWarningsForShapes } ) ;
11141108
11151109var TEMPLATE_STRING_FORMAT_SEPARATOR = / ^ [: | \| ] / ;
11161110/**
11171111 * Substitute values from an object into a string and optionally formats them using d3-format,
11181112 * or fallback to associated labels.
11191113 *
11201114 * Examples:
1121- * Lib.hovertemplateString('name: %{trace}', {trace: 'asdf'}) --> 'name: asdf'
1122- * Lib.hovertemplateString('name: %{trace[0].name}', { trace: [{name: 'asdf'}] }) --> 'name: asdf'
1123- * Lib.hovertemplateString('price: %{y:$.2f}', { y: 1}) --> 'price: $1.00'
1115+ * Lib.hovertemplateString({ string 'name: %{trace}', labels: {trace: 'asdf'} }) --> 'name: asdf'
1116+ * Lib.hovertemplateString({ string: 'name: %{trace[0].name}', labels: { trace: [{ name: 'asdf' }] } }) --> 'name: asdf'
1117+ * Lib.hovertemplateString({ string: 'price: %{y:$.2f}', labels: { y: 1 } }) --> 'price: $1.00'
11241118 *
1125- * @param {string } input string containing %{...:...} template strings
1126- * @param {obj } data object containing fallback text when no formatting is specified, ex.: {yLabel: 'formattedYValue'}
1127- * @param {obj } d3 locale
1128- * @param {obj } data objects containing substitution values
1119+ * @param {object } options - Configuration object
1120+ * @param {array } options.args - Data objects containing substitution values
1121+ * @param {object } options.d3locale - D3 locale for formatting
1122+ * @param {string } options.fallback - Fallback value when substitution fails
1123+ * @param {object } options.labels - Data object containing fallback text when no formatting is specified, ex.: {yLabel: 'formattedYValue'}
1124+ * @param {object } options.opts - Additional options
1125+ * @param {string } options.string - Input string containing %{...:...} template strings
11291126 *
11301127 * @return {string } templated string
11311128 */
1132- function templateFormatString ( string , labels , d3locale ) {
1133- var opts = this ;
1134- var args = arguments ;
1135- if ( ! labels ) labels = { } ;
1136-
1137- return string . replace ( lib . TEMPLATE_STRING_REGEX , function ( match , rawKey , format ) {
1138- var isOther = rawKey === 'xother' || rawKey === 'yother' ;
1139-
1140- var isSpaceOther = rawKey === '_xother' || rawKey === '_yother' ;
1141-
1142- var isSpaceOtherSpace = rawKey === '_xother_' || rawKey === '_yother_' ;
1143-
1144- var isOtherSpace = rawKey === 'xother_' || rawKey === 'yother_' ;
1145-
1146- var hasOther = isOther || isSpaceOther || isOtherSpace || isSpaceOtherSpace ;
1147-
1148- var key = rawKey ;
1129+ function templateFormatString ( { args = [ ] , d3locale, fallback, labels = { } , opts, string } ) {
1130+ return string . replace ( lib . TEMPLATE_STRING_REGEX , ( _ , rawKey , format ) => {
1131+ const isOther = [ 'xother' , 'yother' ] . includes ( rawKey ) ;
1132+ const isSpaceOther = [ '_xother' , '_yother' ] . includes ( rawKey ) ;
1133+ const isSpaceOtherSpace = [ '_xother_' , '_yother_' ] . includes ( rawKey ) ;
1134+ const isOtherSpace = [ 'xother_' , 'yother_' ] . includes ( rawKey ) ;
1135+ const hasOther = isOther || isSpaceOther || isOtherSpace || isSpaceOtherSpace ;
1136+
1137+ let key = rawKey ;
11491138 if ( isSpaceOther || isSpaceOtherSpace ) key = key . substring ( 1 ) ;
11501139 if ( isOtherSpace || isSpaceOtherSpace ) key = key . substring ( 0 , key . length - 1 ) ;
11511140
11521141 // Shape labels support * and / operators in template string
11531142 // Parse these if the parseMultDiv param is set to true
1154- var parsedOp = null ;
1155- var parsedNumber = null ;
1143+ let parsedOp = null ;
1144+ let parsedNumber = null ;
11561145 if ( opts . parseMultDiv ) {
11571146 var _match = multDivParser ( key ) ;
11581147 key = _match . key ;
11591148 parsedOp = _match . op ;
11601149 parsedNumber = _match . number ;
11611150 }
11621151
1163- var value ;
1152+ let value ;
11641153 if ( hasOther ) {
1154+ if ( labels [ key ] === undefined ) return '' ;
11651155 value = labels [ key ] ;
1166- if ( value === undefined ) return '' ;
11671156 } else {
1168- var obj , i ;
1169- for ( i = 3 ; i < args . length ; i ++ ) {
1170- obj = args [ i ] ;
1157+ for ( const obj of args ) {
11711158 if ( ! obj ) continue ;
11721159 if ( obj . hasOwnProperty ( key ) ) {
11731160 value = obj [ key ] ;
@@ -1184,12 +1171,11 @@ function templateFormatString(string, labels, d3locale) {
11841171
11851172 if ( value === undefined ) {
11861173 const { count, max, name } = opts ;
1187- if ( count < max ) lib . warn ( `Variable '${ key } ' in ${ name } could not be found!` ) ;
1174+ if ( count < max ) lib . warn ( `Variable '${ key } ' in ${ name } could not be found! Using fallback value. ` ) ;
11881175 if ( count === max ) lib . warn ( `Too many '${ name } ' warnings - additional warnings will be suppressed` ) ;
11891176 opts . count ++ ;
11901177
1191- // TODO: Make return valuable configurable with a reasonable default (like 'N/A')
1192- return '' ;
1178+ return fallback ;
11931179 }
11941180
11951181 if ( parsedOp === '*' ) value *= parsedNumber ;
0 commit comments