Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boxiang Sun
gitlab-ce
Commits
e7bb9b95
Commit
e7bb9b95
authored
Feb 01, 2019
by
Adriel Santiago
Committed by
Phil Hughes
Feb 01, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove d3 metrics graph
parent
c1286332
Changes
24
Show whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
2 additions
and
1868 deletions
+2
-1868
app/assets/javascripts/monitoring/components/dashboard.vue
app/assets/javascripts/monitoring/components/dashboard.vue
+2
-34
app/assets/javascripts/monitoring/components/graph.vue
app/assets/javascripts/monitoring/components/graph.vue
+0
-329
app/assets/javascripts/monitoring/components/graph/axis.vue
app/assets/javascripts/monitoring/components/graph/axis.vue
+0
-118
app/assets/javascripts/monitoring/components/graph/deployment.vue
...ts/javascripts/monitoring/components/graph/deployment.vue
+0
-48
app/assets/javascripts/monitoring/components/graph/flag.vue
app/assets/javascripts/monitoring/components/graph/flag.vue
+0
-151
app/assets/javascripts/monitoring/components/graph/legend.vue
...assets/javascripts/monitoring/components/graph/legend.vue
+0
-62
app/assets/javascripts/monitoring/components/graph/path.vue
app/assets/javascripts/monitoring/components/graph/path.vue
+0
-65
app/assets/javascripts/monitoring/components/graph/track_info.vue
...ts/javascripts/monitoring/components/graph/track_info.vue
+0
-28
app/assets/javascripts/monitoring/components/graph/track_line.vue
...ts/javascripts/monitoring/components/graph/track_line.vue
+0
-33
app/assets/javascripts/monitoring/event_hub.js
app/assets/javascripts/monitoring/event_hub.js
+0
-3
app/assets/javascripts/monitoring/mixins/monitoring_mixins.js
...assets/javascripts/monitoring/mixins/monitoring_mixins.js
+0
-86
app/assets/javascripts/monitoring/utils/date_time_formatters.js
...sets/javascripts/monitoring/utils/date_time_formatters.js
+0
-42
app/assets/javascripts/monitoring/utils/measurements.js
app/assets/javascripts/monitoring/utils/measurements.js
+0
-44
app/assets/javascripts/monitoring/utils/multiple_time_series.js
...sets/javascripts/monitoring/utils/multiple_time_series.js
+0
-223
locale/gitlab.pot
locale/gitlab.pot
+0
-6
spec/javascripts/monitoring/graph/axis_spec.js
spec/javascripts/monitoring/graph/axis_spec.js
+0
-65
spec/javascripts/monitoring/graph/deployment_spec.js
spec/javascripts/monitoring/graph/deployment_spec.js
+0
-53
spec/javascripts/monitoring/graph/flag_spec.js
spec/javascripts/monitoring/graph/flag_spec.js
+0
-133
spec/javascripts/monitoring/graph/legend_spec.js
spec/javascripts/monitoring/graph/legend_spec.js
+0
-44
spec/javascripts/monitoring/graph/track_info_spec.js
spec/javascripts/monitoring/graph/track_info_spec.js
+0
-44
spec/javascripts/monitoring/graph/track_line_spec.js
spec/javascripts/monitoring/graph/track_line_spec.js
+0
-52
spec/javascripts/monitoring/graph_path_spec.js
spec/javascripts/monitoring/graph_path_spec.js
+0
-56
spec/javascripts/monitoring/graph_spec.js
spec/javascripts/monitoring/graph_spec.js
+0
-127
spec/javascripts/monitoring/utils/multiple_time_series_spec.js
...javascripts/monitoring/utils/multiple_time_series_spec.js
+0
-22
No files found.
app/assets/javascripts/monitoring/components/dashboard.vue
View file @
e7bb9b95
...
...
@@ -6,15 +6,12 @@ import Flash from '../../flash';
import
MonitoringService
from
'
../services/monitoring_service
'
;
import
MonitorAreaChart
from
'
./charts/area.vue
'
;
import
GraphGroup
from
'
./graph_group.vue
'
;
import
Graph
from
'
./graph.vue
'
;
import
EmptyState
from
'
./empty_state.vue
'
;
import
MonitoringStore
from
'
../stores/monitoring_store
'
;
import
eventHub
from
'
../event_hub
'
;
export
default
{
components
:
{
MonitorAreaChart
,
Graph
,
GraphGroup
,
EmptyState
,
Icon
,
...
...
@@ -25,21 +22,11 @@ export default {
required
:
false
,
default
:
true
,
},
showLegend
:
{
type
:
Boolean
,
required
:
false
,
default
:
true
,
},
showPanels
:
{
type
:
Boolean
,
required
:
false
,
default
:
true
,
},
forceSmallGraph
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
},
documentationPath
:
{
type
:
String
,
required
:
true
,
...
...
@@ -99,14 +86,10 @@ export default {
store
:
new
MonitoringStore
(),
state
:
'
gettingStarted
'
,
showEmptyState
:
true
,
hoverData
:
{},
elWidth
:
0
,
};
},
computed
:
{
graphComponent
()
{
return
gon
.
features
&&
gon
.
features
.
areaChart
?
MonitorAreaChart
:
Graph
;
},
forceRedraw
()
{
return
this
.
elWidth
;
},
...
...
@@ -122,10 +105,8 @@ export default {
childList
:
false
,
subtree
:
false
,
};
eventHub
.
$on
(
'
hoverChanged
'
,
this
.
hoverChanged
);
},
beforeDestroy
()
{
eventHub
.
$off
(
'
hoverChanged
'
,
this
.
hoverChanged
);
window
.
removeEventListener
(
'
resize
'
,
this
.
resizeThrottled
,
false
);
this
.
sidebarMutationObserver
.
disconnect
();
},
...
...
@@ -176,9 +157,6 @@ export default {
resize
()
{
this
.
elWidth
=
this
.
$el
.
clientWidth
;
},
hoverChanged
(
data
)
{
this
.
hoverData
=
data
;
},
},
};
</
script
>
...
...
@@ -215,23 +193,13 @@ export default {
:name=
"groupData.group"
:show-panels=
"showPanels"
>
<component
:is=
"graphComponent"
<monitor-area-chart
v-for=
"(graphData, graphIndex) in groupData.metrics"
:key=
"graphIndex"
:graph-data=
"graphData"
:hover-data=
"hoverData"
:deployment-data=
"store.deploymentData"
:project-path=
"projectPath"
:tags-path=
"tagsPath"
:show-legend=
"showLegend"
:small-graph=
"forceSmallGraph"
:alert-data=
"getGraphAlerts(graphData.id)"
group-id=
"monitor-area-chart"
>
<!-- EE content -->
{{
null
}}
</component>
/>
</graph-group>
</div>
<empty-state
...
...
app/assets/javascripts/monitoring/components/graph.vue
deleted
100644 → 0
View file @
c1286332
<
script
>
import
{
scaleLinear
,
scaleTime
}
from
'
d3-scale
'
;
import
{
axisLeft
,
axisBottom
}
from
'
d3-axis
'
;
import
_
from
'
underscore
'
;
import
{
max
,
extent
}
from
'
d3-array
'
;
import
{
select
}
from
'
d3-selection
'
;
import
GraphAxis
from
'
./graph/axis.vue
'
;
import
GraphLegend
from
'
./graph/legend.vue
'
;
import
GraphFlag
from
'
./graph/flag.vue
'
;
import
GraphDeployment
from
'
./graph/deployment.vue
'
;
import
GraphPath
from
'
./graph/path.vue
'
;
import
MonitoringMixin
from
'
../mixins/monitoring_mixins
'
;
import
eventHub
from
'
../event_hub
'
;
import
measurements
from
'
../utils/measurements
'
;
import
{
bisectDate
,
timeScaleFormat
}
from
'
../utils/date_time_formatters
'
;
import
createTimeSeries
from
'
../utils/multiple_time_series
'
;
import
bp
from
'
../../breakpoints
'
;
const
d3
=
{
scaleLinear
,
scaleTime
,
axisLeft
,
axisBottom
,
max
,
extent
,
select
};
export
default
{
components
:
{
GraphAxis
,
GraphFlag
,
GraphDeployment
,
GraphPath
,
GraphLegend
,
},
mixins
:
[
MonitoringMixin
],
props
:
{
graphData
:
{
type
:
Object
,
required
:
true
,
},
deploymentData
:
{
type
:
Array
,
required
:
true
,
},
hoverData
:
{
type
:
Object
,
required
:
false
,
default
:
()
=>
({}),
},
projectPath
:
{
type
:
String
,
required
:
true
,
},
tagsPath
:
{
type
:
String
,
required
:
true
,
},
showLegend
:
{
type
:
Boolean
,
required
:
false
,
default
:
true
,
},
smallGraph
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
},
},
data
()
{
return
{
baseGraphHeight
:
450
,
baseGraphWidth
:
600
,
graphHeight
:
450
,
graphWidth
:
600
,
graphHeightOffset
:
120
,
margin
:
{},
unitOfDisplay
:
''
,
yAxisLabel
:
''
,
legendTitle
:
''
,
reducedDeploymentData
:
[],
measurements
:
measurements
.
large
,
currentData
:
{
time
:
new
Date
(),
value
:
0
,
},
currentXCoordinate
:
0
,
currentCoordinates
:
{},
showFlag
:
false
,
showFlagContent
:
false
,
timeSeries
:
[],
graphDrawData
:
{},
realPixelRatio
:
1
,
seriesUnderMouse
:
[],
};
},
computed
:
{
outerViewBox
()
{
return
`0 0
${
this
.
baseGraphWidth
}
${
this
.
baseGraphHeight
}
`
;
},
innerViewBox
()
{
return
`0 0
${
this
.
baseGraphWidth
-
150
}
${
this
.
baseGraphHeight
}
`
;
},
axisTransform
()
{
return
`translate(70,
${
this
.
graphHeight
-
100
}
)`
;
},
paddingBottomRootSvg
()
{
return
{
paddingBottom
:
`
${
Math
.
ceil
(
this
.
baseGraphHeight
*
100
)
/
this
.
baseGraphWidth
||
0
}
%`
,
};
},
deploymentFlagData
()
{
return
this
.
reducedDeploymentData
.
find
(
deployment
=>
deployment
.
showDeploymentFlag
);
},
shouldRenderData
()
{
return
this
.
graphData
.
queries
.
filter
(
s
=>
s
.
result
.
length
>
0
).
length
>
0
;
},
},
watch
:
{
hoverData
()
{
this
.
positionFlag
();
},
},
mounted
()
{
this
.
draw
();
},
methods
:
{
showDot
(
path
)
{
return
this
.
showFlagContent
&&
this
.
seriesUnderMouse
.
includes
(
path
);
},
draw
()
{
const
breakpointSize
=
bp
.
getBreakpointSize
();
const
svgWidth
=
this
.
$refs
.
baseSvg
.
getBoundingClientRect
().
width
;
this
.
margin
=
measurements
.
large
.
margin
;
if
(
this
.
smallGraph
||
breakpointSize
===
'
xs
'
||
breakpointSize
===
'
sm
'
)
{
this
.
graphHeight
=
300
;
this
.
margin
=
measurements
.
small
.
margin
;
this
.
measurements
=
measurements
.
small
;
}
this
.
yAxisLabel
=
this
.
graphData
.
y_label
||
'
Values
'
;
this
.
graphWidth
=
svgWidth
-
this
.
margin
.
left
-
this
.
margin
.
right
;
this
.
graphHeight
=
this
.
graphHeight
-
this
.
margin
.
top
-
this
.
margin
.
bottom
;
this
.
baseGraphHeight
=
this
.
graphHeight
-
50
;
this
.
baseGraphWidth
=
this
.
graphWidth
;
// pixel offsets inside the svg and outside are not 1:1
this
.
realPixelRatio
=
svgWidth
/
this
.
baseGraphWidth
;
// set the legends on the axes
const
[
query
]
=
this
.
graphData
.
queries
;
this
.
legendTitle
=
query
?
query
.
label
:
'
Average
'
;
this
.
unitOfDisplay
=
query
?
query
.
unit
:
''
;
if
(
this
.
shouldRenderData
)
{
this
.
renderAxesPaths
();
this
.
formatDeployments
();
}
},
handleMouseOverGraph
(
e
)
{
let
point
=
this
.
$refs
.
graphData
.
createSVGPoint
();
point
.
x
=
e
.
clientX
;
point
.
y
=
e
.
clientY
;
point
=
point
.
matrixTransform
(
this
.
$refs
.
graphData
.
getScreenCTM
().
inverse
());
point
.
x
+=
7
;
this
.
seriesUnderMouse
=
this
.
timeSeries
.
filter
(
series
=>
{
const
mouseX
=
series
.
timeSeriesScaleX
.
invert
(
point
.
x
);
let
minDistance
=
Infinity
;
const
closestTickMark
=
Object
.
keys
(
this
.
allXAxisValues
).
reduce
((
closest
,
x
)
=>
{
const
distance
=
Math
.
abs
(
Number
(
new
Date
(
x
))
-
Number
(
mouseX
));
if
(
distance
<
minDistance
)
{
minDistance
=
distance
;
return
x
;
}
return
closest
;
});
return
series
.
values
.
find
(
v
=>
v
.
time
.
toString
()
===
closestTickMark
);
});
const
firstTimeSeries
=
this
.
seriesUnderMouse
[
0
];
const
timeValueOverlay
=
firstTimeSeries
.
timeSeriesScaleX
.
invert
(
point
.
x
);
const
overlayIndex
=
bisectDate
(
firstTimeSeries
.
values
,
timeValueOverlay
,
1
);
const
d0
=
firstTimeSeries
.
values
[
overlayIndex
-
1
];
const
d1
=
firstTimeSeries
.
values
[
overlayIndex
];
if
(
d0
===
undefined
||
d1
===
undefined
)
return
;
const
evalTime
=
timeValueOverlay
-
d0
[
0
]
>
d1
[
0
]
-
timeValueOverlay
;
const
hoveredDataIndex
=
evalTime
?
overlayIndex
:
overlayIndex
-
1
;
const
hoveredDate
=
firstTimeSeries
.
values
[
hoveredDataIndex
].
time
;
const
currentDeployXPos
=
this
.
mouseOverDeployInfo
(
point
.
x
);
eventHub
.
$emit
(
'
hoverChanged
'
,
{
hoveredDate
,
currentDeployXPos
,
});
},
renderAxesPaths
()
{
({
timeSeries
:
this
.
timeSeries
,
graphDrawData
:
this
.
graphDrawData
}
=
createTimeSeries
(
this
.
graphData
.
queries
,
this
.
graphWidth
,
this
.
graphHeight
,
this
.
graphHeightOffset
,
));
if
(
_
.
findWhere
(
this
.
timeSeries
,
{
renderCanary
:
true
}))
{
this
.
timeSeries
=
this
.
timeSeries
.
map
(
series
=>
({
...
series
,
renderCanary
:
true
}));
}
const
axisXScale
=
d3
.
scaleTime
().
range
([
0
,
this
.
graphWidth
-
70
]);
const
axisYScale
=
d3
.
scaleLinear
().
range
([
this
.
graphHeight
-
this
.
graphHeightOffset
,
0
]);
const
allValues
=
this
.
timeSeries
.
reduce
((
all
,
{
values
})
=>
all
.
concat
(
values
),
[]);
axisXScale
.
domain
(
d3
.
extent
(
allValues
,
d
=>
d
.
time
));
axisYScale
.
domain
([
0
,
d3
.
max
(
allValues
.
map
(
d
=>
d
.
value
))]);
this
.
allXAxisValues
=
this
.
timeSeries
.
reduce
((
obj
,
series
)
=>
{
const
seriesKeys
=
{};
series
.
values
.
forEach
(
v
=>
{
seriesKeys
[
v
.
time
]
=
true
;
});
return
{
...
obj
,
...
seriesKeys
,
};
},
{});
const
xAxis
=
d3
.
axisBottom
()
.
scale
(
axisXScale
)
.
ticks
(
this
.
graphWidth
/
120
)
.
tickFormat
(
timeScaleFormat
);
const
yAxis
=
d3
.
axisLeft
()
.
scale
(
axisYScale
)
.
ticks
(
measurements
.
yTicks
);
d3
.
select
(
this
.
$refs
.
baseSvg
)
.
select
(
'
.x-axis
'
)
.
call
(
xAxis
);
const
width
=
this
.
graphWidth
;
d3
.
select
(
this
.
$refs
.
baseSvg
)
.
select
(
'
.y-axis
'
)
.
call
(
yAxis
)
.
selectAll
(
'
.tick
'
)
.
each
(
function
createTickLines
(
d
,
i
)
{
if
(
i
>
0
)
{
d3
.
select
(
this
)
.
select
(
'
line
'
)
.
attr
(
'
x2
'
,
width
)
.
attr
(
'
class
'
,
'
axis-tick
'
);
}
// Avoid adding the class to the first tick, to prevent coloring
});
// This will select all of the ticks once they're rendered
},
},
};
</
script
>
<
template
>
<div
class=
"prometheus-graph"
@
mouseover=
"showFlagContent = true"
@
mouseleave=
"showFlagContent = false"
>
<div
class=
"prometheus-graph-header"
>
<h5
class=
"prometheus-graph-title"
>
{{
graphData
.
title
}}
</h5>
<div
class=
"prometheus-graph-widgets"
><slot></slot></div>
</div>
<div
:style=
"paddingBottomRootSvg"
class=
"prometheus-svg-container"
>
<svg
ref=
"baseSvg"
:viewBox=
"outerViewBox"
>
<g
:transform=
"axisTransform"
class=
"x-axis"
/>
<g
class=
"y-axis"
transform=
"translate(70, 20)"
/>
<graph-axis
:graph-width=
"graphWidth"
:graph-height=
"graphHeight"
:margin=
"margin"
:measurements=
"measurements"
:y-axis-label=
"yAxisLabel"
:unit-of-display=
"unitOfDisplay"
/>
<svg
v-if=
"shouldRenderData"
ref=
"graphData"
:viewBox=
"innerViewBox"
class=
"graph-data"
>
<slot
name=
"additionalSvgContent"
:graphDrawData=
"graphDrawData"
/>
<graph-path
v-for=
"(path, index) in timeSeries"
:key=
"index"
:generated-line-path=
"path.linePath"
:generated-area-path=
"path.areaPath"
:line-style=
"path.lineStyle"
:line-color=
"path.lineColor"
:area-color=
"path.areaColor"
:current-coordinates=
"currentCoordinates[path.metricTag]"
:show-dot=
"showDot(path)"
/>
<graph-deployment
:deployment-data=
"reducedDeploymentData"
:graph-height=
"graphHeight"
:graph-height-offset=
"graphHeightOffset"
/>
<rect
ref=
"graphOverlay"
:width=
"graphWidth - 70"
:height=
"graphHeight - 100"
class=
"prometheus-graph-overlay"
transform=
"translate(-5, 20)"
@
mousemove=
"handleMouseOverGraph($event)"
/>
</svg>
<svg
v-else
:viewBox=
"innerViewBox"
class=
"js-no-data-to-display"
>
<text
x=
"50%"
y=
"50%"
alignment-baseline=
"middle"
text-anchor=
"middle"
>
{{
s__
(
'
Metrics|No data to display
'
)
}}
</text>
</svg>
</svg>
<graph-flag
v-if=
"shouldRenderData"
:real-pixel-ratio=
"realPixelRatio"
:current-x-coordinate=
"currentXCoordinate"
:current-data=
"currentData"
:graph-height=
"graphHeight"
:graph-height-offset=
"graphHeightOffset"
:show-flag-content=
"showFlagContent"
:time-series=
"seriesUnderMouse"
:unit-of-display=
"unitOfDisplay"
:legend-title=
"legendTitle"
:deployment-flag-data=
"deploymentFlagData"
:current-coordinates=
"currentCoordinates"
/>
</div>
<graph-legend
v-if=
"showLegend"
:legend-title=
"legendTitle"
:time-series=
"timeSeries"
/>
</div>
</
template
>
app/assets/javascripts/monitoring/components/graph/axis.vue
deleted
100644 → 0
View file @
c1286332
<
script
>
import
{
convertToSentenceCase
}
from
'
~/lib/utils/text_utility
'
;
import
{
s__
}
from
'
~/locale
'
;
export
default
{
props
:
{
graphWidth
:
{
type
:
Number
,
required
:
true
,
},
graphHeight
:
{
type
:
Number
,
required
:
true
,
},
margin
:
{
type
:
Object
,
required
:
true
,
},
measurements
:
{
type
:
Object
,
required
:
true
,
},
yAxisLabel
:
{
type
:
String
,
required
:
true
,
},
unitOfDisplay
:
{
type
:
String
,
required
:
true
,
},
},
data
()
{
return
{
yLabelWidth
:
0
,
yLabelHeight
:
0
,
};
},
computed
:
{
textTransform
()
{
const
yCoordinate
=
(
this
.
graphHeight
-
this
.
margin
.
top
+
this
.
measurements
.
axisLabelLineOffset
)
/
2
||
0
;
return
`translate(15,
${
yCoordinate
}
) rotate(-90)`
;
},
rectTransform
()
{
const
yCoordinate
=
(
this
.
graphHeight
-
this
.
margin
.
top
+
this
.
measurements
.
axisLabelLineOffset
)
/
2
+
this
.
yLabelWidth
/
2
||
0
;
return
`translate(0,
${
yCoordinate
}
) rotate(-90)`
;
},
xPosition
()
{
return
(
this
.
graphWidth
+
this
.
measurements
.
axisLabelLineOffset
)
/
2
-
this
.
margin
.
right
||
0
;
},
yPosition
()
{
return
this
.
graphHeight
-
this
.
margin
.
top
+
this
.
measurements
.
axisLabelLineOffset
||
0
;
},
yAxisLabelSentenceCase
()
{
return
`
${
convertToSentenceCase
(
this
.
yAxisLabel
)}
(
${
this
.
unitOfDisplay
}
)`
;
},
timeString
()
{
return
s__
(
'
PrometheusDashboard|Time
'
);
},
},
mounted
()
{
this
.
$nextTick
(()
=>
{
const
bbox
=
this
.
$refs
.
ylabel
.
getBBox
();
this
.
yLabelWidth
=
bbox
.
width
+
10
;
// Added some padding
this
.
yLabelHeight
=
bbox
.
height
+
5
;
});
},
};
</
script
>
<
template
>
<g
class=
"axis-label-container"
>
<line
:y1=
"yPosition"
:x2=
"graphWidth + 20"
:y2=
"yPosition"
class=
"label-x-axis-line"
stroke=
"#000000"
stroke-width=
"1"
x1=
"10"
/>
<line
:x2=
"10"
:y2=
"yPosition"
class=
"label-y-axis-line"
stroke=
"#000000"
stroke-width=
"1"
x1=
"10"
y1=
"0"
/>
<rect
:transform=
"rectTransform"
:width=
"yLabelWidth"
:height=
"yLabelHeight"
class=
"rect-axis-text"
/>
<text
ref=
"ylabel"
:transform=
"textTransform"
class=
"label-axis-text y-label-text"
text-anchor=
"middle"
>
{{
yAxisLabelSentenceCase
}}
</text>
<rect
:x=
"xPosition + 60"
:y=
"graphHeight - 80"
class=
"rect-axis-text"
width=
"35"
height=
"50"
/>
<text
:x=
"xPosition + 60"
:y=
"yPosition"
class=
"label-axis-text x-label-text"
dy=
".35em"
>
{{
timeString
}}
</text>
</g>
</
template
>
app/assets/javascripts/monitoring/components/graph/deployment.vue
deleted
100644 → 0
View file @
c1286332
<
script
>
export
default
{
props
:
{
deploymentData
:
{
type
:
Array
,
required
:
true
,
},
graphHeight
:
{
type
:
Number
,
required
:
true
,
},
graphHeightOffset
:
{
type
:
Number
,
required
:
true
,
},
},
computed
:
{
calculatedHeight
()
{
return
this
.
graphHeight
-
this
.
graphHeightOffset
;
},
},
methods
:
{
transformDeploymentGroup
(
deployment
)
{
return
`translate(
${
Math
.
floor
(
deployment
.
xPos
)
-
5
}
, 20)`
;
},
},
};
</
script
>
<
template
>
<g
class=
"deploy-info"
>
<g
v-for=
"(deployment, index) in deploymentData"
:key=
"index"
:transform=
"transformDeploymentGroup(deployment)"
>
<rect
:height=
"calculatedHeight"
x=
"0"
y=
"0"
width=
"3"
fill=
"url(#shadow-gradient)"
/>
<line
:y2=
"calculatedHeight"
class=
"deployment-line"
x1=
"0"
y1=
"0"
x2=
"0"
stroke=
"#000"
/>
</g>
<svg
height=
"0"
width=
"0"
>
<defs>
<linearGradient
id=
"shadow-gradient"
>
<stop
offset=
"0%"
stop-color=
"#000"
stop-opacity=
"0.4"
/>
<stop
offset=
"100%"
stop-color=
"#000"
stop-opacity=
"0"
/>
</linearGradient>
</defs>
</svg>
</g>
</
template
>
app/assets/javascripts/monitoring/components/graph/flag.vue
deleted
100644 → 0
View file @
c1286332
<
script
>
import
{
dateFormat
,
timeFormat
}
from
'
../../utils/date_time_formatters
'
;
import
{
formatRelevantDigits
}
from
'
../../../lib/utils/number_utils
'
;
import
Icon
from
'
../../../vue_shared/components/icon.vue
'
;
import
TrackLine
from
'
./track_line.vue
'
;
export
default
{
components
:
{
Icon
,
TrackLine
,
},
props
:
{
currentXCoordinate
:
{
type
:
Number
,
required
:
true
,
},
currentData
:
{
type
:
Object
,
required
:
true
,
},
deploymentFlagData
:
{
type
:
Object
,
required
:
false
,
default
:
null
,
},
graphHeight
:
{
type
:
Number
,
required
:
true
,
},
graphHeightOffset
:
{
type
:
Number
,
required
:
true
,
},
realPixelRatio
:
{
type
:
Number
,
required
:
true
,
},
showFlagContent
:
{
type
:
Boolean
,
required
:
true
,
},
timeSeries
:
{
type
:
Array
,
required
:
true
,
},
unitOfDisplay
:
{
type
:
String
,
required
:
true
,
},
legendTitle
:
{
type
:
String
,
required
:
true
,
},
currentCoordinates
:
{
type
:
Object
,
required
:
true
,
},
},
computed
:
{
formatTime
()
{
return
this
.
deploymentFlagData
?
timeFormat
(
this
.
deploymentFlagData
.
time
)
:
timeFormat
(
this
.
currentData
.
time
);
},
formatDate
()
{
return
this
.
deploymentFlagData
?
dateFormat
(
this
.
deploymentFlagData
.
time
)
:
dateFormat
(
this
.
currentData
.
time
);
},
cursorStyle
()
{
const
xCoordinate
=
this
.
deploymentFlagData
?
this
.
deploymentFlagData
.
xPos
:
this
.
currentXCoordinate
;
const
offsetTop
=
20
*
this
.
realPixelRatio
;
const
offsetLeft
=
(
70
+
xCoordinate
)
*
this
.
realPixelRatio
;
const
height
=
(
this
.
graphHeight
-
this
.
graphHeightOffset
)
*
this
.
realPixelRatio
;
return
{
top
:
`
${
offsetTop
}
px`
,
left
:
`
${
offsetLeft
}
px`
,
height
:
`
${
height
}
px`
,
};
},
flagOrientation
()
{
if
(
this
.
currentXCoordinate
*
this
.
realPixelRatio
>
120
)
{
return
'
left
'
;
}
return
'
right
'
;
},
},
methods
:
{
seriesMetricValue
(
seriesIndex
,
series
)
{
const
indexFromCoordinates
=
this
.
currentCoordinates
[
series
.
metricTag
]
?
this
.
currentCoordinates
[
series
.
metricTag
].
currentDataIndex
:
0
;
const
index
=
this
.
deploymentFlagData
?
this
.
deploymentFlagData
.
seriesIndex
:
indexFromCoordinates
;
const
value
=
series
.
values
[
index
]
&&
series
.
values
[
index
].
value
;
if
(
Number
.
isNaN
(
value
))
{
return
'
-
'
;
}
return
`
${
formatRelevantDigits
(
value
)}${
this
.
unitOfDisplay
}
`
;
},
seriesMetricLabel
(
index
,
series
)
{
if
(
this
.
timeSeries
.
length
<
2
)
{
return
this
.
legendTitle
;
}
if
(
series
.
metricTag
)
{
return
series
.
metricTag
;
}
return
`series
${
index
+
1
}
`
;
},
},
};
</
script
>
<
template
>
<div
:style=
"cursorStyle"
class=
"prometheus-graph-cursor"
>
<div
v-if=
"showFlagContent"
:class=
"flagOrientation"
class=
"prometheus-graph-flag popover"
>
<div
class=
"arrow-shadow"
></div>
<div
class=
"arrow"
></div>
<div
class=
"popover-title"
>
<h5
v-if=
"deploymentFlagData"
>
Deployed
</h5>
{{
formatDate
}}
<strong>
{{
formatTime
}}
</strong>
</div>
<div
v-if=
"deploymentFlagData"
class=
"popover-content deploy-meta-content"
>
<div>
<icon
:size=
"12"
name=
"commit"
/>
<a
:href=
"deploymentFlagData.commitUrl"
>
{{
deploymentFlagData
.
sha
.
slice
(
0
,
8
)
}}
</a>
</div>
<div
v-if=
"deploymentFlagData.tag"
>
<icon
:size=
"12"
name=
"label"
/>
<a
:href=
"deploymentFlagData.tagUrl"
>
{{
deploymentFlagData
.
ref
}}
</a>
</div>
</div>
<div
class=
"popover-content"
>
<table
class=
"prometheus-table"
>
<tr
v-for=
"(series, index) in timeSeries"
:key=
"index"
>
<track-line
:track=
"series"
/>
<td>
{{
series
.
track
}}
{{
seriesMetricLabel
(
index
,
series
)
}}
</td>
<td>
<strong>
{{
seriesMetricValue
(
index
,
series
)
}}
</strong>
</td>
</tr>
</table>
</div>
</div>
</div>
</
template
>
app/assets/javascripts/monitoring/components/graph/legend.vue
deleted
100644 → 0
View file @
c1286332
<
script
>
import
TrackLine
from
'
./track_line.vue
'
;
import
TrackInfo
from
'
./track_info.vue
'
;
export
default
{
components
:
{
TrackLine
,
TrackInfo
,
},
props
:
{
legendTitle
:
{
type
:
String
,
required
:
true
,
},
timeSeries
:
{
type
:
Array
,
required
:
true
,
},
},
methods
:
{
isStable
(
track
)
{
return
{
'
prometheus-table-row-highlight
'
:
track
.
trackName
!==
'
Canary
'
&&
track
.
renderCanary
,
};
},
},
};
</
script
>
<
template
>
<div
class=
"prometheus-graph-legends prepend-left-10"
>
<table
class=
"prometheus-table"
>
<tr
v-for=
"(series, index) in timeSeries"
v-if=
"series.shouldRenderLegend"
:key=
"index"
:class=
"isStable(series)"
>
<td>
<strong
v-if=
"series.renderCanary"
>
{{
series
.
trackName
}}
</strong>
</td>
<track-line
:track=
"series"
/>
<td
v-if=
"timeSeries.length > 1"
class=
"legend-metric-title"
>
<track-info
v-if=
"series.metricTag"
:track=
"series"
/>
<track-info
v-else
:track=
"series"
>
<strong>
{{
legendTitle
}}
</strong>
series
{{
index
+
1
}}
</track-info>
</td>
<td
v-else
>
<track-info
:track=
"series"
>
<strong>
{{
legendTitle
}}
</strong>
</track-info>
</td>
<template
v-for=
"(track, trackIndex) in series.tracksLegend"
>
<track-line
:key=
"`track-line-$
{trackIndex}`" :track="track" />
<td
:key=
"`track-info-$
{trackIndex}`">
<track-info
:track=
"track"
class=
"legend-metric-title"
/>
</td>
</
template
>
</tr>
</table>
</div>
</template>
app/assets/javascripts/monitoring/components/graph/path.vue
deleted
100644 → 0
View file @
c1286332
<
script
>
export
default
{
props
:
{
generatedLinePath
:
{
type
:
String
,
required
:
true
,
},
generatedAreaPath
:
{
type
:
String
,
required
:
true
,
},
lineStyle
:
{
type
:
String
,
required
:
false
,
default
:
''
,
},
lineColor
:
{
type
:
String
,
required
:
true
,
},
areaColor
:
{
type
:
String
,
required
:
true
,
},
currentCoordinates
:
{
type
:
Object
,
required
:
false
,
default
:
()
=>
({
currentX
:
0
,
currentY
:
0
}),
},
showDot
:
{
type
:
Boolean
,
required
:
true
,
},
},
computed
:
{
strokeDashArray
()
{
if
(
this
.
lineStyle
===
'
dashed
'
)
return
'
3, 1
'
;
if
(
this
.
lineStyle
===
'
dotted
'
)
return
'
1, 1
'
;
return
null
;
},
},
};
</
script
>
<
template
>
<g
transform=
"translate(-5, 20)"
>
<circle
v-if=
"showDot"
:cx=
"currentCoordinates.currentX"
:cy=
"currentCoordinates.currentY"
:fill=
"lineColor"
:stroke=
"lineColor"
class=
"circle-path"
r=
"3"
/>
<path
:d=
"generatedAreaPath"
:fill=
"areaColor"
class=
"metric-area"
/>
<path
:d=
"generatedLinePath"
:stroke=
"lineColor"
:stroke-dasharray=
"strokeDashArray"
class=
"metric-line"
fill=
"none"
stroke-width=
"1"
/>
</g>
</
template
>
app/assets/javascripts/monitoring/components/graph/track_info.vue
deleted
100644 → 0
View file @
c1286332
<
script
>
import
{
formatRelevantDigits
}
from
'
~/lib/utils/number_utils
'
;
export
default
{
name
:
'
TrackInfo
'
,
props
:
{
track
:
{
type
:
Object
,
required
:
true
,
},
},
computed
:
{
summaryMetrics
()
{
return
`Avg:
${
formatRelevantDigits
(
this
.
track
.
average
)}
· Max:
${
formatRelevantDigits
(
this
.
track
.
max
,
)}
`
;
},
},
};
</
script
>
<
template
>
<span>
<slot>
<strong>
{{
track
.
metricTag
}}
</strong>
</slot>
{{
summaryMetrics
}}
</span>
</
template
>
app/assets/javascripts/monitoring/components/graph/track_line.vue
deleted
100644 → 0
View file @
c1286332
<
script
>
export
default
{
name
:
'
TrackLine
'
,
props
:
{
track
:
{
type
:
Object
,
required
:
true
,
},
},
computed
:
{
stylizedLine
()
{
if
(
this
.
track
.
lineStyle
===
'
dashed
'
)
return
'
6, 3
'
;
if
(
this
.
track
.
lineStyle
===
'
dotted
'
)
return
'
3, 3
'
;
return
null
;
},
},
};
</
script
>
<
template
>
<td>
<svg
width=
"16"
height=
"8"
>
<line
:stroke-dasharray=
"stylizedLine"
:stroke=
"track.lineColor"
:x1=
"0"
:x2=
"16"
:y1=
"4"
:y2=
"4"
stroke-width=
"4"
/>
</svg>
</td>
</
template
>
app/assets/javascripts/monitoring/event_hub.js
deleted
100644 → 0
View file @
c1286332
import
Vue
from
'
vue
'
;
export
default
new
Vue
();
app/assets/javascripts/monitoring/mixins/monitoring_mixins.js
deleted
100644 → 0
View file @
c1286332
import
{
bisectDate
}
from
'
../utils/date_time_formatters
'
;
const
mixins
=
{
methods
:
{
mouseOverDeployInfo
(
mouseXPos
)
{
if
(
!
this
.
reducedDeploymentData
)
return
false
;
let
dataFound
=
false
;
this
.
reducedDeploymentData
=
this
.
reducedDeploymentData
.
map
(
d
=>
{
const
deployment
=
d
;
if
(
d
.
xPos
>=
mouseXPos
-
10
&&
d
.
xPos
<=
mouseXPos
+
10
&&
!
dataFound
)
{
dataFound
=
d
.
xPos
+
1
;
deployment
.
showDeploymentFlag
=
true
;
}
else
{
deployment
.
showDeploymentFlag
=
false
;
}
return
deployment
;
});
return
dataFound
;
},
formatDeployments
()
{
this
.
reducedDeploymentData
=
this
.
deploymentData
.
reduce
((
deploymentDataArray
,
deployment
)
=>
{
const
time
=
new
Date
(
deployment
.
created_at
);
const
xPos
=
Math
.
floor
(
this
.
timeSeries
[
0
].
timeSeriesScaleX
(
time
));
time
.
setSeconds
(
this
.
timeSeries
[
0
].
values
[
0
].
time
.
getSeconds
());
if
(
xPos
>=
0
)
{
const
seriesIndex
=
bisectDate
(
this
.
timeSeries
[
0
].
values
,
time
,
1
);
deploymentDataArray
.
push
({
id
:
deployment
.
id
,
time
,
sha
:
deployment
.
sha
,
commitUrl
:
`
${
this
.
projectPath
}
/commit/
${
deployment
.
sha
}
`
,
tag
:
deployment
.
tag
,
tagUrl
:
deployment
.
tag
?
`
${
this
.
tagsPath
}
/
${
deployment
.
ref
.
name
}
`
:
null
,
ref
:
deployment
.
ref
.
name
,
xPos
,
seriesIndex
,
showDeploymentFlag
:
false
,
});
}
return
deploymentDataArray
;
},
[]);
},
positionFlag
()
{
const
timeSeries
=
this
.
seriesUnderMouse
[
0
];
if
(
!
timeSeries
)
{
return
;
}
const
hoveredDataIndex
=
bisectDate
(
timeSeries
.
values
,
this
.
hoverData
.
hoveredDate
);
this
.
currentData
=
timeSeries
.
values
[
hoveredDataIndex
];
this
.
currentXCoordinate
=
Math
.
floor
(
timeSeries
.
timeSeriesScaleX
(
this
.
currentData
.
time
));
this
.
currentCoordinates
=
{};
this
.
seriesUnderMouse
.
forEach
(
series
=>
{
const
currentDataIndex
=
bisectDate
(
series
.
values
,
this
.
hoverData
.
hoveredDate
);
const
currentData
=
series
.
values
[
currentDataIndex
];
const
currentX
=
Math
.
floor
(
series
.
timeSeriesScaleX
(
currentData
.
time
));
const
currentY
=
Math
.
floor
(
series
.
timeSeriesScaleY
(
currentData
.
value
));
this
.
currentCoordinates
[
series
.
metricTag
]
=
{
currentX
,
currentY
,
currentDataIndex
,
};
});
if
(
this
.
hoverData
.
currentDeployXPos
)
{
this
.
showFlag
=
false
;
}
else
{
this
.
showFlag
=
true
;
}
},
},
};
export
default
mixins
;
app/assets/javascripts/monitoring/utils/date_time_formatters.js
deleted
100644 → 0
View file @
c1286332
import
{
timeFormat
as
time
}
from
'
d3-time-format
'
;
import
{
timeSecond
,
timeMinute
,
timeHour
,
timeDay
,
timeWeek
,
timeMonth
,
timeYear
}
from
'
d3-time
'
;
import
{
bisector
}
from
'
d3-array
'
;
const
d3
=
{
time
,
bisector
,
timeSecond
,
timeMinute
,
timeHour
,
timeDay
,
timeWeek
,
timeMonth
,
timeYear
,
};
export
const
dateFormat
=
d3
.
time
(
'
%d %b %Y,
'
);
export
const
timeFormat
=
d3
.
time
(
'
%-I:%M%p
'
);
export
const
dateFormatWithName
=
d3
.
time
(
'
%a, %b %-d
'
);
export
const
bisectDate
=
d3
.
bisector
(
d
=>
d
.
time
).
left
;
export
function
timeScaleFormat
(
date
)
{
let
formatFunction
;
if
(
d3
.
timeSecond
(
date
)
<
date
)
{
formatFunction
=
d3
.
time
(
'
.%L
'
);
}
else
if
(
d3
.
timeMinute
(
date
)
<
date
)
{
formatFunction
=
d3
.
time
(
'
:%S
'
);
}
else
if
(
d3
.
timeHour
(
date
)
<
date
)
{
formatFunction
=
d3
.
time
(
'
%-I:%M
'
);
}
else
if
(
d3
.
timeDay
(
date
)
<
date
)
{
formatFunction
=
d3
.
time
(
'
%-I %p
'
);
}
else
if
(
d3
.
timeWeek
(
date
)
<
date
)
{
formatFunction
=
d3
.
time
(
'
%a %d
'
);
}
else
if
(
d3
.
timeMonth
(
date
)
<
date
)
{
formatFunction
=
d3
.
time
(
'
%b %d
'
);
}
else
if
(
d3
.
timeYear
(
date
)
<
date
)
{
formatFunction
=
d3
.
time
(
'
%B
'
);
}
else
{
formatFunction
=
d3
.
time
(
'
%Y
'
);
}
return
formatFunction
(
date
);
}
app/assets/javascripts/monitoring/utils/measurements.js
deleted
100644 → 0
View file @
c1286332
export
default
{
small
:
{
// Covers both xs and sm screen sizes
margin
:
{
top
:
40
,
right
:
40
,
bottom
:
50
,
left
:
40
,
},
legends
:
{
width
:
15
,
height
:
3
,
offsetX
:
20
,
offsetY
:
32
,
},
backgroundLegend
:
{
width
:
30
,
height
:
50
,
},
axisLabelLineOffset
:
-
20
,
},
large
:
{
// This covers both md and lg screen sizes
margin
:
{
top
:
80
,
right
:
80
,
bottom
:
100
,
left
:
80
,
},
legends
:
{
width
:
15
,
height
:
3
,
offsetX
:
20
,
offsetY
:
34
,
},
backgroundLegend
:
{
width
:
30
,
height
:
150
,
},
axisLabelLineOffset
:
20
,
},
xTicks
:
8
,
yTicks
:
3
,
};
app/assets/javascripts/monitoring/utils/multiple_time_series.js
deleted
100644 → 0
View file @
c1286332
import
_
from
'
underscore
'
;
import
{
scaleLinear
,
scaleTime
}
from
'
d3-scale
'
;
import
{
line
,
area
,
curveLinear
}
from
'
d3-shape
'
;
import
{
extent
,
max
,
sum
}
from
'
d3-array
'
;
import
{
timeMinute
,
timeSecond
}
from
'
d3-time
'
;
import
{
capitalizeFirstCharacter
}
from
'
~/lib/utils/text_utility
'
;
const
d3
=
{
scaleLinear
,
scaleTime
,
line
,
area
,
curveLinear
,
extent
,
max
,
timeMinute
,
timeSecond
,
sum
,
};
const
defaultColorPalette
=
{
blue
:
[
'
#1f78d1
'
,
'
#8fbce8
'
],
orange
:
[
'
#fc9403
'
,
'
#feca81
'
],
red
:
[
'
#db3b21
'
,
'
#ed9d90
'
],
green
:
[
'
#1aaa55
'
,
'
#8dd5aa
'
],
purple
:
[
'
#6666c4
'
,
'
#d1d1f0
'
],
};
const
defaultColorOrder
=
[
'
blue
'
,
'
orange
'
,
'
red
'
,
'
green
'
,
'
purple
'
];
const
defaultStyleOrder
=
[
'
solid
'
,
'
dashed
'
,
'
dotted
'
];
function
queryTimeSeries
(
query
,
graphDrawData
,
lineStyle
)
{
let
usedColors
=
[];
let
renderCanary
=
false
;
const
timeSeriesParsed
=
[];
function
pickColor
(
name
)
{
let
pick
;
if
(
name
&&
defaultColorPalette
[
name
])
{
pick
=
name
;
}
else
{
const
unusedColors
=
_
.
difference
(
defaultColorOrder
,
usedColors
);
if
(
unusedColors
.
length
>
0
)
{
[
pick
]
=
unusedColors
;
}
else
{
usedColors
=
[];
[
pick
]
=
defaultColorOrder
;
}
}
usedColors
.
push
(
pick
);
return
defaultColorPalette
[
pick
];
}
function
findByDate
(
series
,
time
)
{
const
val
=
series
.
find
(
v
=>
Math
.
abs
(
d3
.
timeSecond
.
count
(
time
,
v
.
time
))
<
60
);
if
(
val
)
{
return
val
.
value
;
}
return
NaN
;
}
// The timeseries data may have gaps in it
// but we need a regularly-spaced set of time/value pairs
// this gives us a complete range of one minute intervals
// offset the same amount as the original data
const
[
minX
,
maxX
]
=
graphDrawData
.
xDom
;
const
offset
=
d3
.
timeMinute
(
minX
)
-
Number
(
minX
);
const
datesWithoutGaps
=
d3
.
timeSecond
.
every
(
60
)
.
range
(
d3
.
timeMinute
.
offset
(
minX
,
-
1
),
maxX
)
.
map
(
d
=>
d
-
offset
);
query
.
result
.
forEach
((
timeSeries
,
timeSeriesNumber
)
=>
{
let
metricTag
=
''
;
let
lineColor
=
''
;
let
areaColor
=
''
;
let
shouldRenderLegend
=
true
;
const
timeSeriesValues
=
timeSeries
.
values
.
map
(
d
=>
d
.
value
);
const
maximumValue
=
d3
.
max
(
timeSeriesValues
);
const
accum
=
d3
.
sum
(
timeSeriesValues
);
const
trackName
=
capitalizeFirstCharacter
(
query
.
track
?
query
.
track
:
'
Stable
'
);
if
(
trackName
===
'
Canary
'
)
{
renderCanary
=
true
;
}
const
timeSeriesMetricLabel
=
timeSeries
.
metric
[
Object
.
keys
(
timeSeries
.
metric
)[
0
]];
const
seriesCustomizationData
=
query
.
series
!=
null
&&
_
.
findWhere
(
query
.
series
[
0
].
when
,
{
value
:
timeSeriesMetricLabel
});
if
(
seriesCustomizationData
)
{
metricTag
=
seriesCustomizationData
.
value
||
timeSeriesMetricLabel
;
[
lineColor
,
areaColor
]
=
pickColor
(
seriesCustomizationData
.
color
);
if
(
timeSeriesParsed
.
length
>
0
)
{
shouldRenderLegend
=
false
;
}
else
{
shouldRenderLegend
=
true
;
}
}
else
{
metricTag
=
timeSeriesMetricLabel
||
query
.
label
||
`series
${
timeSeriesNumber
+
1
}
`
;
[
lineColor
,
areaColor
]
=
pickColor
();
if
(
timeSeriesParsed
.
length
>
1
)
{
shouldRenderLegend
=
false
;
}
}
const
values
=
datesWithoutGaps
.
map
(
time
=>
({
time
,
value
:
findByDate
(
timeSeries
.
values
,
time
),
}));
timeSeriesParsed
.
push
({
linePath
:
graphDrawData
.
lineFunction
(
values
),
areaPath
:
graphDrawData
.
areaBelowLine
(
values
),
timeSeriesScaleX
:
graphDrawData
.
timeSeriesScaleX
,
timeSeriesScaleY
:
graphDrawData
.
timeSeriesScaleY
,
values
:
timeSeries
.
values
,
max
:
maximumValue
,
average
:
accum
/
timeSeries
.
values
.
length
,
lineStyle
,
lineColor
,
areaColor
,
metricTag
,
trackName
,
shouldRenderLegend
,
renderCanary
,
});
if
(
!
shouldRenderLegend
)
{
if
(
!
timeSeriesParsed
[
0
].
tracksLegend
)
{
timeSeriesParsed
[
0
].
tracksLegend
=
[];
}
timeSeriesParsed
[
0
].
tracksLegend
.
push
({
max
:
maximumValue
,
average
:
accum
/
timeSeries
.
values
.
length
,
lineStyle
,
lineColor
,
metricTag
,
});
}
});
return
timeSeriesParsed
;
}
function
xyDomain
(
queries
)
{
const
allValues
=
queries
.
reduce
(
(
allQueryResults
,
query
)
=>
allQueryResults
.
concat
(
query
.
result
.
reduce
((
allResults
,
result
)
=>
allResults
.
concat
(
result
.
values
),
[]),
),
[],
);
const
xDom
=
d3
.
extent
(
allValues
,
d
=>
d
.
time
);
const
yDom
=
[
0
,
d3
.
max
(
allValues
.
map
(
d
=>
d
.
value
))];
return
{
xDom
,
yDom
,
};
}
export
function
generateGraphDrawData
(
queries
,
graphWidth
,
graphHeight
,
graphHeightOffset
)
{
const
{
xDom
,
yDom
}
=
xyDomain
(
queries
);
const
timeSeriesScaleX
=
d3
.
scaleTime
().
range
([
0
,
graphWidth
-
70
]);
const
timeSeriesScaleY
=
d3
.
scaleLinear
().
range
([
graphHeight
-
graphHeightOffset
,
0
]);
timeSeriesScaleX
.
domain
(
xDom
);
timeSeriesScaleX
.
ticks
(
d3
.
timeMinute
,
60
);
timeSeriesScaleY
.
domain
(
yDom
);
const
defined
=
d
=>
!
Number
.
isNaN
(
d
.
value
)
&&
d
.
value
!=
null
;
const
lineFunction
=
d3
.
line
()
.
defined
(
defined
)
.
curve
(
d3
.
curveLinear
)
// d3 v4 uses curbe instead of interpolate
.
x
(
d
=>
timeSeriesScaleX
(
d
.
time
))
.
y
(
d
=>
timeSeriesScaleY
(
d
.
value
));
const
areaBelowLine
=
d3
.
area
()
.
defined
(
defined
)
.
curve
(
d3
.
curveLinear
)
.
x
(
d
=>
timeSeriesScaleX
(
d
.
time
))
.
y0
(
graphHeight
-
graphHeightOffset
)
.
y1
(
d
=>
timeSeriesScaleY
(
d
.
value
));
const
areaAboveLine
=
d3
.
area
()
.
defined
(
defined
)
.
curve
(
d3
.
curveLinear
)
.
x
(
d
=>
timeSeriesScaleX
(
d
.
time
))
.
y0
(
0
)
.
y1
(
d
=>
timeSeriesScaleY
(
d
.
value
));
return
{
lineFunction
,
areaBelowLine
,
areaAboveLine
,
xDom
,
yDom
,
timeSeriesScaleX
,
timeSeriesScaleY
,
};
}
export
default
function
createTimeSeries
(
queries
,
graphWidth
,
graphHeight
,
graphHeightOffset
)
{
const
graphDrawData
=
generateGraphDrawData
(
queries
,
graphWidth
,
graphHeight
,
graphHeightOffset
);
const
timeSeries
=
queries
.
reduce
((
series
,
query
,
index
)
=>
{
const
lineStyle
=
defaultStyleOrder
[
index
%
defaultStyleOrder
.
length
];
return
series
.
concat
(
queryTimeSeries
(
query
,
graphDrawData
,
lineStyle
));
},
[]);
return
{
timeSeries
,
graphDrawData
,
};
}
locale/gitlab.pot
View file @
e7bb9b95
...
...
@@ -4447,9 +4447,6 @@ msgstr ""
msgid "Metrics|Learn about environments"
msgstr ""
msgid "Metrics|No data to display"
msgstr ""
msgid "Metrics|No deployed environments"
msgstr ""
...
...
@@ -5711,9 +5708,6 @@ msgstr ""
msgid "ProjectsDropdown|This feature requires browser localStorage support"
msgstr ""
msgid "PrometheusDashboard|Time"
msgstr ""
msgid "PrometheusService|%{exporters} with %{metrics} were found"
msgstr ""
...
...
spec/javascripts/monitoring/graph/axis_spec.js
deleted
100644 → 0
View file @
c1286332
import
Vue
from
'
vue
'
;
import
GraphAxis
from
'
~/monitoring/components/graph/axis.vue
'
;
import
measurements
from
'
~/monitoring/utils/measurements
'
;
const
createComponent
=
propsData
=>
{
const
Component
=
Vue
.
extend
(
GraphAxis
);
return
new
Component
({
propsData
,
}).
$mount
();
};
const
defaultValuesComponent
=
{
graphWidth
:
500
,
graphHeight
:
300
,
graphHeightOffset
:
120
,
margin
:
measurements
.
large
.
margin
,
measurements
:
measurements
.
large
,
yAxisLabel
:
'
Values
'
,
unitOfDisplay
:
'
MB
'
,
};
function
getTextFromNode
(
component
,
selector
)
{
return
component
.
$el
.
querySelector
(
selector
).
firstChild
.
nodeValue
.
trim
();
}
describe
(
'
Axis
'
,
()
=>
{
describe
(
'
Computed props
'
,
()
=>
{
it
(
'
textTransform
'
,
()
=>
{
const
component
=
createComponent
(
defaultValuesComponent
);
expect
(
component
.
textTransform
).
toContain
(
'
translate(15, 120) rotate(-90)
'
);
});
it
(
'
xPosition
'
,
()
=>
{
const
component
=
createComponent
(
defaultValuesComponent
);
expect
(
component
.
xPosition
).
toEqual
(
180
);
});
it
(
'
yPosition
'
,
()
=>
{
const
component
=
createComponent
(
defaultValuesComponent
);
expect
(
component
.
yPosition
).
toEqual
(
240
);
});
it
(
'
rectTransform
'
,
()
=>
{
const
component
=
createComponent
(
defaultValuesComponent
);
expect
(
component
.
rectTransform
).
toContain
(
'
translate(0, 120) rotate(-90)
'
);
});
});
it
(
'
has 2 rect-axis-text rect svg elements
'
,
()
=>
{
const
component
=
createComponent
(
defaultValuesComponent
);
expect
(
component
.
$el
.
querySelectorAll
(
'
.rect-axis-text
'
).
length
).
toEqual
(
2
);
});
it
(
'
contains text to signal the usage, title and time with multiple time series
'
,
()
=>
{
const
component
=
createComponent
(
defaultValuesComponent
);
expect
(
getTextFromNode
(
component
,
'
.y-label-text
'
)).
toEqual
(
'
Values (MB)
'
);
});
});
spec/javascripts/monitoring/graph/deployment_spec.js
deleted
100644 → 0
View file @
c1286332
import
Vue
from
'
vue
'
;
import
GraphDeployment
from
'
~/monitoring/components/graph/deployment.vue
'
;
import
{
deploymentData
}
from
'
../mock_data
'
;
const
createComponent
=
propsData
=>
{
const
Component
=
Vue
.
extend
(
GraphDeployment
);
return
new
Component
({
propsData
,
}).
$mount
();
};
describe
(
'
MonitoringDeployment
'
,
()
=>
{
describe
(
'
Methods
'
,
()
=>
{
it
(
'
should contain a hidden gradient
'
,
()
=>
{
const
component
=
createComponent
({
showDeployInfo
:
true
,
deploymentData
,
graphHeight
:
300
,
graphWidth
:
440
,
graphHeightOffset
:
120
,
});
expect
(
component
.
$el
.
querySelector
(
'
#shadow-gradient
'
)).
not
.
toBeNull
();
});
it
(
'
transformDeploymentGroup translates an available deployment
'
,
()
=>
{
const
component
=
createComponent
({
showDeployInfo
:
false
,
deploymentData
,
graphHeight
:
300
,
graphWidth
:
440
,
graphHeightOffset
:
120
,
});
expect
(
component
.
transformDeploymentGroup
({
xPos
:
16
})).
toContain
(
'
translate(11, 20)
'
);
});
describe
(
'
Computed props
'
,
()
=>
{
it
(
'
calculatedHeight
'
,
()
=>
{
const
component
=
createComponent
({
showDeployInfo
:
true
,
deploymentData
,
graphHeight
:
300
,
graphWidth
:
440
,
graphHeightOffset
:
120
,
});
expect
(
component
.
calculatedHeight
).
toEqual
(
180
);
});
});
});
});
spec/javascripts/monitoring/graph/flag_spec.js
deleted
100644 → 0
View file @
c1286332
import
Vue
from
'
vue
'
;
import
GraphFlag
from
'
~/monitoring/components/graph/flag.vue
'
;
import
{
deploymentData
}
from
'
../mock_data
'
;
const
createComponent
=
propsData
=>
{
const
Component
=
Vue
.
extend
(
GraphFlag
);
return
new
Component
({
propsData
,
}).
$mount
();
};
const
defaultValuesComponent
=
{
currentXCoordinate
:
200
,
currentYCoordinate
:
100
,
currentFlagPosition
:
100
,
currentData
:
{
time
:
new
Date
(
'
2017-06-04T18:17:33.501Z
'
),
value
:
'
1.49609375
'
,
},
graphHeight
:
300
,
graphHeightOffset
:
120
,
showFlagContent
:
true
,
realPixelRatio
:
1
,
timeSeries
:
[
{
values
:
[
{
time
:
new
Date
(
'
2017-06-04T18:17:33.501Z
'
),
value
:
'
1.49609375
'
,
},
],
},
],
unitOfDisplay
:
'
ms
'
,
currentDataIndex
:
0
,
legendTitle
:
'
Average
'
,
currentCoordinates
:
{},
};
const
deploymentFlagData
=
{
...
deploymentData
[
0
],
ref
:
deploymentData
[
0
].
ref
.
name
,
xPos
:
10
,
time
:
new
Date
(
deploymentData
[
0
].
created_at
),
};
describe
(
'
GraphFlag
'
,
()
=>
{
let
component
;
it
(
'
has a line at the currentXCoordinate
'
,
()
=>
{
component
=
createComponent
(
defaultValuesComponent
);
expect
(
component
.
$el
.
style
.
left
).
toEqual
(
`
${
70
+
component
.
currentXCoordinate
}
px`
);
});
describe
(
'
Deployment flag
'
,
()
=>
{
it
(
'
shows a deployment flag when deployment data provided
'
,
()
=>
{
const
deploymentFlagComponent
=
createComponent
({
...
defaultValuesComponent
,
deploymentFlagData
,
});
expect
(
deploymentFlagComponent
.
$el
.
querySelector
(
'
.popover-title
'
)).
toContainText
(
'
Deployed
'
);
});
it
(
'
contains the ref when a tag is available
'
,
()
=>
{
const
deploymentFlagComponent
=
createComponent
({
...
defaultValuesComponent
,
deploymentFlagData
:
{
...
deploymentFlagData
,
sha
:
'
f5bcd1d9dac6fa4137e2510b9ccd134ef2e84187
'
,
tag
:
true
,
ref
:
'
1.0
'
,
},
});
expect
(
deploymentFlagComponent
.
$el
.
querySelector
(
'
.deploy-meta-content
'
)).
toContainText
(
'
f5bcd1d9
'
,
);
expect
(
deploymentFlagComponent
.
$el
.
querySelector
(
'
.deploy-meta-content
'
)).
toContainText
(
'
1.0
'
,
);
});
it
(
'
does not contain the ref when a tag is unavailable
'
,
()
=>
{
const
deploymentFlagComponent
=
createComponent
({
...
defaultValuesComponent
,
deploymentFlagData
:
{
...
deploymentFlagData
,
sha
:
'
f5bcd1d9dac6fa4137e2510b9ccd134ef2e84187
'
,
tag
:
false
,
ref
:
'
1.0
'
,
},
});
expect
(
deploymentFlagComponent
.
$el
.
querySelector
(
'
.deploy-meta-content
'
)).
toContainText
(
'
f5bcd1d9
'
,
);
expect
(
deploymentFlagComponent
.
$el
.
querySelector
(
'
.deploy-meta-content
'
)).
not
.
toContainText
(
'
1.0
'
,
);
});
});
describe
(
'
Computed props
'
,
()
=>
{
beforeEach
(()
=>
{
component
=
createComponent
(
defaultValuesComponent
);
});
it
(
'
formatTime
'
,
()
=>
{
expect
(
component
.
formatTime
).
toMatch
(
/
\d
:17PM/
);
});
it
(
'
formatDate
'
,
()
=>
{
expect
(
component
.
formatDate
).
toEqual
(
'
04 Jun 2017,
'
);
});
it
(
'
cursorStyle
'
,
()
=>
{
expect
(
component
.
cursorStyle
).
toEqual
({
top
:
'
20px
'
,
left
:
'
270px
'
,
height
:
'
180px
'
,
});
});
it
(
'
flagOrientation
'
,
()
=>
{
expect
(
component
.
flagOrientation
).
toEqual
(
'
left
'
);
});
});
});
spec/javascripts/monitoring/graph/legend_spec.js
deleted
100644 → 0
View file @
c1286332
import
Vue
from
'
vue
'
;
import
GraphLegend
from
'
~/monitoring/components/graph/legend.vue
'
;
import
createTimeSeries
from
'
~/monitoring/utils/multiple_time_series
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
{
singleRowMetricsMultipleSeries
,
convertDatesMultipleSeries
}
from
'
../mock_data
'
;
const
convertedMetrics
=
convertDatesMultipleSeries
(
singleRowMetricsMultipleSeries
);
const
defaultValuesComponent
=
{};
const
{
timeSeries
}
=
createTimeSeries
(
convertedMetrics
[
0
].
queries
,
500
,
300
,
120
);
defaultValuesComponent
.
timeSeries
=
timeSeries
;
describe
(
'
Legend Component
'
,
()
=>
{
let
vm
;
let
Legend
;
beforeEach
(()
=>
{
Legend
=
Vue
.
extend
(
GraphLegend
);
});
describe
(
'
View
'
,
()
=>
{
beforeEach
(()
=>
{
vm
=
mountComponent
(
Legend
,
{
legendTitle
:
'
legend
'
,
timeSeries
,
currentDataIndex
:
0
,
unitOfDisplay
:
'
Req/Sec
'
,
});
});
it
(
'
should render the usage, title and time with multiple time series
'
,
()
=>
{
const
titles
=
vm
.
$el
.
querySelectorAll
(
'
.legend-metric-title
'
);
expect
(
titles
[
0
].
textContent
.
indexOf
(
'
1xx
'
)).
not
.
toEqual
(
-
1
);
expect
(
titles
[
1
].
textContent
.
indexOf
(
'
2xx
'
)).
not
.
toEqual
(
-
1
);
});
it
(
'
should container the same number of rows in the table as time series
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelectorAll
(
'
.prometheus-table tr
'
).
length
).
toEqual
(
vm
.
timeSeries
.
length
);
});
});
});
spec/javascripts/monitoring/graph/track_info_spec.js
deleted
100644 → 0
View file @
c1286332
import
Vue
from
'
vue
'
;
import
TrackInfo
from
'
~/monitoring/components/graph/track_info.vue
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
createTimeSeries
from
'
~/monitoring/utils/multiple_time_series
'
;
import
{
singleRowMetricsMultipleSeries
,
convertDatesMultipleSeries
}
from
'
../mock_data
'
;
const
convertedMetrics
=
convertDatesMultipleSeries
(
singleRowMetricsMultipleSeries
);
const
{
timeSeries
}
=
createTimeSeries
(
convertedMetrics
[
0
].
queries
,
500
,
300
,
120
);
describe
(
'
TrackInfo component
'
,
()
=>
{
let
vm
;
let
Component
;
beforeEach
(()
=>
{
Component
=
Vue
.
extend
(
TrackInfo
);
});
afterEach
(()
=>
{
vm
.
$destroy
();
});
describe
(
'
Computed props
'
,
()
=>
{
beforeEach
(()
=>
{
vm
=
mountComponent
(
Component
,
{
track
:
timeSeries
[
0
]
});
});
it
(
'
summaryMetrics
'
,
()
=>
{
expect
(
vm
.
summaryMetrics
).
toEqual
(
'
Avg: 0.000 · Max: 0.000
'
);
});
});
describe
(
'
Rendered output
'
,
()
=>
{
beforeEach
(()
=>
{
vm
=
mountComponent
(
Component
,
{
track
:
timeSeries
[
0
]
});
});
it
(
'
contains metric tag and the summary metrics
'
,
()
=>
{
const
metricTag
=
vm
.
$el
.
querySelector
(
'
strong
'
);
expect
(
metricTag
.
textContent
.
trim
()).
toEqual
(
vm
.
track
.
metricTag
);
expect
(
vm
.
$el
.
textContent
).
toContain
(
'
Avg: 0.000 · Max: 0.000
'
);
});
});
});
spec/javascripts/monitoring/graph/track_line_spec.js
deleted
100644 → 0
View file @
c1286332
import
Vue
from
'
vue
'
;
import
TrackLine
from
'
~/monitoring/components/graph/track_line.vue
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
createTimeSeries
from
'
~/monitoring/utils/multiple_time_series
'
;
import
{
singleRowMetricsMultipleSeries
,
convertDatesMultipleSeries
}
from
'
../mock_data
'
;
const
convertedMetrics
=
convertDatesMultipleSeries
(
singleRowMetricsMultipleSeries
);
const
{
timeSeries
}
=
createTimeSeries
(
convertedMetrics
[
0
].
queries
,
500
,
300
,
120
);
describe
(
'
TrackLine component
'
,
()
=>
{
let
vm
;
let
Component
;
beforeEach
(()
=>
{
Component
=
Vue
.
extend
(
TrackLine
);
});
afterEach
(()
=>
{
vm
.
$destroy
();
});
describe
(
'
Computed props
'
,
()
=>
{
it
(
'
stylizedLine for dashed lineStyles
'
,
()
=>
{
vm
=
mountComponent
(
Component
,
{
track
:
{
...
timeSeries
[
0
],
lineStyle
:
'
dashed
'
}
});
expect
(
vm
.
stylizedLine
).
toEqual
(
'
6, 3
'
);
});
it
(
'
stylizedLine for dotted lineStyles
'
,
()
=>
{
vm
=
mountComponent
(
Component
,
{
track
:
{
...
timeSeries
[
0
],
lineStyle
:
'
dotted
'
}
});
expect
(
vm
.
stylizedLine
).
toEqual
(
'
3, 3
'
);
});
});
describe
(
'
Rendered output
'
,
()
=>
{
it
(
'
has an svg with a line
'
,
()
=>
{
vm
=
mountComponent
(
Component
,
{
track
:
{
...
timeSeries
[
0
]
}
});
const
svgEl
=
vm
.
$el
.
querySelector
(
'
svg
'
);
const
lineEl
=
vm
.
$el
.
querySelector
(
'
svg line
'
);
expect
(
svgEl
.
getAttribute
(
'
width
'
)).
toEqual
(
'
16
'
);
expect
(
svgEl
.
getAttribute
(
'
height
'
)).
toEqual
(
'
8
'
);
expect
(
lineEl
.
getAttribute
(
'
stroke-width
'
)).
toEqual
(
'
4
'
);
expect
(
lineEl
.
getAttribute
(
'
x1
'
)).
toEqual
(
'
0
'
);
expect
(
lineEl
.
getAttribute
(
'
x2
'
)).
toEqual
(
'
16
'
);
expect
(
lineEl
.
getAttribute
(
'
y1
'
)).
toEqual
(
'
4
'
);
expect
(
lineEl
.
getAttribute
(
'
y2
'
)).
toEqual
(
'
4
'
);
});
});
});
spec/javascripts/monitoring/graph_path_spec.js
deleted
100644 → 0
View file @
c1286332
import
Vue
from
'
vue
'
;
import
GraphPath
from
'
~/monitoring/components/graph/path.vue
'
;
import
createTimeSeries
from
'
~/monitoring/utils/multiple_time_series
'
;
import
{
singleRowMetricsMultipleSeries
,
convertDatesMultipleSeries
}
from
'
./mock_data
'
;
const
createComponent
=
propsData
=>
{
const
Component
=
Vue
.
extend
(
GraphPath
);
return
new
Component
({
propsData
,
}).
$mount
();
};
const
convertedMetrics
=
convertDatesMultipleSeries
(
singleRowMetricsMultipleSeries
);
const
{
timeSeries
}
=
createTimeSeries
(
convertedMetrics
[
0
].
queries
,
428
,
272
,
120
);
const
firstTimeSeries
=
timeSeries
[
0
];
describe
(
'
Monitoring Paths
'
,
()
=>
{
it
(
'
renders two paths to represent a line and the area underneath it
'
,
()
=>
{
const
component
=
createComponent
({
generatedLinePath
:
firstTimeSeries
.
linePath
,
generatedAreaPath
:
firstTimeSeries
.
areaPath
,
lineColor
:
firstTimeSeries
.
lineColor
,
areaColor
:
firstTimeSeries
.
areaColor
,
showDot
:
false
,
});
const
metricArea
=
component
.
$el
.
querySelector
(
'
.metric-area
'
);
const
metricLine
=
component
.
$el
.
querySelector
(
'
.metric-line
'
);
expect
(
metricArea
.
getAttribute
(
'
fill
'
)).
toBe
(
'
#8fbce8
'
);
expect
(
metricArea
.
getAttribute
(
'
d
'
)).
toBe
(
firstTimeSeries
.
areaPath
);
expect
(
metricLine
.
getAttribute
(
'
stroke
'
)).
toBe
(
'
#1f78d1
'
);
expect
(
metricLine
.
getAttribute
(
'
d
'
)).
toBe
(
firstTimeSeries
.
linePath
);
});
describe
(
'
Computed properties
'
,
()
=>
{
it
(
'
strokeDashArray
'
,
()
=>
{
const
component
=
createComponent
({
generatedLinePath
:
firstTimeSeries
.
linePath
,
generatedAreaPath
:
firstTimeSeries
.
areaPath
,
lineColor
:
firstTimeSeries
.
lineColor
,
areaColor
:
firstTimeSeries
.
areaColor
,
showDot
:
false
,
});
component
.
lineStyle
=
'
dashed
'
;
expect
(
component
.
strokeDashArray
).
toBe
(
'
3, 1
'
);
component
.
lineStyle
=
'
dotted
'
;
expect
(
component
.
strokeDashArray
).
toBe
(
'
1, 1
'
);
});
});
});
spec/javascripts/monitoring/graph_spec.js
deleted
100644 → 0
View file @
c1286332
import
Vue
from
'
vue
'
;
import
Graph
from
'
~/monitoring/components/graph.vue
'
;
import
MonitoringMixins
from
'
~/monitoring/mixins/monitoring_mixins
'
;
import
{
deploymentData
,
convertDatesMultipleSeries
,
singleRowMetricsMultipleSeries
,
queryWithoutData
,
}
from
'
./mock_data
'
;
const
tagsPath
=
'
http://test.host/frontend-fixtures/environments-project/tags
'
;
const
projectPath
=
'
http://test.host/frontend-fixtures/environments-project
'
;
const
createComponent
=
propsData
=>
{
const
Component
=
Vue
.
extend
(
Graph
);
return
new
Component
({
propsData
,
}).
$mount
();
};
const
convertedMetrics
=
convertDatesMultipleSeries
(
singleRowMetricsMultipleSeries
);
describe
(
'
Graph
'
,
()
=>
{
beforeEach
(()
=>
{
spyOn
(
MonitoringMixins
.
methods
,
'
formatDeployments
'
).
and
.
returnValue
({});
});
it
(
'
has a title
'
,
()
=>
{
const
component
=
createComponent
({
graphData
:
convertedMetrics
[
1
],
updateAspectRatio
:
false
,
deploymentData
,
tagsPath
,
projectPath
,
});
expect
(
component
.
$el
.
querySelector
(
'
.prometheus-graph-title
'
).
innerText
.
trim
()).
toBe
(
component
.
graphData
.
title
,
);
});
describe
(
'
Computed props
'
,
()
=>
{
it
(
'
axisTransform translates an element Y position depending of its height
'
,
()
=>
{
const
component
=
createComponent
({
graphData
:
convertedMetrics
[
1
],
updateAspectRatio
:
false
,
deploymentData
,
tagsPath
,
projectPath
,
});
const
transformedHeight
=
`
${
component
.
graphHeight
-
100
}
`
;
expect
(
component
.
axisTransform
.
indexOf
(
transformedHeight
)).
not
.
toEqual
(
-
1
);
});
it
(
'
outerViewBox gets a width and height property based on the DOM size of the element
'
,
()
=>
{
const
component
=
createComponent
({
graphData
:
convertedMetrics
[
1
],
updateAspectRatio
:
false
,
deploymentData
,
tagsPath
,
projectPath
,
});
const
viewBoxArray
=
component
.
outerViewBox
.
split
(
'
'
);
expect
(
typeof
component
.
outerViewBox
).
toEqual
(
'
string
'
);
expect
(
viewBoxArray
[
2
]).
toEqual
(
component
.
graphWidth
.
toString
());
expect
(
viewBoxArray
[
3
]).
toEqual
((
component
.
graphHeight
-
50
).
toString
());
});
});
it
(
'
has a title for the y-axis and the chart legend that comes from the backend
'
,
()
=>
{
const
component
=
createComponent
({
graphData
:
convertedMetrics
[
1
],
updateAspectRatio
:
false
,
deploymentData
,
tagsPath
,
projectPath
,
});
expect
(
component
.
yAxisLabel
).
toEqual
(
component
.
graphData
.
y_label
);
expect
(
component
.
legendTitle
).
toEqual
(
component
.
graphData
.
queries
[
0
].
label
);
});
it
(
'
sets the currentData object based on the hovered data index
'
,
()
=>
{
const
component
=
createComponent
({
graphData
:
convertedMetrics
[
1
],
updateAspectRatio
:
false
,
deploymentData
,
graphIdentifier
:
0
,
hoverData
:
{
hoveredDate
:
new
Date
(
'
Sun Aug 27 2017 06:11:51 GMT-0500 (CDT)
'
),
currentDeployXPos
:
null
,
},
tagsPath
,
projectPath
,
});
// simulate moving mouse over data series
component
.
seriesUnderMouse
=
component
.
timeSeries
;
component
.
positionFlag
();
expect
(
component
.
currentData
).
toBe
(
component
.
timeSeries
[
0
].
values
[
10
]);
});
describe
(
'
Without data to display
'
,
()
=>
{
it
(
'
shows a "no data to display" empty state on a graph
'
,
done
=>
{
const
component
=
createComponent
({
graphData
:
queryWithoutData
,
deploymentData
,
tagsPath
,
projectPath
,
});
Vue
.
nextTick
(()
=>
{
expect
(
component
.
$el
.
querySelector
(
'
.js-no-data-to-display text
'
).
textContent
.
trim
(),
).
toEqual
(
'
No data to display
'
);
done
();
});
});
});
});
spec/javascripts/monitoring/utils/multiple_time_series_spec.js
deleted
100644 → 0
View file @
c1286332
import
createTimeSeries
from
'
~/monitoring/utils/multiple_time_series
'
;
import
{
convertDatesMultipleSeries
,
singleRowMetricsMultipleSeries
}
from
'
../mock_data
'
;
const
convertedMetrics
=
convertDatesMultipleSeries
(
singleRowMetricsMultipleSeries
);
const
{
timeSeries
}
=
createTimeSeries
(
convertedMetrics
[
0
].
queries
,
428
,
272
,
120
);
const
firstTimeSeries
=
timeSeries
[
0
];
describe
(
'
Multiple time series
'
,
()
=>
{
it
(
'
createTimeSeries returned array contains an object for each element
'
,
()
=>
{
expect
(
typeof
firstTimeSeries
.
linePath
).
toEqual
(
'
string
'
);
expect
(
typeof
firstTimeSeries
.
areaPath
).
toEqual
(
'
string
'
);
expect
(
typeof
firstTimeSeries
.
timeSeriesScaleX
).
toEqual
(
'
function
'
);
expect
(
typeof
firstTimeSeries
.
areaColor
).
toEqual
(
'
string
'
);
expect
(
typeof
firstTimeSeries
.
lineColor
).
toEqual
(
'
string
'
);
expect
(
firstTimeSeries
.
values
instanceof
Array
).
toEqual
(
true
);
});
it
(
'
createTimeSeries returns an array
'
,
()
=>
{
expect
(
timeSeries
instanceof
Array
).
toEqual
(
true
);
expect
(
timeSeries
.
length
).
toEqual
(
2
);
});
});
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment