diff --git a/README.md b/README.md index d9fd954..220ec4c 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,16 @@ $ dockviz images --dot --only-labelled | dot -Tpng -o images.png ![](sample/images_only_labelled.png "Image") +Or as a treemap: + +``` +$ dockviz images -d | patchwork -Tpng -o treemap.png +OR +$ dockviz images --dot | patchwork -Tpng -o treemap.png +``` + +![](sample/treemap.png "Image") + Or in short form: ``` diff --git a/images.go b/images.go index ca202b7..097b4ec 100644 --- a/images.go +++ b/images.go @@ -405,6 +405,10 @@ func PrintTreeNode(buffer *bytes.Buffer, image Image, dispOpts DisplayOpts, pref } } +func megabytes(bytes int64) float64 { + return float64(bytes) / (1024 * 1024) +} + func humanSize(raw int64) string { sizes := []string{"B", "KB", "MB", "GB", "TB"} @@ -461,9 +465,9 @@ func imagesToDot(buffer *bytes.Buffer, images []Image, byParent map[string][]Ima buffer.WriteString(fmt.Sprintf(" \"%s\" -> \"%s\"\n", truncate(image.ParentId, 12), truncate(image.Id, 12))) } if image.RepoTags[0] != ":" { - buffer.WriteString(fmt.Sprintf(" \"%s\" [label=\"%s\\n%s\",shape=box,fillcolor=\"paleturquoise\",style=\"filled,rounded\"];\n", truncate(image.Id, 12), truncate(stripPrefix(image.OrigId), 12), strings.Join(image.RepoTags, "\\n"))) + buffer.WriteString(fmt.Sprintf(" \"%s\" [label=\"%s\\n%s\",area=%f,shape=box,fillcolor=\"paleturquoise\",style=\"filled,rounded\"];\n", truncate(image.Id, 12), truncate(stripPrefix(image.OrigId), 12), strings.Join(image.RepoTags, "\\n"), megabytes(image.Size))) } else { - buffer.WriteString(fmt.Sprintf(" \"%s\" [label=\"%s\"]\n", truncate(image.Id, 12), truncate(stripPrefix(image.OrigId), 12))) + buffer.WriteString(fmt.Sprintf(" \"%s\" [label=\"%s\",area=%f]\n", truncate(image.Id, 12), truncate(stripPrefix(image.OrigId), 12), megabytes(image.Size))) } if subimages, exists := byParent[image.Id]; exists { imagesToDot(buffer, subimages, byParent) diff --git a/sample/images.dot b/sample/images.dot index c3e4889..7faf467 100644 --- a/sample/images.dot +++ b/sample/images.dot @@ -1,37 +1,61 @@ digraph docker { - "0fe9a2bc50fe" -> "8c32832f07ba" - "cc4e1358bc80" -> "5c0d04fba9df" - "5c0d04fba9df" [label="5c0d04fba9df\nnate/mongodb:latest",shape=box,fillcolor="paleturquoise",style="filled,rounded"]; - "67b8b7262a67" -> "0fe9a2bc50fe" - "2f96171d2098" -> "67b8b7262a67" - "8c32832f07ba" -> "cc4e1358bc80" - "89541b3b35f2" -> "7dac4e98548e" - "341d0cc3fac8" -> "2f96171d2098" - "7dac4e98548e" -> "341d0cc3fac8" - "59dac4bae93b" -> "89541b3b35f2" - "d0525208a46c" -> "59dac4bae93b" - "e18d8001204e" -> "d0525208a46c" - "a7cf8ae4e998" -> "e18d8001204e" - "0cd8e7f50270" -> "594b6f8e6f92" - "594b6f8e6f92" -> "f832a63e87a4" - "f832a63e87a4" [label="f832a63e87a4\nredis:latest",shape=box,fillcolor="paleturquoise",style="filled,rounded"]; - "398d592f2009" -> "0cd8e7f50270" - "a7cf8ae4e998" -> "398d592f2009" - "5dbd9cb5a02f" -> "74fe38d11401" - "74fe38d11401" [label="74fe38d11401\nubuntu:12.04\nubuntu:precise",shape=box,fillcolor="paleturquoise",style="filled,rounded"]; - "82cdea7ab5b5" -> "5dbd9cb5a02f" - "f10ebce2c0e1" -> "82cdea7ab5b5" - "511136ea3c5a" -> "f10ebce2c0e1" - "cf8dc907452c" -> "a7cf8ae4e998" - "a7cf8ae4e998" [label="a7cf8ae4e998\nubuntu:12.10\nubuntu:quantal",shape=box,fillcolor="paleturquoise",style="filled,rounded"]; - "ef519c9ee91a" -> "07302703becc" - "07302703becc" -> "cf8dc907452c" - "511136ea3c5a" -> "ef519c9ee91a" - "cb12405ee8fa" -> "316b678ddf48" - "316b678ddf48" [label="316b678ddf48\nubuntu:13.04\nubuntu:raring",shape=box,fillcolor="paleturquoise",style="filled,rounded"]; - "e7206bfc66aa" -> "cb12405ee8fa" - "02dae1c13f51" -> "e7206bfc66aa" - "511136ea3c5a" -> "02dae1c13f51" base -> "511136ea3c5a" [style=invis] + "511136ea3c5a" [label="511136ea3c5a",area=0.000000] + "511136ea3c5a" -> "f10ebce2c0e1" + "f10ebce2c0e1" [label="f10ebce2c0e1",area=98.872495] + "f10ebce2c0e1" -> "82cdea7ab5b5" + "82cdea7ab5b5" [label="82cdea7ab5b5",area=0.243621] + "82cdea7ab5b5" -> "5dbd9cb5a02f" + "5dbd9cb5a02f" [label="5dbd9cb5a02f",area=0.001830] + "5dbd9cb5a02f" -> "74fe38d11401" + "74fe38d11401" [label="74fe38d11401\nubuntu:12.04\nubuntu:precise",area=100.772088,shape=box,fillcolor="paleturquoise",style="filled,rounded"]; + "511136ea3c5a" -> "ef519c9ee91a" + "ef519c9ee91a" [label="ef519c9ee91a",area=96.254996] + "ef519c9ee91a" -> "07302703becc" + "07302703becc" [label="07302703becc",area=0.239370] + "07302703becc" -> "cf8dc907452c" + "cf8dc907452c" [label="cf8dc907452c",area=0.001830] + "cf8dc907452c" -> "a7cf8ae4e998" + "a7cf8ae4e998" [label="a7cf8ae4e998\nubuntu:12.10\nubuntu:quantal",area=66.847105,shape=box,fillcolor="paleturquoise",style="filled,rounded"]; + "a7cf8ae4e998" -> "e18d8001204e" + "e18d8001204e" [label="e18d8001204e",area=0.027992] + "e18d8001204e" -> "d0525208a46c" + "d0525208a46c" [label="d0525208a46c",area=0.000068] + "d0525208a46c" -> "59dac4bae93b" + "59dac4bae93b" [label="59dac4bae93b",area=67.854815] + "59dac4bae93b" -> "89541b3b35f2" + "89541b3b35f2" [label="89541b3b35f2",area=256.858793] + "89541b3b35f2" -> "7dac4e98548e" + "7dac4e98548e" [label="7dac4e98548e",area=0.000000] + "7dac4e98548e" -> "341d0cc3fac8" + "341d0cc3fac8" [label="341d0cc3fac8",area=0.000000] + "341d0cc3fac8" -> "2f96171d2098" + "2f96171d2098" [label="2f96171d2098",area=0.000000] + "2f96171d2098" -> "67b8b7262a67" + "67b8b7262a67" [label="67b8b7262a67",area=1.779918] + "67b8b7262a67" -> "0fe9a2bc50fe" + "0fe9a2bc50fe" [label="0fe9a2bc50fe",area=0.000626] + "0fe9a2bc50fe" -> "8c32832f07ba" + "8c32832f07ba" [label="8c32832f07ba",area=0.000365] + "8c32832f07ba" -> "cc4e1358bc80" + "cc4e1358bc80" [label="cc4e1358bc80",area=0.000000] + "cc4e1358bc80" -> "5c0d04fba9df" + "5c0d04fba9df" [label="5c0d04fba9df\nnate/mongodb:latest",area=0.000000,shape=box,fillcolor="paleturquoise",style="filled,rounded"]; + "a7cf8ae4e998" -> "398d592f2009" + "398d592f2009" [label="398d592f2009",area=67.632430] + "398d592f2009" -> "0cd8e7f50270" + "0cd8e7f50270" [label="0cd8e7f50270",area=1.352684] + "0cd8e7f50270" -> "594b6f8e6f92" + "594b6f8e6f92" [label="594b6f8e6f92",area=0.000000] + "594b6f8e6f92" -> "f832a63e87a4" + "f832a63e87a4" [label="f832a63e87a4\nredis:latest",area=0.000000,shape=box,fillcolor="paleturquoise",style="filled,rounded"]; + "511136ea3c5a" -> "02dae1c13f51" + "02dae1c13f51" [label="02dae1c13f51",area=93.792276] + "02dae1c13f51" -> "e7206bfc66aa" + "e7206bfc66aa" [label="e7206bfc66aa",area=0.181205] + "e7206bfc66aa" -> "cb12405ee8fa" + "cb12405ee8fa" [label="cb12405ee8fa",area=0.001815] + "cb12405ee8fa" -> "316b678ddf48" + "316b678ddf48" [label="316b678ddf48\nubuntu:13.04\nubuntu:raring",area=67.541988,shape=box,fillcolor="paleturquoise",style="filled,rounded"]; base [style=invisible] } diff --git a/sample/images.png b/sample/images.png index 9dd4a2d..6e9e5f7 100644 Binary files a/sample/images.png and b/sample/images.png differ diff --git a/sample/treemap.png b/sample/treemap.png new file mode 100644 index 0000000..64e3993 Binary files /dev/null and b/sample/treemap.png differ