@@ -50,6 +50,48 @@ module.exports = function draw(gd) {
50
50
} ;
51
51
52
52
53
+ // Images must be converted to dataURL's for exporting.
54
+ function setImage ( d ) {
55
+
56
+ var thisImage = d3 . select ( this ) ;
57
+
58
+ var imagePromise = new Promise ( function ( resolve ) {
59
+
60
+ var img = new Image ( ) ;
61
+
62
+ // If not set, a `tainted canvas` error is thrown
63
+ img . setAttribute ( 'crossOrigin' , 'anonymous' ) ;
64
+ img . onerror = errorHandler ;
65
+ img . onload = function ( ) {
66
+
67
+ var canvas = document . createElement ( 'canvas' ) ;
68
+ canvas . width = this . width ;
69
+ canvas . height = this . height ;
70
+
71
+ var ctx = canvas . getContext ( '2d' ) ;
72
+ ctx . drawImage ( this , 0 , 0 ) ;
73
+
74
+ var dataURL = canvas . toDataURL ( 'image/png' ) ;
75
+
76
+ thisImage . attr ( 'xlink:href' , dataURL ) ;
77
+ } ;
78
+
79
+
80
+ thisImage . on ( 'error' , errorHandler ) ;
81
+ thisImage . on ( 'load' , resolve ) ;
82
+
83
+ img . src = d . source ;
84
+
85
+ function errorHandler ( ) {
86
+ thisImage . remove ( ) ;
87
+ resolve ( ) ;
88
+ }
89
+ } ) ;
90
+
91
+ gd . _promises . push ( imagePromise ) ;
92
+ }
93
+
94
+
53
95
function applyAttributes ( d ) {
54
96
55
97
var thisImage = d3 . select ( this ) ;
@@ -59,8 +101,6 @@ module.exports = function draw(gd) {
59
101
yref = Axes . getFromId ( gd , d . yref ) ;
60
102
61
103
var size = fullLayout . _size ,
62
- width = xref ? Math . abs ( xref . l2p ( d . width ) - xref . l2p ( 0 ) ) : d . width * size . w ,
63
- height = yref ? Math . abs ( yref . l2p ( d . height ) - yref . l2p ( 0 ) ) : d . width * size . h ;
64
104
width = xref ? Math . abs ( xref . l2p ( d . sizex ) - xref . l2p ( 0 ) ) : d . sizex * size . w ,
65
105
height = yref ? Math . abs ( yref . l2p ( d . sizey ) - yref . l2p ( 0 ) ) : d . sizey * size . h ;
66
106
@@ -96,22 +136,6 @@ module.exports = function draw(gd) {
96
136
} ) ;
97
137
98
138
99
- // Images load async so we must add the promise to the list
100
- var imagePromise = new Promise ( function ( resolve ) {
101
-
102
- thisImage . on ( 'load' , resolve ) ;
103
- thisImage . on ( 'error' , function ( ) {
104
- thisImage . remove ( ) ;
105
- console . log ( 'Image with source ' + d . source + ' could not be loaded.' ) ;
106
- resolve ( ) ;
107
- } ) ;
108
-
109
- thisImage . attr ( 'href' , d . source ) ;
110
- } ) ;
111
-
112
- gd . _promises . push ( imagePromise ) ;
113
-
114
-
115
139
// Set proper clipping on images
116
140
var xId = xref ? xref . _id : '' ,
117
141
yId = yref ? yref . _id : '' ,
@@ -121,16 +145,22 @@ module.exports = function draw(gd) {
121
145
}
122
146
123
147
148
+ // Required for updating images
149
+ function keyFunction ( d ) {
150
+ return d . source ;
151
+ }
152
+
153
+
124
154
var imagesBelow = fullLayout . _imageLowerLayer . selectAll ( 'image' )
125
- . data ( imageDataBelow ) ,
155
+ . data ( imageDataBelow , keyFunction ) ,
126
156
imagesSubplot = fullLayout . _imageSubplotLayer . selectAll ( 'image' )
127
- . data ( imageDataSubplot ) ,
157
+ . data ( imageDataSubplot , keyFunction ) ,
128
158
imagesAbove = fullLayout . _imageUpperLayer . selectAll ( 'image' )
129
- . data ( imageDataAbove ) ;
159
+ . data ( imageDataAbove , keyFunction ) ;
130
160
131
- imagesBelow . enter ( ) . append ( 'image' ) ;
132
- imagesSubplot . enter ( ) . append ( 'image' ) ;
133
- imagesAbove . enter ( ) . append ( 'image' ) ;
161
+ imagesBelow . enter ( ) . append ( 'image' ) . each ( setImage ) ;
162
+ imagesSubplot . enter ( ) . append ( 'image' ) . each ( setImage ) ;
163
+ imagesAbove . enter ( ) . append ( 'image' ) . each ( setImage ) ;
134
164
135
165
imagesBelow . exit ( ) . remove ( ) ;
136
166
imagesSubplot . exit ( ) . remove ( ) ;
0 commit comments