1/** 2 * PanoramicData.ECharts - Blazor wrapper for Apache ECharts 3 * JavaScript interop layer 4 */ 5window.panoramicDataECharts = { 6 7 charts: new Map(), 8 dataSources: new Map(), 9 10 logging: false, 11 12 changeLogging: function (b) { 13 panoramicDataECharts.logging = b; 14 }, 15 16 getChart: function (id) { 17 return panoramicDataECharts.charts.get(id); 18 }, 19 20 getDataSource: function (fetchId) { 21 var data = panoramicDataECharts.dataSources.get(fetchId); 22 23 if (panoramicDataECharts.logging) { 24 console.log(`GET CACHED FETCH ${fetchId}`); 25 console.log(data); 26 } 27 28 return data; 29 }, 30 31 evaluatePath: function (data, pathExpression) { 32 const pathSegments = pathExpression.split('.'); 33 let currentObj = data; 34 35 for (const segment of pathSegments) { 36 if (!currentObj.hasOwnProperty(segment)) { 37 return undefined; // Property not found, return undefined 38 } 39 currentObj = currentObj[segment]; 40 } 41 42 return currentObj; 43 }, 44 45 fetchExternalData: async function (chart, fetchOptions) { 46 if (fetchOptions == null) 47 return; 48 49 chart.__dataSources = []; 50 51 for (item of JSON.parse(fetchOptions)) { 52 if (panoramicDataECharts.logging) { 53 console.log(`FETCH ${item.id}`); 54 console.log(item); 55 } 56 57 const response = await fetch(item.url, item.options); 58 if (!response.ok) { 59 throw new Error('Failed to fetch external chart data: url=' + url); 60 } 61 62 // parse the response as JSON 63 var data = null; 64 if (item.fetchAs == "json") { 65 data = await response.json(); 66 67 // replace the object with the fetched data 68 if (item.path != null) { 69 try { 70 data = panoramicDataECharts.evaluatePath(data, item.path); 71 } catch (error) { 72 console.log('Failed to evaluate path expression of external data source'); 73 console.log(error); 74 } 75 } 76 } else if (item.fetchAs == "string") { 77 data = await response.text(); 78 } 79 80 if (panoramicDataECharts.logging) { 81 console.log(data); 82 } 83 84 // execute the afterLoad function if required 85 if (item.afterLoad != null) { 86 try { 87 const func = eval(`(${item.afterLoad})`) 88 data = func(data); 89 } catch (error) { 90 console.log('Failed to execute afterLoad function of external data source'); 91 console.log(error); 92 } 93 } 94 95 // store in the datasources map for later retrieval 96 window.panoramicDataECharts.dataSources.set(item.id, data); 97 98 // add reference inside the chart, so we can cleanup later 99 chart.__dataSources.push(item.id); 100 } 101 }, 102 103 registerMaps: function (chart, mapOptions) { 104 if (mapOptions == null) 105 return; 106 107 var parsedOptions = eval('(' + mapOptions + ')'); 108 for (item of parsedOptions) { 109 if (panoramicDataECharts.logging) { 110 console.log("MAP"); 111 console.log(item); 112 } 113 114 if (item.type === "geoJSON") { 115 echarts.registerMap(item.mapName, { geoJSON: item.geoJSON, specialAreas: item.specialAreas }); 116 } else if (item.type === "svg") { 117 echarts.registerMap(item.mapName, { svg: item.svg }); 118 } 119 } 120 }, 121 122 initChart: async function (id, theme, initOptions, chartOptions, mapOptions, fetchOptions) { 123 var chart = echarts.init(document.getElementById(id), theme, JSON.parse(initOptions)); 124 panoramicDataECharts.charts.set(id, chart); 125 126 // show loading animation 127 chart.showLoading(); 128 129 if (chartOptions == null) 130 return; 131 132 // fetch external data if needed 133 await panoramicDataECharts.fetchExternalData(chart, fetchOptions); 134 135 // register GEO maps 136 await panoramicDataECharts.registerMaps(chart, mapOptions); 137 138 // parse the options using eval to support JavaScript functions 139 var parsedOptions = eval('(' + chartOptions + ')'); 140 141 if (panoramicDataECharts.logging) { 142 console.log("CHART"); 143 console.log(parsedOptions); 144 } 145 146 // set the chart options 147 chart.setOption(parsedOptions); 148 149 // schedule resize after current call stack so the browser has time to compute layout 150 setTimeout(() => { var c = panoramicDataECharts.charts.get(id); if (c) c.resize(); }, 0); 151 152 // hide the loading animation immediately 153 chart.hideLoading(); 154 }, 155 156 updateChart: async function (id, chartOptions, mapOptions, fetchOptions) { 157 var chart = panoramicDataECharts.charts.get(id); 158 if (chart == null) { 159 console.error("Failed to retrieve chart " + id); 160 return; 161 } 162 163 // fetch external data if needed 164 await panoramicDataECharts.fetchExternalData(chart, fetchOptions); 165 166 // register GEO maps 167 await panoramicDataECharts.registerMaps(chart, mapOptions); 168
169 // parse the options using eval to support JavaScript functions 170 var parsedOptions = eval('(' + chartOptions + ')'); 171 172 // resize before setting options so container dimensions are correct when animations play 173 chart.resize(); 174 175 // set the chart options 176 chart.setOption(parsedOptions); 177 178 // hide the loading animation 179 chart.hideLoading(); 180 }, 181 182 clearChart: function (id) { 183 var chart = panoramicDataECharts.charts.get(id); 184 if (chart == null) { 185 console.error("Failed to clear chart " + id); 186 return; 187 } 188 189 chart.clear(); 190 }, 191 192 disposeChart: function (id) { 193 var chart = panoramicDataECharts.charts.get(id); 194 if (chart == null) { 195 console.error("Failed to dispose chart " + id); 196 return; 197 } 198 199 // dispose of all dataSources linked to the chart 200 if (chart.__dataSources && Array.isArray(chart.__dataSources)) { 201 chart.__dataSources.forEach(id => { 202 window.panoramicDataECharts.dataSources.delete(id); 203 }); 204 } 205 206 echarts.dispose(chart) 207 panoramicDataECharts.charts.delete(id); 208 } 209};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.