@@ -1122,24 +1122,26 @@ var TEMPLATE_STRING_FORMAT_SEPARATOR = /^[:|\|]/;
11221122 * @param {object } options.labels - Data object containing fallback text when no formatting is specified, ex.: {yLabel: 'formattedYValue'}
11231123 * @param {object } options.locale - D3 locale for formatting
11241124 * @param {object } options.opts - Additional options
1125- * @param {string } options.template - Input string containing %{...:...} template strings
1125+ * @param {number } options.opts.count - Count of warnings for missing values
1126+ * @param {number } options.opts.max - Maximum allowed count of warnings for missing values before suppressing the warning message
1127+ * @param {string } options.opts.name - Template name, used in warning message
1128+ * @param {boolean } options.opts.parseMultDiv - Parse * and / operators in template string (used in shape labels)
1129+ * @param {string } options.template - Input string containing %{...:...} template string specifiers
11261130 *
11271131 * @return {string } templated string
11281132 */
11291133function templateFormatString ( { data = [ ] , locale, fallback, labels = { } , opts, template } ) {
1130- return template . 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 ) ;
1134+ return template . replace ( lib . TEMPLATE_STRING_REGEX , ( match , key , format ) => {
1135+ const isOther = [ 'xother' , 'yother' ] . includes ( key ) ;
1136+ const isSpaceOther = [ '_xother' , '_yother' ] . includes ( key ) ;
1137+ const isSpaceOtherSpace = [ '_xother_' , '_yother_' ] . includes ( key ) ;
1138+ const isOtherSpace = [ 'xother_' , 'yother_' ] . includes ( key ) ;
11351139 const hasOther = isOther || isSpaceOther || isOtherSpace || isSpaceOtherSpace ;
11361140
1137- let key = rawKey ;
1141+ // Remove underscores from key
11381142 if ( isSpaceOther || isSpaceOtherSpace ) key = key . substring ( 1 ) ;
11391143 if ( isOtherSpace || isSpaceOtherSpace ) key = key . substring ( 0 , key . length - 1 ) ;
11401144
1141- // Shape labels support * and / operators in template string
1142- // Parse these if the parseMultDiv param is set to true
11431145 let parsedOp = null ;
11441146 let parsedNumber = null ;
11451147 if ( opts . parseMultDiv ) {
@@ -1149,32 +1151,46 @@ function templateFormatString({ data = [], locale, fallback, labels = {}, opts,
11491151 parsedNumber = _match . number ;
11501152 }
11511153
1152- let value ;
1154+ let keyIsMissing = true ;
1155+ let value = undefined ;
11531156 if ( hasOther ) {
1157+ // 'other' specifiers that are undefined return an empty string by design
11541158 if ( labels [ key ] === undefined ) return '' ;
11551159 value = labels [ key ] ;
1160+ keyIsMissing = false ;
11561161 } else {
11571162 for ( const obj of data ) {
11581163 if ( ! obj ) continue ;
11591164 if ( obj . hasOwnProperty ( key ) ) {
11601165 value = obj [ key ] ;
1166+ keyIsMissing = false ;
11611167 break ;
11621168 }
11631169
11641170 if ( ! SIMPLE_PROPERTY_REGEX . test ( key ) ) {
11651171 // true here means don't convert null to undefined
11661172 value = lib . nestedProperty ( obj , key ) . get ( true ) ;
1173+ keyIsMissing = false ;
11671174 }
11681175 if ( value !== undefined ) break ;
11691176 }
11701177 }
11711178
1172- if ( value === undefined ) {
1179+ if ( keyIsMissing ) {
11731180 const { count, max, name } = opts ;
1174- if ( count < max ) lib . warn ( `Variable '${ key } ' in ${ name } could not be found! Using fallback value.` ) ;
1175- if ( count === max ) lib . warn ( `Too many '${ name } ' warnings - additional warnings will be suppressed` ) ;
1181+ if ( count < max )
1182+ lib . warn (
1183+ [
1184+ `Variable '${ key } ' in ${ name } could not be found!` ,
1185+ 'Please verify that the template is correct.'
1186+ ] . join ( ' ' )
1187+ ) ;
1188+ if ( count === max ) lib . warn ( `Too many '${ name } ' warnings - additional warnings will be suppressed.` ) ;
11761189 opts . count ++ ;
11771190
1191+ return match ;
1192+ } else if ( value === undefined ) {
1193+ // In this case, the actual value in the data set is 'undefined', so use fallback without warning
11781194 return fallback ;
11791195 }
11801196
0 commit comments