我正在使用由 https://azgaar.github.io/Fantasy-Map-Generator/ 创建的地图的修改版本作为Angular(9)模板svg。该文件的长度为12,000行,因此大大降低了编译速度。枚举所有5248个网格单元(按快捷键e在链接的地图上显示)并对每个单元设置id时,我的性能进一步下降。不幸的是,这对于我的用例是必需的。
由于该地图具有12种不同的叠加组(PE城市,湖泊,路线,海岸线),并且一次都不需要,因此我认为我可以将此.svg精简为最小的骨架,并要求使用不同的元素一旦用户选择通过REST进行访问。
以下内容将在模板中添加正确的行(与从原始svg中裁剪出来的完全一样)。但是,该小组不会出现。我需要重新渲染整个SVG吗?我该怎么办?
public async toggleVisibility(elementToDisplay): void {
try {
// if elementToDisplay already is part of the .svg, set it visible / invisible here
} catch(_) {
this._http.get<string>(`${environment.backend}/worldmap/data/${elementToDisplay}`, { headers: new HttpHeaders({ 'Content-Type': 'application/json' }) }).toPromise()
.then((res: string) => {
// as an unrelated issue: my spring application is returning a String, yet angular would not resolve this promise
}.catch((rej: any) => {
const parser = new DOMParser();
const doc = parser.parseFromString(rej.error.text, "image/svg+xml");
this.svgMap.nativeElement.children.namedItem('viewbox').appendChild(doc.lastChild);
}
}
通话前我的SVG看起来类似于以下内容:
<svg _ngcontent-lys-c61 xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
[...]
id="worldmap"
width="100%" height="100%"
background-color="#000000"
viewBox="145 45 1000 1000">
[...]
<g _ngcontent-lys-c61 id="viewbox" style="cursor:default;">
<g _ngcontent-lys-c61 id="ocean"> [...] </g>
<g _ngcontent-lys-c61 id="lakes"> [...] </g>
<g _ngcontent-lys-c61 id="landmass">[...] </g>
[...]
</g>
</svg>
通话后,陆地群之后还有一个<g id="biomes"> [...] </g>
(如果我明显要求生物群系的话)。
我能发现的唯一区别是缺少_ngContent-lys-c61。但是,事件changeDetectorRef.detectChanges()不会导致显示该组。这也不是没有其他。我删除了chrome调试器中的所有组,但生物群系仍未显示。
在旁注:我发现了很多类似的问题,都使用了D3.js。我不想包括在内。
答案 0 :(得分:0)
当我终于找到解决方案时,将完全擦除并编辑此答案。问题与发送无法转换为json的字符串有关-我正在定义一个json标头用作标准响应类型。
长话短说,我将展示将svg组动态添加到现有svg的整个过程。技术:Angular和Spring Boot角度:
// component.ts
@ViewChild('svg') public svgMap: ElementRef<SVGElement>;
// function
const svg = await this._http.get(`pathToServer`, { responseType: 'text' }).toPromise();
const document: Document = new DOMParser().parseFromString(svg, "image/svg+xml");
const group: HTMLCollectionOf<SVGElement> = document.getElementsByTagNameNS('http://www.w3.org/2000/svg', 'g');
const groupToAttach: SVGElement = this.svgMap.nativeElement.children.namedItem('myGroup') as SVGElement;
groupToAttach.appendChild(group.namedItem('paths'))
// component.svg
<svg id="svg">
<g id="myGroup"></g>
</svg>
弹簧靴:
// imports:
import java.io.InputStreamReader;
import java.io.BufferedReader;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import java.nio.charset.StandardCharsets;
import java.util.stream.Collectors;
// class-level
@Autowired
private ResourceLoader resourceLoader;
//function
@GetMapping(path = "endpoint/{element}")
public ResponseEntity<String> function(@PathVariable String element) throws Exception {
Resource elementResource = resourceLoader.getResource("classpath:/" + element + ".svg");
InputStreamReader is = new InputStreamReader(elementResource.getInputStream(), StandardCharsets.UTF_8);
String data = new BufferedReader(is).lines().collect(Collectors.joining("\n"));
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.valueOf("image/svg+xml"));
return ResponseEntity.ok().headers(headers).contentLength(data.length()).body(data);
延迟加载的svg
<svg xmlns="http://www.w3.org/2000/svg">
<g id="paths">
// ...
</g>
</svg>