Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Open sidebar
MUR Drupal
d3-library
Commits
4adb0c24
Commit
4adb0c24
authored
Apr 05, 2014
by
Mike Bostock
Browse files
Optimize interpolateString.
parent
fa55eead
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
73 additions
and
131 deletions
+73
-131
d3.js
d3.js
+24
-57
d3.min.js
d3.min.js
+5
-5
src/interpolate/string.js
src/interpolate/string.js
+35
-69
test/interpolate/string-test.js
test/interpolate/string-test.js
+9
-0
No files found.
d3.js
View file @
4adb0c24
...
...
@@ -5617,71 +5617,38 @@
}
d3
.
interpolateString
=
d3_interpolateString
;
function
d3_interpolateString
(
a
,
b
)
{
var
m
,
i
,
j
,
s0
=
0
,
s1
=
0
,
s
=
[],
q
=
[]
,
n
,
o
;
var
bi
=
d3_interpolate_numberA
.
lastIndex
=
d3_interpolate_numberB
.
lastIndex
=
0
,
am
,
bm
,
bs
,
i
=
-
1
,
s
=
[],
q
=
[];
a
=
a
+
""
,
b
=
b
+
""
;
d3_interpolate_number
.
lastIndex
=
0
;
for
(
i
=
0
;
m
=
d3_interpolate_number
.
exec
(
b
);
++
i
)
{
if
(
m
.
index
)
s
.
push
(
b
.
substring
(
s0
,
s1
=
m
.
index
));
q
.
push
({
i
:
s
.
length
,
x
:
m
[
0
]
});
s
.
push
(
null
);
s0
=
d3_interpolate_number
.
lastIndex
;
}
if
(
s0
<
b
.
length
)
s
.
push
(
b
.
substring
(
s0
));
for
(
i
=
0
,
n
=
q
.
length
;
(
m
=
d3_interpolate_number
.
exec
(
a
))
&&
i
<
n
;
++
i
)
{
o
=
q
[
i
];
if
(
o
.
x
==
m
[
0
])
{
if
(
o
.
i
)
{
if
(
s
[
o
.
i
+
1
]
==
null
)
{
s
[
o
.
i
-
1
]
+=
o
.
x
;
s
.
splice
(
o
.
i
,
1
);
for
(
j
=
i
+
1
;
j
<
n
;
++
j
)
q
[
j
].
i
--
;
}
else
{
s
[
o
.
i
-
1
]
+=
o
.
x
+
s
[
o
.
i
+
1
];
s
.
splice
(
o
.
i
,
2
);
for
(
j
=
i
+
1
;
j
<
n
;
++
j
)
q
[
j
].
i
-=
2
;
}
}
else
{
if
(
s
[
o
.
i
+
1
]
==
null
)
{
s
[
o
.
i
]
=
o
.
x
;
}
else
{
s
[
o
.
i
]
=
o
.
x
+
s
[
o
.
i
+
1
];
s
.
splice
(
o
.
i
+
1
,
1
);
for
(
j
=
i
+
1
;
j
<
n
;
++
j
)
q
[
j
].
i
--
;
}
}
q
.
splice
(
i
,
1
);
n
--
;
i
--
;
}
else
{
o
.
x
=
d3_interpolateNumber
(
parseFloat
(
m
[
0
]),
parseFloat
(
o
.
x
));
while
((
am
=
d3_interpolate_numberA
.
exec
(
a
))
&&
(
bm
=
d3_interpolate_numberB
.
exec
(
b
)))
{
if
((
bs
=
bm
.
index
)
>
bi
)
{
bs
=
b
.
substring
(
bi
,
bs
);
if
(
s
[
i
])
s
[
i
]
+=
bs
;
else
s
[
++
i
]
=
bs
;
}
}
while
(
i
<
n
)
{
o
=
q
.
pop
();
if
(
s
[
o
.
i
+
1
]
==
null
)
{
s
[
o
.
i
]
=
o
.
x
;
if
((
am
=
+
am
[
0
])
===
(
bm
=
+
(
bs
=
bm
[
0
])))
{
if
(
s
[
i
])
s
[
i
]
+=
bs
;
else
s
[
++
i
]
=
bs
;
}
else
{
s
[
o
.
i
]
=
o
.
x
+
s
[
o
.
i
+
1
];
s
.
splice
(
o
.
i
+
1
,
1
);
s
[
++
i
]
=
null
;
q
.
push
({
i
:
i
,
x
:
d3_interpolateNumber
(
am
,
bm
)
});
}
n
--
;
bi
=
d3_interpolate_numberB
.
lastIndex
;
}
if
(
s
.
length
===
1
)
{
return
s
[
0
]
==
null
?
(
o
=
q
[
0
].
x
,
function
(
t
)
{
return
o
(
t
)
+
""
;
})
:
function
()
{
return
b
;
};
if
(
bi
<
b
.
length
)
{
bs
=
b
.
substring
(
bi
);
if
(
s
[
i
])
s
[
i
]
+=
bs
;
else
s
[
++
i
]
=
bs
;
}
return
function
(
t
)
{
for
(
i
=
0
;
i
<
n
;
++
i
)
s
[(
o
=
q
[
i
]).
i
]
=
o
.
x
(
t
);
return
s
.
length
<
2
?
q
[
0
]
?
(
b
=
q
[
0
].
x
,
function
(
t
)
{
return
b
(
t
)
+
""
;
})
:
function
()
{
return
b
;
}
:
(
b
=
q
.
length
,
function
(
t
)
{
for
(
var
i
=
0
,
o
;
i
<
b
;
++
i
)
s
[(
o
=
q
[
i
]).
i
]
=
o
.
x
(
t
);
return
s
.
join
(
""
);
};
}
)
;
}
var
d3_interpolate_number
=
/
[
-+
]?(?:\d
+
\.?\d
*|
\.?\d
+
)(?:[
eE
][
-+
]?\d
+
)?
/g
;
var
d3_interpolate_number
A
=
/
[
-+
]?(?:\d
+
\.?\d
*|
\.?\d
+
)(?:[
eE
][
-+
]?\d
+
)?
/g
,
d3_interpolate_numberB
=
new
RegExp
(
d3_interpolate_numberA
.
source
,
"
g
"
)
;
d3
.
interpolate
=
d3_interpolate
;
function
d3_interpolate
(
a
,
b
)
{
var
i
=
d3
.
interpolators
.
length
,
f
;
...
...
d3.min.js
View file @
4adb0c24
This source diff could not be displayed because it is too large. You can
view the blob
instead.
src/interpolate/string.js
View file @
4adb0c24
...
...
@@ -3,86 +3,52 @@ import "number";
d3
.
interpolateString
=
d3_interpolateString
;
function
d3_interpolateString
(
a
,
b
)
{
var
m
,
// current match
i
,
// current
index
j
,
// current
index (for coalescing)
s
0
=
0
,
// st
art index of current string prefix
s1
=
0
,
//
end
index
of current string prefix
var
bi
=
d3_interpolate_numberA
.
lastIndex
=
d3_interpolate_numberB
.
lastIndex
=
0
,
// scan index for next number in b
am
,
// current
match in a
bm
,
// current
match in b
b
s
,
// st
ring preceding current number in b, if any
i
=
-
1
,
// index
in s
s
=
[],
// string constants and placeholders
q
=
[],
// number interpolators
n
,
// q.length
o
;
q
=
[];
// number interpolators
// Coerce inputs to strings.
a
=
a
+
""
,
b
=
b
+
""
;
// Reset our regular expression!
d3_interpolate_number
.
lastIndex
=
0
;
// Find all numbers in b.
for
(
i
=
0
;
m
=
d3_interpolate_number
.
exec
(
b
);
++
i
)
{
if
(
m
.
index
)
s
.
push
(
b
.
substring
(
s0
,
s1
=
m
.
index
));
q
.
push
({
i
:
s
.
length
,
x
:
m
[
0
]});
s
.
push
(
null
);
s0
=
d3_interpolate_number
.
lastIndex
;
}
if
(
s0
<
b
.
length
)
s
.
push
(
b
.
substring
(
s0
));
// Find all numbers in a.
for
(
i
=
0
,
n
=
q
.
length
;
(
m
=
d3_interpolate_number
.
exec
(
a
))
&&
i
<
n
;
++
i
)
{
o
=
q
[
i
];
if
(
o
.
x
==
m
[
0
])
{
// The numbers match, so coalesce.
if
(
o
.
i
)
{
if
(
s
[
o
.
i
+
1
]
==
null
)
{
// This match is followed by another number.
s
[
o
.
i
-
1
]
+=
o
.
x
;
s
.
splice
(
o
.
i
,
1
);
for
(
j
=
i
+
1
;
j
<
n
;
++
j
)
q
[
j
].
i
--
;
}
else
{
// This match is followed by a string, so coalesce twice.
s
[
o
.
i
-
1
]
+=
o
.
x
+
s
[
o
.
i
+
1
];
s
.
splice
(
o
.
i
,
2
);
for
(
j
=
i
+
1
;
j
<
n
;
++
j
)
q
[
j
].
i
-=
2
;
}
}
else
{
if
(
s
[
o
.
i
+
1
]
==
null
)
{
// This match is followed by another number.
s
[
o
.
i
]
=
o
.
x
;
}
else
{
// This match is followed by a string, so coalesce twice.
s
[
o
.
i
]
=
o
.
x
+
s
[
o
.
i
+
1
];
s
.
splice
(
o
.
i
+
1
,
1
);
for
(
j
=
i
+
1
;
j
<
n
;
++
j
)
q
[
j
].
i
--
;
}
}
q
.
splice
(
i
,
1
);
n
--
;
i
--
;
}
else
{
o
.
x
=
d3_interpolateNumber
(
parseFloat
(
m
[
0
]),
parseFloat
(
o
.
x
));
// Interpolate pairs of numbers in a & b.
while
((
am
=
d3_interpolate_numberA
.
exec
(
a
))
&&
(
bm
=
d3_interpolate_numberB
.
exec
(
b
)))
{
if
((
bs
=
bm
.
index
)
>
bi
)
{
// a string precedes the next number in b
bs
=
b
.
substring
(
bi
,
bs
);
if
(
s
[
i
])
s
[
i
]
+=
bs
;
// coalesce with previous string
else
s
[
++
i
]
=
bs
;
}
}
// Remove any numbers in b not found in a.
while
(
i
<
n
)
{
o
=
q
.
pop
();
if
(
s
[
o
.
i
+
1
]
==
null
)
{
// This match is followed by another number.
s
[
o
.
i
]
=
o
.
x
;
}
else
{
// This match is followed by a string, so coalesce twice.
s
[
o
.
i
]
=
o
.
x
+
s
[
o
.
i
+
1
];
s
.
splice
(
o
.
i
+
1
,
1
);
if
((
am
=
+
am
[
0
])
===
(
bm
=
+
(
bs
=
bm
[
0
])))
{
// coalesce matching numbers
if
(
s
[
i
])
s
[
i
]
+=
bs
;
// coalesce with previous string
else
s
[
++
i
]
=
bs
;
}
else
{
// interpolate non-matching numbers
s
[
++
i
]
=
null
;
q
.
push
({
i
:
i
,
x
:
d3_interpolateNumber
(
am
,
bm
)});
}
n
--
;
bi
=
d3_interpolate_numberB
.
lastIndex
;
}
//
Special optimization for only a single match
.
if
(
s
.
length
===
1
)
{
return
s
[
0
]
==
null
?
(
o
=
q
[
0
].
x
,
function
(
t
)
{
return
o
(
t
)
+
""
;
})
:
function
()
{
return
b
;
}
;
//
Add remains of b
.
if
(
bi
<
b
.
length
)
{
bs
=
b
.
substring
(
bi
);
if
(
s
[
i
])
s
[
i
]
+=
bs
;
// coalesce with previous string
else
s
[
++
i
]
=
bs
;
}
// Special optimization for only a single match.
// Otherwise, interpolate each of the numbers and rejoin the string.
return
function
(
t
)
{
for
(
i
=
0
;
i
<
n
;
++
i
)
s
[(
o
=
q
[
i
]).
i
]
=
o
.
x
(
t
);
return
s
.
join
(
""
);
};
return
s
.
length
<
2
?
(
q
[
0
]
?
(
b
=
q
[
0
].
x
,
function
(
t
)
{
return
b
(
t
)
+
""
;
})
:
function
()
{
return
b
;
})
:
(
b
=
q
.
length
,
function
(
t
)
{
for
(
var
i
=
0
,
o
;
i
<
b
;
++
i
)
s
[(
o
=
q
[
i
]).
i
]
=
o
.
x
(
t
);
return
s
.
join
(
""
);
});
}
var
d3_interpolate_number
=
/
[
-+
]?(?:\d
+
\.?\d
*|
\.?\d
+
)(?:[
eE
][
-+
]?\d
+
)?
/g
;
var
d3_interpolate_numberA
=
/
[
-+
]?(?:\d
+
\.?\d
*|
\.?\d
+
)(?:[
eE
][
-+
]?\d
+
)?
/g
,
d3_interpolate_numberB
=
new
RegExp
(
d3_interpolate_numberA
.
source
,
"
g
"
);
test/interpolate/string-test.js
View file @
4adb0c24
...
...
@@ -36,6 +36,15 @@ suite.addBatch({
assert
.
strictEqual
(
interpolate
(
"
-1.e-3
"
,
"
-1.e-4
"
)(.
5
),
"
-0.00055
"
);
assert
.
strictEqual
(
interpolate
(
"
+1.e-3
"
,
"
+1.e-4
"
)(.
5
),
"
0.00055
"
);
assert
.
strictEqual
(
interpolate
(
"
.1e-2
"
,
"
.1e-3
"
)(.
5
),
"
0.00055
"
);
},
"
with no numbers, returns the target string
"
:
function
(
interpolate
)
{
assert
.
strictEqual
(
interpolate
(
"
foo
"
,
"
bar
"
)(.
5
),
"
bar
"
);
assert
.
strictEqual
(
interpolate
(
"
foo
"
,
""
)(.
5
),
""
);
assert
.
strictEqual
(
interpolate
(
""
,
"
bar
"
)(.
5
),
"
bar
"
);
assert
.
strictEqual
(
interpolate
(
""
,
""
)(.
5
),
""
);
},
"
with two numerically-equivalent numbers, returns the target format
"
:
function
(
interpolate
)
{
assert
.
strictEqual
(
interpolate
(
"
top: 1000px;
"
,
"
top: 1e3px;
"
)(.
5
),
"
top: 1e3px;
"
);
}
}
});
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment