| // Copyright 2014 Google Inc. All Rights Reserved. | |
| // | |
| // Licensed under the Apache License, Version 2.0 (the "License"); | |
| // you may not use this file except in compliance with the License. | |
| // You may obtain a copy of the License at | |
| // | |
| // http://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, software | |
| // distributed under the License is distributed on an "AS IS" BASIS, | |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| // See the License for the specific language governing permissions and | |
| // limitations under the License. | |
| package driver | |
| import ( | |
| "regexp" | |
| "strings" | |
| "github.com/google/pprof/third_party/svgpan" | |
| ) | |
| var ( | |
| viewBox = regexp.MustCompile(`<svg\s*width="[^"]+"\s*height="[^"]+"\s*viewBox="[^"]+"`) | |
| graphID = regexp.MustCompile(`<g id="graph\d"`) | |
| svgClose = regexp.MustCompile(`</svg>`) | |
| ) | |
| // massageSVG enhances the SVG output from DOT to provide better | |
| // panning inside a web browser. It uses the svgpan library, which is | |
| // embedded into the svgpan.JSSource variable. | |
| func massageSVG(svg string) string { | |
| // Work around for dot bug which misses quoting some ampersands, | |
| // resulting on unparsable SVG. | |
| svg = strings.Replace(svg, "&;", "&;", -1) | |
| // Dot's SVG output is | |
| // | |
| // <svg width="___" height="___" | |
| // viewBox="___" xmlns=...> | |
| // <g id="graph0" transform="..."> | |
| // ... | |
| // </g> | |
| // </svg> | |
| // | |
| // Change it to | |
| // | |
| // <svg width="100%" height="100%" | |
| // xmlns=...> | |
| // <script type="text/ecmascript"><![CDATA[` ..$(svgpan.JSSource)... `]]></script>` | |
| // <g id="viewport" transform="translate(0,0)"> | |
| // <g id="graph0" transform="..."> | |
| // ... | |
| // </g> | |
| // </g> | |
| // </svg> | |
| if loc := viewBox.FindStringIndex(svg); loc != nil { | |
| svg = svg[:loc[0]] + | |
| `<svg width="100%" height="100%"` + | |
| svg[loc[1]:] | |
| } | |
| if loc := graphID.FindStringIndex(svg); loc != nil { | |
| svg = svg[:loc[0]] + | |
| `<script type="text/ecmascript"><![CDATA[` + svgpan.JSSource + `]]></script>` + | |
| `<g id="viewport" transform="scale(0.5,0.5) translate(0,0)">` + | |
| svg[loc[0]:] | |
| } | |
| if loc := svgClose.FindStringIndex(svg); loc != nil { | |
| svg = svg[:loc[0]] + | |
| `</g>` + | |
| svg[loc[0]:] | |
| } | |
| return svg | |
| } | |