@parca/profile 0.16.122 → 0.16.124
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/dist/MetricsGraph/MetricsTooltip/index.js +1 -1
- package/dist/MetricsGraph/index.d.ts +1 -0
- package/dist/MetricsGraph/index.js +10 -8
- package/dist/ProfileIcicleGraph/IcicleGraph/index.d.ts +0 -1
- package/dist/ProfileIcicleGraph/IcicleGraph/index.js +4 -22
- package/dist/ProfileIcicleGraph/index.d.ts +2 -1
- package/dist/ProfileIcicleGraph/index.js +10 -3
- package/dist/ProfileSelector/index.js +13 -3
- package/dist/ProfileSource.d.ts +6 -8
- package/dist/ProfileSource.js +26 -18
- package/dist/ProfileView/VisualizationPanel.d.ts +18 -0
- package/dist/ProfileView/VisualizationPanel.js +38 -0
- package/dist/ProfileView/index.js +6 -10
- package/dist/TopTable/index.d.ts +4 -1
- package/dist/TopTable/index.js +12 -7
- package/dist/styles.css +1 -1
- package/package.json +6 -6
- package/src/MetricsGraph/MetricsTooltip/index.tsx +7 -1
- package/src/MetricsGraph/index.tsx +11 -8
- package/src/ProfileIcicleGraph/IcicleGraph/index.tsx +0 -41
- package/src/ProfileIcicleGraph/index.tsx +23 -2
- package/src/ProfileSelector/index.tsx +14 -5
- package/src/ProfileSource.tsx +34 -51
- package/src/ProfileView/VisualizationPanel.tsx +79 -0
- package/src/ProfileView/index.tsx +16 -37
- package/src/TopTable/index.tsx +29 -20
package/dist/styles.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
/*! tailwindcss v3.2.4 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e7eb;box-sizing:border-box}:after,:before{--tw-content:""}html{-webkit-text-size-adjust:100%;font-feature-settings:normal;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{color:inherit;font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]{display:none}*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.visible{visibility:visible}.invisible{visibility:hidden}.absolute{position:absolute}.relative{position:relative}.-inset-2{bottom:-.5rem;left:-.5rem;right:-.5rem;top:-.5rem}.left-\[25px\]{left:25px}.left-0{left:0}.top-\[-46px\]{top:-46px}.right-0{right:0}.top-\[-45px\]{top:-45px}.top-\[-48px\]{top:-48px}.top-\[-69px\]{top:-69px}.top-\[-54px\]{top:-54px}.top-\[-70px\]{top:-70px}.z-50{z-index:50}.z-10{z-index:10}.m-auto{margin:auto}.m-0{margin:0}.m-2{margin:.5rem}.mx-2{margin-left:.5rem;margin-right:.5rem}.my-2{margin-bottom:.5rem;margin-top:.5rem}.my-20{margin-bottom:5rem;margin-top:5rem}.my-6{margin-bottom:1.5rem;margin-top:1.5rem}.mt-1{margin-top:.25rem}.ml-2{margin-left:.5rem}.ml-auto{margin-left:auto}.mb-2{margin-bottom:.5rem}.mr-6{margin-right:1.5rem}.mr-3{margin-right:.75rem}.mr-1{margin-right:.25rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-8{margin-top:2rem}.block{display:block}.inline-block{display:inline-block}.flex{display:flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-fit{height:-moz-fit-content;height:fit-content}.h-10{height:2.5rem}.h-1{height:.25rem}.h-\[80vh\]{height:80vh}.h-4{height:1rem}.max-h-\[400px\]{max-height:400px}.min-h-52{min-height:13rem}.w-auto{width:auto}.w-full{width:100%}.w-1\/4{width:25%}.w-3\/4{width:75%}.w-\[500px\]{width:500px}.w-40{width:10rem}.w-2\/5{width:40%}.w-1\/2{width:50%}.w-8{width:2rem}.w-4{width:1rem}.w-16{width:4rem}.w-fit{width:-moz-fit-content;width:fit-content}.w-\[420px\]{width:420px}.min-w-\[300px\]{min-width:300px}.max-w-\[500px\]{max-width:500px}.max-w-md{max-width:28rem}.flex-1{flex:1 1 0%}.flex-grow{flex-grow:1}.table-auto{table-layout:auto}.table-fixed{table-layout:fixed}.translate-y-1{--tw-translate-y:0.25rem}.translate-y-0,.translate-y-1{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-0{--tw-translate-y:0px}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.cursor-pointer{cursor:pointer}.cursor-default{cursor:default}.cursor-not-allowed{cursor:not-allowed}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-2{gap:.5rem}.gap-1{gap:.25rem}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.5rem*var(--tw-space-x-reverse))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.25rem*var(--tw-space-y-reverse));margin-top:calc(.25rem*(1 - var(--tw-space-y-reverse)))}.space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1rem*var(--tw-space-x-reverse))}.space-x-1>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.25rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.25rem*var(--tw-space-x-reverse))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-scroll{overflow:scroll}.text-ellipsis{text-overflow:ellipsis}.whitespace-normal{white-space:normal}.whitespace-nowrap{white-space:nowrap}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-none{border-radius:0}.rounded-l{border-bottom-left-radius:.25rem;border-top-left-radius:.25rem}.rounded-r{border-bottom-right-radius:.25rem;border-top-right-radius:.25rem}.border{border-width:1px}.border-r-0{border-right-width:0}.border-l-0{border-left-width:0}.border-gray-300{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity))}.border-red-400{--tw-border-opacity:1;border-color:rgb(248 113 113/var(--tw-border-opacity))}.bg-gray-50{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity))}.bg-gray-200{--tw-bg-opacity:1;background-color:rgb(229 231 235/var(--tw-bg-opacity))}.bg-indigo-600{--tw-bg-opacity:1;background-color:rgb(79 70 229/var(--tw-bg-opacity))}.bg-red-100{--tw-bg-opacity:1;background-color:rgb(254 226 226/var(--tw-bg-opacity))}.bg-black{--tw-bg-opacity:1;background-color:rgb(0 0 0/var(--tw-bg-opacity))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.bg-gray-800{--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity))}.bg-inherit{background-color:inherit}.fill-transparent{fill:transparent}.fill-current{fill:currentColor}.stroke-white{stroke:#fff}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-10{padding:2.5rem}.p-4{padding:1rem}.p-1{padding:.25rem}.px-2{padding-left:.5rem;padding-right:.5rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.px-4{padding-left:1rem;padding-right:1rem}.py-3{padding-bottom:.75rem;padding-top:.75rem}.py-20{padding-bottom:5rem;padding-top:5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.py-1{padding-bottom:.25rem;padding-top:.25rem}.px-1{padding-left:.25rem;padding-right:.25rem}.pr-0{padding-right:0}.pl-3{padding-left:.75rem}.pr-9{padding-right:2.25rem}.pt-2{padding-top:.5rem}.pb-4{padding-bottom:1rem}.pr-2{padding-right:.5rem}.pl-2{padding-left:.5rem}.pb-2{padding-bottom:.5rem}.text-left{text-align:left}.text-center{text-align:center}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.text-base{font-size:1rem;line-height:1.5rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.font-semibold{font-weight:600}.font-bold{font-weight:700}.text-gray-700{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity))}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.text-red-700{--tw-text-opacity:1;color:rgb(185 28 28/var(--tw-text-opacity))}.text-black{--tw-text-opacity:1;color:rgb(0 0 0/var(--tw-text-opacity))}.\!text-indigo-600{--tw-text-opacity:1!important;color:rgb(79 70 229/var(--tw-text-opacity))!important}.opacity-100{opacity:1}.opacity-0{opacity:0}.opacity-90{opacity:.9}.opacity-50{opacity:.5}.shadow-\[0_0_10px_2px_rgba\(0\2c 0\2c 0\2c 0\.3\)\]{--tw-shadow:0 0 10px 2px rgba(0,0,0,.3);--tw-shadow-colored:0 0 10px 2px var(--tw-shadow-color)}.shadow-\[0_0_10px_2px_rgba\(0\2c 0\2c 0\2c 0\.3\)\],.shadow-lg{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color)}.outline-none{outline:2px solid transparent;outline-offset:2px}.ring-1{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.ring-black{--tw-ring-opacity:1;--tw-ring-color:rgb(0 0 0/var(--tw-ring-opacity))}.ring-opacity-5{--tw-ring-opacity:0.05}.blur{--tw-blur:blur(8px)}.blur,.invert{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.invert{--tw-invert:invert(100%)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-100{transition-duration:.1s}.duration-200{transition-duration:.2s}.duration-150{transition-duration:.15s}.ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-indigo-800:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(55 48 163/var(--tw-ring-opacity))}.group:hover .group-hover\:flex{display:flex}[class~=theme-dark] .dark\:border-gray-500{--tw-border-opacity:1;border-color:rgb(107 114 128/var(--tw-border-opacity))}[class~=theme-dark] .dark\:bg-gray-900{--tw-bg-opacity:1;background-color:rgb(17 24 39/var(--tw-bg-opacity))}[class~=theme-dark] .dark\:bg-gray-800{--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity))}[class~=theme-dark] .dark\:bg-gray-700{--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity))}[class~=theme-dark] .dark\:stroke-gray-700{stroke:#374151}[class~=theme-dark] .dark\:text-gray-300{--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity))}[class~=theme-dark] .dark\:text-gray-50{--tw-text-opacity:1;color:rgb(249 250 251/var(--tw-text-opacity))}[class~=theme-dark] .dark\:text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity))}[class~=theme-dark] .dark\:\!text-indigo-400{--tw-text-opacity:1!important;color:rgb(129 140 248/var(--tw-text-opacity))!important}@media (min-width:640px){.sm\:inline{display:inline}.sm\:text-sm{font-size:.875rem;line-height:1.25rem}}
|
|
1
|
+
/*! tailwindcss v3.2.4 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e7eb;box-sizing:border-box}:after,:before{--tw-content:""}html{-webkit-text-size-adjust:100%;font-feature-settings:normal;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{color:inherit;font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]{display:none}*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.visible{visibility:visible}.invisible{visibility:hidden}.absolute{position:absolute}.relative{position:relative}.-inset-2{bottom:-.5rem;left:-.5rem;right:-.5rem;top:-.5rem}.left-\[25px\]{left:25px}.left-0{left:0}.top-\[-46px\]{top:-46px}.right-0{right:0}.z-50{z-index:50}.z-10{z-index:10}.m-auto{margin:auto}.m-0{margin:0}.m-2{margin:.5rem}.mx-2{margin-left:.5rem;margin-right:.5rem}.my-2{margin-bottom:.5rem;margin-top:.5rem}.my-20{margin-bottom:5rem;margin-top:5rem}.my-6{margin-bottom:1.5rem;margin-top:1.5rem}.mt-1{margin-top:.25rem}.ml-2{margin-left:.5rem}.ml-auto{margin-left:auto}.mb-2{margin-bottom:.5rem}.mr-6{margin-right:1.5rem}.mr-3{margin-right:.75rem}.mr-1{margin-right:.25rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-8{margin-top:2rem}.block{display:block}.inline-block{display:inline-block}.flex{display:flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-fit{height:-moz-fit-content;height:fit-content}.h-10{height:2.5rem}.h-1{height:.25rem}.h-\[80vh\]{height:80vh}.h-4{height:1rem}.max-h-\[400px\]{max-height:400px}.min-h-52{min-height:13rem}.w-auto{width:auto}.w-full{width:100%}.w-1\/4{width:25%}.w-3\/4{width:75%}.w-\[500px\]{width:500px}.w-40{width:10rem}.w-2\/5{width:40%}.w-1\/2{width:50%}.w-8{width:2rem}.w-4{width:1rem}.w-16{width:4rem}.w-fit{width:-moz-fit-content;width:fit-content}.w-\[420px\]{width:420px}.min-w-\[300px\]{min-width:300px}.max-w-\[500px\]{max-width:500px}.max-w-md{max-width:28rem}.flex-1{flex:1 1 0%}.flex-grow{flex-grow:1}.table-auto{table-layout:auto}.table-fixed{table-layout:fixed}.translate-y-1{--tw-translate-y:0.25rem}.translate-y-0,.translate-y-1{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-0{--tw-translate-y:0px}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.cursor-pointer{cursor:pointer}.cursor-default{cursor:default}.cursor-not-allowed{cursor:not-allowed}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-2{gap:.5rem}.gap-1{gap:.25rem}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.5rem*var(--tw-space-x-reverse))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.25rem*var(--tw-space-y-reverse));margin-top:calc(.25rem*(1 - var(--tw-space-y-reverse)))}.space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1rem*var(--tw-space-x-reverse))}.space-x-1>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.25rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.25rem*var(--tw-space-x-reverse))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-scroll{overflow:scroll}.text-ellipsis{text-overflow:ellipsis}.whitespace-normal{white-space:normal}.whitespace-nowrap{white-space:nowrap}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-none{border-radius:0}.rounded-l{border-bottom-left-radius:.25rem;border-top-left-radius:.25rem}.rounded-r{border-bottom-right-radius:.25rem;border-top-right-radius:.25rem}.border{border-width:1px}.border-r-0{border-right-width:0}.border-l-0{border-left-width:0}.border-gray-300{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity))}.border-red-400{--tw-border-opacity:1;border-color:rgb(248 113 113/var(--tw-border-opacity))}.bg-gray-50{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity))}.bg-gray-200{--tw-bg-opacity:1;background-color:rgb(229 231 235/var(--tw-bg-opacity))}.bg-indigo-600{--tw-bg-opacity:1;background-color:rgb(79 70 229/var(--tw-bg-opacity))}.bg-red-100{--tw-bg-opacity:1;background-color:rgb(254 226 226/var(--tw-bg-opacity))}.bg-black{--tw-bg-opacity:1;background-color:rgb(0 0 0/var(--tw-bg-opacity))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.bg-gray-800{--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity))}.bg-inherit{background-color:inherit}.fill-transparent{fill:transparent}.fill-current{fill:currentColor}.stroke-white{stroke:#fff}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-10{padding:2.5rem}.p-4{padding:1rem}.p-1{padding:.25rem}.px-2{padding-left:.5rem;padding-right:.5rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.px-4{padding-left:1rem;padding-right:1rem}.py-3{padding-bottom:.75rem;padding-top:.75rem}.py-20{padding-bottom:5rem;padding-top:5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.py-1{padding-bottom:.25rem;padding-top:.25rem}.px-1{padding-left:.25rem;padding-right:.25rem}.pr-0{padding-right:0}.pl-3{padding-left:.75rem}.pr-9{padding-right:2.25rem}.pt-2{padding-top:.5rem}.pb-4{padding-bottom:1rem}.pr-2{padding-right:.5rem}.pl-2{padding-left:.5rem}.pb-2{padding-bottom:.5rem}.text-left{text-align:left}.text-center{text-align:center}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.text-base{font-size:1rem;line-height:1.5rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.font-semibold{font-weight:600}.font-bold{font-weight:700}.text-gray-700{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity))}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.text-red-700{--tw-text-opacity:1;color:rgb(185 28 28/var(--tw-text-opacity))}.text-black{--tw-text-opacity:1;color:rgb(0 0 0/var(--tw-text-opacity))}.\!text-indigo-600{--tw-text-opacity:1!important;color:rgb(79 70 229/var(--tw-text-opacity))!important}.opacity-100{opacity:1}.opacity-0{opacity:0}.opacity-90{opacity:.9}.opacity-50{opacity:.5}.shadow-\[0_0_10px_2px_rgba\(0\2c 0\2c 0\2c 0\.3\)\]{--tw-shadow:0 0 10px 2px rgba(0,0,0,.3);--tw-shadow-colored:0 0 10px 2px var(--tw-shadow-color)}.shadow-\[0_0_10px_2px_rgba\(0\2c 0\2c 0\2c 0\.3\)\],.shadow-lg{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color)}.outline-none{outline:2px solid transparent;outline-offset:2px}.ring-1{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.ring-black{--tw-ring-opacity:1;--tw-ring-color:rgb(0 0 0/var(--tw-ring-opacity))}.ring-opacity-5{--tw-ring-opacity:0.05}.blur{--tw-blur:blur(8px)}.blur,.invert{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.invert{--tw-invert:invert(100%)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-100{transition-duration:.1s}.duration-200{transition-duration:.2s}.duration-150{transition-duration:.15s}.ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-indigo-800:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(55 48 163/var(--tw-ring-opacity))}.group:hover .group-hover\:flex{display:flex}[class~=theme-dark] .dark\:border-gray-500{--tw-border-opacity:1;border-color:rgb(107 114 128/var(--tw-border-opacity))}[class~=theme-dark] .dark\:bg-gray-900{--tw-bg-opacity:1;background-color:rgb(17 24 39/var(--tw-bg-opacity))}[class~=theme-dark] .dark\:bg-gray-800{--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity))}[class~=theme-dark] .dark\:bg-gray-700{--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity))}[class~=theme-dark] .dark\:stroke-gray-700{stroke:#374151}[class~=theme-dark] .dark\:text-gray-300{--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity))}[class~=theme-dark] .dark\:text-gray-50{--tw-text-opacity:1;color:rgb(249 250 251/var(--tw-text-opacity))}[class~=theme-dark] .dark\:text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity))}[class~=theme-dark] .dark\:\!text-indigo-400{--tw-text-opacity:1!important;color:rgb(129 140 248/var(--tw-text-opacity))!important}@media (min-width:640px){.sm\:inline{display:inline}.sm\:text-sm{font-size:.875rem;line-height:1.25rem}}
|
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parca/profile",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.124",
|
|
4
4
|
"description": "Profile viewing libraries",
|
|
5
5
|
"dependencies": {
|
|
6
|
-
"@parca/client": "^0.16.
|
|
7
|
-
"@parca/components": "^0.16.
|
|
6
|
+
"@parca/client": "^0.16.64",
|
|
7
|
+
"@parca/components": "^0.16.103",
|
|
8
8
|
"@parca/dynamicsize": "^0.16.53",
|
|
9
|
-
"@parca/functions": "^0.16.
|
|
9
|
+
"@parca/functions": "^0.16.64",
|
|
10
10
|
"@parca/parser": "^0.16.54",
|
|
11
|
-
"@parca/store": "^0.16.
|
|
11
|
+
"@parca/store": "^0.16.60",
|
|
12
12
|
"@types/react-beautiful-dnd": "^13.1.3",
|
|
13
13
|
"d3": "7.8.2",
|
|
14
14
|
"d3-scale": "^4.0.2",
|
|
@@ -45,5 +45,5 @@
|
|
|
45
45
|
"access": "public",
|
|
46
46
|
"registry": "https://registry.npmjs.org/"
|
|
47
47
|
},
|
|
48
|
-
"gitHead": "
|
|
48
|
+
"gitHead": "bcca09575ec917fdd2669a0b32b7e3b7e3757117"
|
|
49
49
|
}
|
|
@@ -119,7 +119,13 @@ const MetricsTooltip = ({
|
|
|
119
119
|
<tr>
|
|
120
120
|
<td className="w-1/4">Value</td>
|
|
121
121
|
<td className="w-3/4">
|
|
122
|
-
{valueFormatter(highlighted.
|
|
122
|
+
{valueFormatter(highlighted.valuePerSecond, sampleUnit, 5)}
|
|
123
|
+
</td>
|
|
124
|
+
</tr>
|
|
125
|
+
<tr>
|
|
126
|
+
<td className="w-1/4">Total</td>
|
|
127
|
+
<td className="w-3/4">
|
|
128
|
+
{valueFormatter(highlighted.value, sampleUnit, 2)}
|
|
123
129
|
</td>
|
|
124
130
|
</tr>
|
|
125
131
|
<tr>
|
|
@@ -49,6 +49,7 @@ export interface HighlightedSeries {
|
|
|
49
49
|
labels: Label[];
|
|
50
50
|
timestamp: number;
|
|
51
51
|
value: number;
|
|
52
|
+
valuePerSecond: number;
|
|
52
53
|
x: number;
|
|
53
54
|
y: number;
|
|
54
55
|
}
|
|
@@ -134,9 +135,9 @@ export const RawMetricsGraph = ({
|
|
|
134
135
|
agg.push({
|
|
135
136
|
metric: s.labelset.labels,
|
|
136
137
|
values: s.samples.reduce<number[][]>(function (agg: number[][], d: MetricsSample) {
|
|
137
|
-
if (d.timestamp !== undefined && d.
|
|
138
|
+
if (d.timestamp !== undefined && d.valuePerSecond !== undefined) {
|
|
138
139
|
const t = (+d.timestamp.seconds * 1e9 + d.timestamp.nanos) / 1e6; // https://github.com/microsoft/TypeScript/issues/5710#issuecomment-157886246
|
|
139
|
-
agg.push([t, parseFloat(d.value)]);
|
|
140
|
+
agg.push([t, d.valuePerSecond, parseFloat(d.value)]);
|
|
140
141
|
}
|
|
141
142
|
return agg;
|
|
142
143
|
}, []),
|
|
@@ -202,7 +203,8 @@ export const RawMetricsGraph = ({
|
|
|
202
203
|
seriesIndex: closestSeriesIndex,
|
|
203
204
|
labels: series[closestSeriesIndex].metric,
|
|
204
205
|
timestamp: point[0],
|
|
205
|
-
|
|
206
|
+
valuePerSecond: point[1],
|
|
207
|
+
value: point[2],
|
|
206
208
|
x: xScale(point[0]),
|
|
207
209
|
y: yScale(point[1]),
|
|
208
210
|
};
|
|
@@ -295,14 +297,14 @@ export const RawMetricsGraph = ({
|
|
|
295
297
|
let seriesIndex = -1;
|
|
296
298
|
|
|
297
299
|
outer: for (let i = 0; i < series.length; i++) {
|
|
298
|
-
const keys = profile.
|
|
300
|
+
const keys = profile.query.matchers.map(e => e.key);
|
|
299
301
|
for (let j = 0; j < keys.length; j++) {
|
|
300
|
-
const
|
|
301
|
-
const label = series[i].metric.find(e => e.name ===
|
|
302
|
+
const matcherKey = keys[j];
|
|
303
|
+
const label = series[i].metric.find(e => e.name === matcherKey);
|
|
302
304
|
if (label === undefined) {
|
|
303
305
|
continue outer; // label doesn't exist to begin with
|
|
304
306
|
}
|
|
305
|
-
if (profile.
|
|
307
|
+
if (profile.query.matchers[j].value !== label.value) {
|
|
306
308
|
continue outer; // label values don't match
|
|
307
309
|
}
|
|
308
310
|
}
|
|
@@ -325,7 +327,8 @@ export const RawMetricsGraph = ({
|
|
|
325
327
|
labels: [],
|
|
326
328
|
seriesIndex,
|
|
327
329
|
timestamp: sample[0],
|
|
328
|
-
|
|
330
|
+
valuePerSecond: sample[1],
|
|
331
|
+
value: sample[2],
|
|
329
332
|
x: xScale(sample[0]),
|
|
330
333
|
y: yScale(sample[1]),
|
|
331
334
|
};
|
|
@@ -13,13 +13,10 @@
|
|
|
13
13
|
|
|
14
14
|
import {memo, useEffect, useMemo, useRef, useState} from 'react';
|
|
15
15
|
|
|
16
|
-
import cx from 'classnames';
|
|
17
16
|
import {scaleLinear} from 'd3-scale';
|
|
18
17
|
|
|
19
18
|
import {Flamegraph, FlamegraphNode, FlamegraphRootNode} from '@parca/client';
|
|
20
|
-
import {Button, useURLState} from '@parca/components';
|
|
21
19
|
import {selectQueryParam, type NavigateFunction} from '@parca/functions';
|
|
22
|
-
import useUserPreference, {USER_PREFERENCES} from '@parca/functions/useUserPreference';
|
|
23
20
|
|
|
24
21
|
import GraphTooltip, {type HoveringNode} from '../../GraphTooltip';
|
|
25
22
|
import ColorStackLegend from './ColorStackLegend';
|
|
@@ -33,7 +30,6 @@ interface IcicleGraphProps {
|
|
|
33
30
|
curPath: string[];
|
|
34
31
|
setCurPath: (path: string[]) => void;
|
|
35
32
|
navigateTo?: NavigateFunction;
|
|
36
|
-
isTrimmed?: boolean;
|
|
37
33
|
}
|
|
38
34
|
|
|
39
35
|
export const IcicleGraph = memo(function IcicleGraph({
|
|
@@ -43,7 +39,6 @@ export const IcicleGraph = memo(function IcicleGraph({
|
|
|
43
39
|
curPath,
|
|
44
40
|
sampleUnit,
|
|
45
41
|
navigateTo,
|
|
46
|
-
isTrimmed = false,
|
|
47
42
|
}: IcicleGraphProps): JSX.Element {
|
|
48
43
|
const [hoveringNode, setHoveringNode] = useState<
|
|
49
44
|
FlamegraphNode | FlamegraphRootNode | undefined
|
|
@@ -51,20 +46,12 @@ export const IcicleGraph = memo(function IcicleGraph({
|
|
|
51
46
|
const [height, setHeight] = useState(0);
|
|
52
47
|
const svg = useRef(null);
|
|
53
48
|
const ref = useRef<SVGGElement>(null);
|
|
54
|
-
const [rawDashboardItems] = useURLState({
|
|
55
|
-
param: 'dashboard_items',
|
|
56
|
-
});
|
|
57
49
|
|
|
58
|
-
const dashboardItems = rawDashboardItems as string[];
|
|
59
50
|
const coloredGraph = useColoredGraph(graph);
|
|
60
51
|
const currentSearchString = (selectQueryParam('search_string') as string) ?? '';
|
|
61
52
|
const compareMode: boolean =
|
|
62
53
|
selectQueryParam('compare_a') === 'true' && selectQueryParam('compare_b') === 'true';
|
|
63
54
|
|
|
64
|
-
const [colorProfileName] = useUserPreference<string>(
|
|
65
|
-
USER_PREFERENCES.FLAMEGRAPH_COLOR_PROFILE.key
|
|
66
|
-
);
|
|
67
|
-
|
|
68
55
|
useEffect(() => {
|
|
69
56
|
if (ref.current != null) {
|
|
70
57
|
setHeight(ref?.current.getBoundingClientRect().height);
|
|
@@ -83,8 +70,6 @@ export const IcicleGraph = memo(function IcicleGraph({
|
|
|
83
70
|
return <></>;
|
|
84
71
|
}
|
|
85
72
|
|
|
86
|
-
const isColorStackLegendVisible = colorProfileName !== 'default';
|
|
87
|
-
|
|
88
73
|
return (
|
|
89
74
|
<div onMouseLeave={() => setHoveringNode(undefined)}>
|
|
90
75
|
<ColorStackLegend navigateTo={navigateTo} compareMode={compareMode} />
|
|
@@ -98,32 +83,6 @@ export const IcicleGraph = memo(function IcicleGraph({
|
|
|
98
83
|
locations={coloredGraph.locations}
|
|
99
84
|
functions={coloredGraph.function}
|
|
100
85
|
/>
|
|
101
|
-
<div
|
|
102
|
-
className={cx('flex justify-start absolute', {
|
|
103
|
-
'top-[-48px]': dashboardItems.length <= 1 && !isTrimmed && !isColorStackLegendVisible,
|
|
104
|
-
'top-[-69px]': dashboardItems.length <= 1 && !isTrimmed && isColorStackLegendVisible,
|
|
105
|
-
'top-[-54px]': dashboardItems.length <= 1 && isTrimmed && isColorStackLegendVisible,
|
|
106
|
-
'top-[-54px] ': dashboardItems.length <= 1 && isTrimmed && !isColorStackLegendVisible,
|
|
107
|
-
'top-[-54px] left-[25px]':
|
|
108
|
-
dashboardItems.length > 1 && isTrimmed && isColorStackLegendVisible,
|
|
109
|
-
'top-[-54px] left-[25px] ':
|
|
110
|
-
dashboardItems.length > 1 && isTrimmed && !isColorStackLegendVisible,
|
|
111
|
-
'top-[-70px] left-[25px]':
|
|
112
|
-
dashboardItems.length > 1 && !isTrimmed && isColorStackLegendVisible,
|
|
113
|
-
'top-[-46px] left-[25px]':
|
|
114
|
-
dashboardItems.length > 1 && !isTrimmed && !isColorStackLegendVisible,
|
|
115
|
-
})}
|
|
116
|
-
>
|
|
117
|
-
<Button
|
|
118
|
-
color="neutral"
|
|
119
|
-
onClick={() => setCurPath([])}
|
|
120
|
-
disabled={curPath.length === 0}
|
|
121
|
-
className="w-auto"
|
|
122
|
-
variant="neutral"
|
|
123
|
-
>
|
|
124
|
-
Reset View
|
|
125
|
-
</Button>
|
|
126
|
-
</div>
|
|
127
86
|
<svg
|
|
128
87
|
className="font-robotoMono"
|
|
129
88
|
width={width}
|
|
@@ -14,11 +14,12 @@
|
|
|
14
14
|
import {useEffect, useMemo} from 'react';
|
|
15
15
|
|
|
16
16
|
import {Flamegraph} from '@parca/client';
|
|
17
|
+
import {Button} from '@parca/components';
|
|
17
18
|
import {useContainerDimensions} from '@parca/dynamicsize';
|
|
18
19
|
import {selectQueryParam, type NavigateFunction} from '@parca/functions';
|
|
19
20
|
|
|
20
21
|
import DiffLegend from '../components/DiffLegend';
|
|
21
|
-
import IcicleGraph from './IcicleGraph';
|
|
22
|
+
import {IcicleGraph} from './IcicleGraph';
|
|
22
23
|
|
|
23
24
|
const numberFormatter = new Intl.NumberFormat('en-US');
|
|
24
25
|
|
|
@@ -33,6 +34,7 @@ interface ProfileIcicleGraphProps {
|
|
|
33
34
|
onContainerResize?: ResizeHandler;
|
|
34
35
|
navigateTo?: NavigateFunction;
|
|
35
36
|
loading: boolean;
|
|
37
|
+
setActionButtons?: (buttons: JSX.Element) => void;
|
|
36
38
|
}
|
|
37
39
|
|
|
38
40
|
const ProfileIcicleGraph = ({
|
|
@@ -43,6 +45,7 @@ const ProfileIcicleGraph = ({
|
|
|
43
45
|
onContainerResize,
|
|
44
46
|
navigateTo,
|
|
45
47
|
loading,
|
|
48
|
+
setActionButtons,
|
|
46
49
|
}: ProfileIcicleGraphProps): JSX.Element => {
|
|
47
50
|
const compareMode: boolean =
|
|
48
51
|
selectQueryParam('compare_a') === 'true' && selectQueryParam('compare_b') === 'true';
|
|
@@ -75,6 +78,25 @@ const ProfileIcicleGraph = ({
|
|
|
75
78
|
];
|
|
76
79
|
}, [graph]);
|
|
77
80
|
|
|
81
|
+
useEffect(() => {
|
|
82
|
+
if (setActionButtons === undefined) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
setActionButtons(
|
|
86
|
+
<>
|
|
87
|
+
<Button
|
|
88
|
+
color="neutral"
|
|
89
|
+
onClick={() => setNewCurPath([])}
|
|
90
|
+
disabled={curPath.length === 0}
|
|
91
|
+
className="w-auto"
|
|
92
|
+
variant="neutral"
|
|
93
|
+
>
|
|
94
|
+
Reset View
|
|
95
|
+
</Button>
|
|
96
|
+
</>
|
|
97
|
+
);
|
|
98
|
+
}, [setNewCurPath, curPath, setActionButtons]);
|
|
99
|
+
|
|
78
100
|
if (graph === undefined) return <div>no data...</div>;
|
|
79
101
|
|
|
80
102
|
const total = graph.total;
|
|
@@ -97,7 +119,6 @@ const ProfileIcicleGraph = ({
|
|
|
97
119
|
setCurPath={setNewCurPath}
|
|
98
120
|
sampleUnit={sampleUnit}
|
|
99
121
|
navigateTo={navigateTo}
|
|
100
|
-
isTrimmed={isTrimmed}
|
|
101
122
|
/>
|
|
102
123
|
</div>
|
|
103
124
|
</div>
|
|
@@ -157,6 +157,7 @@ const ProfileSelector = ({
|
|
|
157
157
|
const newValue = value.includes('\\') ? value.replaceAll('\\', '\\\\') : value;
|
|
158
158
|
const [newQuery, changed] = Query.parse(queryExpressionString).setMatcher(key, newValue);
|
|
159
159
|
if (changed) {
|
|
160
|
+
// TODO: Change this to store the query object
|
|
160
161
|
setNewQueryExpression(newQuery.toString());
|
|
161
162
|
}
|
|
162
163
|
};
|
|
@@ -261,14 +262,22 @@ const ProfileSelector = ({
|
|
|
261
262
|
}}
|
|
262
263
|
addLabelMatcher={addLabelMatcher}
|
|
263
264
|
onPointClick={(timestamp, labels, queryExpression) => {
|
|
265
|
+
// TODO: Pass the query object via click rather than queryExpression
|
|
266
|
+
let query = Query.parse(queryExpression);
|
|
267
|
+
labels.forEach(l => {
|
|
268
|
+
const [newQuery, updated] = query.setMatcher(l.name, l.value);
|
|
269
|
+
if (updated) {
|
|
270
|
+
query = newQuery;
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
|
|
264
274
|
const stepDuration = getStepDuration(querySelection.from, querySelection.to);
|
|
265
275
|
const stepDurationInMilliseconds = getStepDurationInMilliseconds(stepDuration);
|
|
266
|
-
const isDeltaType = Query.parse(queryExpression).profileType().delta;
|
|
267
276
|
const mergeFrom = timestamp;
|
|
268
|
-
const mergeTo =
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
);
|
|
277
|
+
const mergeTo = query.profileType().delta
|
|
278
|
+
? mergeFrom + stepDurationInMilliseconds
|
|
279
|
+
: mergeFrom;
|
|
280
|
+
selectProfile(new MergedProfileSelection(mergeFrom, mergeTo, query));
|
|
272
281
|
}}
|
|
273
282
|
/>
|
|
274
283
|
) : (
|
package/src/ProfileSource.tsx
CHANGED
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
Timestamp,
|
|
22
22
|
} from '@parca/client';
|
|
23
23
|
import {formatDate} from '@parca/functions';
|
|
24
|
-
import {ProfileType, Query} from '@parca/parser';
|
|
24
|
+
import {Matcher, ProfileType, Query} from '@parca/parser';
|
|
25
25
|
|
|
26
26
|
export interface ProfileSource {
|
|
27
27
|
QueryRequest: () => QueryRequest;
|
|
@@ -56,10 +56,12 @@ export function SuffixParams(params: {[key: string]: any}, suffix: string): {[ke
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
export function ParseLabels(labels: string[]): Label[] {
|
|
59
|
-
return labels
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
59
|
+
return labels
|
|
60
|
+
.filter(str => str !== '')
|
|
61
|
+
.map(function (labelString): Label {
|
|
62
|
+
const parts = labelString.split('=', 2);
|
|
63
|
+
return {name: parts[0], value: parts[1]};
|
|
64
|
+
});
|
|
63
65
|
}
|
|
64
66
|
|
|
65
67
|
export function ProfileSelectionFromParams(
|
|
@@ -78,13 +80,16 @@ export function ProfileSelectionFromParams(
|
|
|
78
80
|
mergeTo !== undefined &&
|
|
79
81
|
expression !== undefined
|
|
80
82
|
) {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
83
|
+
// TODO: Refactor parsing the query and adding matchers
|
|
84
|
+
let query = Query.parse(expression);
|
|
85
|
+
ParseLabels(labels ?? ['']).forEach(l => {
|
|
86
|
+
const [newQuery, changed] = query.setMatcher(l.name, l.value);
|
|
87
|
+
if (changed) {
|
|
88
|
+
query = newQuery;
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
return new MergedProfileSelection(parseInt(mergeFrom), parseInt(mergeTo), query, filterQuery);
|
|
88
93
|
}
|
|
89
94
|
|
|
90
95
|
return null;
|
|
@@ -93,26 +98,18 @@ export function ProfileSelectionFromParams(
|
|
|
93
98
|
export class MergedProfileSelection implements ProfileSelection {
|
|
94
99
|
mergeFrom: number;
|
|
95
100
|
mergeTo: number;
|
|
96
|
-
query:
|
|
101
|
+
query: Query;
|
|
97
102
|
filterQuery: string | undefined;
|
|
98
|
-
labels: Label[];
|
|
99
103
|
|
|
100
|
-
constructor(
|
|
101
|
-
mergeFrom: number,
|
|
102
|
-
mergeTo: number,
|
|
103
|
-
labels: Label[],
|
|
104
|
-
query: string,
|
|
105
|
-
filterQuery?: string
|
|
106
|
-
) {
|
|
104
|
+
constructor(mergeFrom: number, mergeTo: number, query: Query, filterQuery?: string) {
|
|
107
105
|
this.mergeFrom = mergeFrom;
|
|
108
106
|
this.mergeTo = mergeTo;
|
|
109
107
|
this.query = query;
|
|
110
108
|
this.filterQuery = filterQuery;
|
|
111
|
-
this.labels = labels;
|
|
112
109
|
}
|
|
113
110
|
|
|
114
111
|
ProfileName(): string {
|
|
115
|
-
return
|
|
112
|
+
return this.query.profileName();
|
|
116
113
|
}
|
|
117
114
|
|
|
118
115
|
HistoryParams(): {[key: string]: any} {
|
|
@@ -121,7 +118,7 @@ export class MergedProfileSelection implements ProfileSelection {
|
|
|
121
118
|
merge_to: this.mergeTo.toString(),
|
|
122
119
|
query: this.query,
|
|
123
120
|
profile_name: this.ProfileName(),
|
|
124
|
-
labels: this.
|
|
121
|
+
labels: this.query.matchers.map(m => `${m.key}=${encodeURIComponent(m.value)}`),
|
|
125
122
|
};
|
|
126
123
|
}
|
|
127
124
|
|
|
@@ -130,13 +127,7 @@ export class MergedProfileSelection implements ProfileSelection {
|
|
|
130
127
|
}
|
|
131
128
|
|
|
132
129
|
ProfileSource(): ProfileSource {
|
|
133
|
-
return new MergedProfileSource(
|
|
134
|
-
this.mergeFrom,
|
|
135
|
-
this.mergeTo,
|
|
136
|
-
this.labels,
|
|
137
|
-
this.query,
|
|
138
|
-
this.filterQuery
|
|
139
|
-
);
|
|
130
|
+
return new MergedProfileSource(this.mergeFrom, this.mergeTo, this.query, this.filterQuery);
|
|
140
131
|
}
|
|
141
132
|
}
|
|
142
133
|
|
|
@@ -190,20 +181,12 @@ export class ProfileDiffSource implements ProfileSource {
|
|
|
190
181
|
export class MergedProfileSource implements ProfileSource {
|
|
191
182
|
mergeFrom: number;
|
|
192
183
|
mergeTo: number;
|
|
193
|
-
|
|
194
|
-
query: string;
|
|
184
|
+
query: Query;
|
|
195
185
|
filterQuery: string | undefined;
|
|
196
186
|
|
|
197
|
-
constructor(
|
|
198
|
-
mergeFrom: number,
|
|
199
|
-
mergeTo: number,
|
|
200
|
-
labels: Label[],
|
|
201
|
-
query: string,
|
|
202
|
-
filterQuery?: string
|
|
203
|
-
) {
|
|
187
|
+
constructor(mergeFrom: number, mergeTo: number, query: Query, filterQuery?: string) {
|
|
204
188
|
this.mergeFrom = mergeFrom;
|
|
205
189
|
this.mergeTo = mergeTo;
|
|
206
|
-
this.labels = labels;
|
|
207
190
|
this.query = query;
|
|
208
191
|
this.filterQuery = filterQuery;
|
|
209
192
|
}
|
|
@@ -215,7 +198,7 @@ export class MergedProfileSource implements ProfileSource {
|
|
|
215
198
|
merge: {
|
|
216
199
|
start: Timestamp.fromDate(new Date(this.mergeFrom)),
|
|
217
200
|
end: Timestamp.fromDate(new Date(this.mergeTo)),
|
|
218
|
-
query: this.query,
|
|
201
|
+
query: this.query.toString(),
|
|
219
202
|
},
|
|
220
203
|
},
|
|
221
204
|
mode: ProfileDiffSelection_Mode.MERGE,
|
|
@@ -229,7 +212,7 @@ export class MergedProfileSource implements ProfileSource {
|
|
|
229
212
|
merge: {
|
|
230
213
|
start: Timestamp.fromDate(new Date(this.mergeFrom)),
|
|
231
214
|
end: Timestamp.fromDate(new Date(this.mergeTo)),
|
|
232
|
-
query: this.query,
|
|
215
|
+
query: this.query.toString(),
|
|
233
216
|
},
|
|
234
217
|
},
|
|
235
218
|
reportType: QueryRequest_ReportType.FLAMEGRAPH_UNSPECIFIED,
|
|
@@ -239,26 +222,26 @@ export class MergedProfileSource implements ProfileSource {
|
|
|
239
222
|
}
|
|
240
223
|
|
|
241
224
|
ProfileType(): ProfileType {
|
|
242
|
-
return ProfileType.fromString(Query.parse(this.query).profileName());
|
|
225
|
+
return ProfileType.fromString(Query.parse(this.query.toString()).profileName());
|
|
243
226
|
}
|
|
244
227
|
|
|
245
228
|
Describe(): JSX.Element {
|
|
246
229
|
return (
|
|
247
230
|
<a>
|
|
248
|
-
Merge of "{this.query}" from {formatDate(this.mergeFrom, timeFormat)}
|
|
249
|
-
{formatDate(this.mergeTo, timeFormat)}
|
|
231
|
+
Merge of "{this.query.toString()}" from {formatDate(this.mergeFrom, timeFormat)}{' '}
|
|
232
|
+
to {formatDate(this.mergeTo, timeFormat)}
|
|
250
233
|
</a>
|
|
251
234
|
);
|
|
252
235
|
}
|
|
253
236
|
|
|
254
|
-
|
|
255
|
-
return this.
|
|
256
|
-
.filter((
|
|
257
|
-
.map((
|
|
237
|
+
stringMatchers(): string[] {
|
|
238
|
+
return this.query.matchers
|
|
239
|
+
.filter((m: Matcher) => m.key !== '__name__')
|
|
240
|
+
.map((m: Matcher) => `${m.key}=${m.value}`);
|
|
258
241
|
}
|
|
259
242
|
|
|
260
243
|
toString(): string {
|
|
261
|
-
return `merged profiles of query "${this.query}" from ${formatDate(
|
|
244
|
+
return `merged profiles of query "${this.query.toString()}" from ${formatDate(
|
|
262
245
|
this.mergeFrom,
|
|
263
246
|
timeFormat
|
|
264
247
|
)} to ${formatDate(this.mergeTo, timeFormat)}`;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// Copyright 2022 The Parca Authors
|
|
2
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
// you may not use this file except in compliance with the License.
|
|
4
|
+
// You may obtain a copy of the License at
|
|
5
|
+
//
|
|
6
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
//
|
|
8
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
// See the License for the specific language governing permissions and
|
|
12
|
+
// limitations under the License.
|
|
13
|
+
|
|
14
|
+
import React, {useState} from 'react';
|
|
15
|
+
|
|
16
|
+
import {Icon} from '@iconify/react';
|
|
17
|
+
import cx from 'classnames';
|
|
18
|
+
import type {DraggableProvidedDragHandleProps} from 'react-beautiful-dnd';
|
|
19
|
+
|
|
20
|
+
import type {NavigateFunction} from '@parca/functions';
|
|
21
|
+
import {CloseIcon} from '@parca/icons';
|
|
22
|
+
|
|
23
|
+
import ViewSelector from './ViewSelector';
|
|
24
|
+
|
|
25
|
+
interface Props {
|
|
26
|
+
dashboardItem: string;
|
|
27
|
+
index: number;
|
|
28
|
+
isMultiPanelView: boolean;
|
|
29
|
+
handleClosePanel: (dashboardItem: string) => void;
|
|
30
|
+
navigateTo: NavigateFunction | undefined;
|
|
31
|
+
dragHandleProps: DraggableProvidedDragHandleProps | null | undefined;
|
|
32
|
+
getDashboardItemByType: (props: {
|
|
33
|
+
type: string;
|
|
34
|
+
isHalfScreen: boolean;
|
|
35
|
+
setActionButtons: (actionButtons: JSX.Element) => void;
|
|
36
|
+
}) => JSX.Element;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export const VisualizationPanel = React.memo(function VisualizationPanel({
|
|
40
|
+
dashboardItem,
|
|
41
|
+
index,
|
|
42
|
+
isMultiPanelView,
|
|
43
|
+
handleClosePanel,
|
|
44
|
+
navigateTo,
|
|
45
|
+
dragHandleProps,
|
|
46
|
+
getDashboardItemByType,
|
|
47
|
+
}: Props): JSX.Element {
|
|
48
|
+
const [actionButtons, setActionButtons] = useState<JSX.Element>(<></>);
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<>
|
|
52
|
+
<div className="w-full flex justify-end pb-2">
|
|
53
|
+
<div className="w-full flex justify-between items-center">
|
|
54
|
+
<div className="flex">
|
|
55
|
+
<div
|
|
56
|
+
className={cx(isMultiPanelView ? 'visible' : 'invisible', 'flex items-center')}
|
|
57
|
+
{...dragHandleProps}
|
|
58
|
+
>
|
|
59
|
+
<Icon className="text-xl" icon="material-symbols:drag-indicator" />
|
|
60
|
+
</div>
|
|
61
|
+
<>{actionButtons}</>
|
|
62
|
+
</div>
|
|
63
|
+
<ViewSelector defaultValue={dashboardItem} navigateTo={navigateTo} position={index} />
|
|
64
|
+
</div>
|
|
65
|
+
|
|
66
|
+
{isMultiPanelView && (
|
|
67
|
+
<button type="button" onClick={() => handleClosePanel(dashboardItem)} className="pl-2">
|
|
68
|
+
<CloseIcon />
|
|
69
|
+
</button>
|
|
70
|
+
)}
|
|
71
|
+
</div>
|
|
72
|
+
{getDashboardItemByType({
|
|
73
|
+
type: dashboardItem,
|
|
74
|
+
isHalfScreen: isMultiPanelView,
|
|
75
|
+
setActionButtons,
|
|
76
|
+
})}
|
|
77
|
+
</>
|
|
78
|
+
);
|
|
79
|
+
});
|