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
1
Merge Requests
1
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
nexedi
gitlab-ce
Commits
86268f75
Commit
86268f75
authored
Aug 24, 2019
by
Miguel Rincon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove area.vue component
parent
8112fb37
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
0 additions
and
569 deletions
+0
-569
app/assets/javascripts/monitoring/components/charts/area.vue
app/assets/javascripts/monitoring/components/charts/area.vue
+0
-304
spec/javascripts/monitoring/charts/area_spec.js
spec/javascripts/monitoring/charts/area_spec.js
+0
-265
No files found.
app/assets/javascripts/monitoring/components/charts/area.vue
deleted
100644 → 0
View file @
8112fb37
<
script
>
import
{
__
}
from
'
~/locale
'
;
import
{
GlLink
}
from
'
@gitlab/ui
'
;
import
{
GlAreaChart
,
GlChartSeriesLabel
}
from
'
@gitlab/ui/dist/charts
'
;
import
dateFormat
from
'
dateformat
'
;
import
{
debounceByAnimationFrame
,
roundOffFloat
}
from
'
~/lib/utils/common_utils
'
;
import
{
getSvgIconPathContent
}
from
'
~/lib/utils/icon_utils
'
;
import
Icon
from
'
~/vue_shared/components/icon.vue
'
;
import
{
chartHeight
,
graphTypes
,
lineTypes
}
from
'
../../constants
'
;
import
{
makeDataSeries
}
from
'
~/helpers/monitor_helper
'
;
import
{
graphDataValidatorForValues
}
from
'
../../utils
'
;
let
debouncedResize
;
// TODO: Remove this component in favor of the more general time_series.vue
// Please port all changes here to time_series.vue as well.
export
default
{
components
:
{
GlAreaChart
,
GlChartSeriesLabel
,
GlLink
,
Icon
,
},
inheritAttrs
:
false
,
props
:
{
graphData
:
{
type
:
Object
,
required
:
true
,
validator
:
graphDataValidatorForValues
.
bind
(
null
,
false
),
},
containerWidth
:
{
type
:
Number
,
required
:
true
,
},
deploymentData
:
{
type
:
Array
,
required
:
false
,
default
:
()
=>
[],
},
projectPath
:
{
type
:
String
,
required
:
false
,
default
:
()
=>
''
,
},
showBorder
:
{
type
:
Boolean
,
required
:
false
,
default
:
()
=>
false
,
},
singleEmbed
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
},
thresholds
:
{
type
:
Array
,
required
:
false
,
default
:
()
=>
[],
},
},
data
()
{
return
{
tooltip
:
{
title
:
''
,
content
:
[],
commitUrl
:
''
,
isDeployment
:
false
,
sha
:
''
,
},
width
:
0
,
height
:
chartHeight
,
svgs
:
{},
primaryColor
:
null
,
};
},
computed
:
{
chartData
()
{
// Transforms & supplements query data to render appropriate labels & styles
// Input: [{ queryAttributes1 }, { queryAttributes2 }]
// Output: [{ seriesAttributes1 }, { seriesAttributes2 }]
return
this
.
graphData
.
queries
.
reduce
((
acc
,
query
)
=>
{
const
{
appearance
}
=
query
;
const
lineType
=
appearance
&&
appearance
.
line
&&
appearance
.
line
.
type
?
appearance
.
line
.
type
:
lineTypes
.
default
;
const
lineWidth
=
appearance
&&
appearance
.
line
&&
appearance
.
line
.
width
?
appearance
.
line
.
width
:
undefined
;
const
series
=
makeDataSeries
(
query
.
result
,
{
name
:
this
.
formatLegendLabel
(
query
),
lineStyle
:
{
type
:
lineType
,
width
:
lineWidth
,
},
areaStyle
:
{
opacity
:
appearance
&&
appearance
.
area
&&
typeof
appearance
.
area
.
opacity
===
'
number
'
?
appearance
.
area
.
opacity
:
undefined
,
},
});
return
acc
.
concat
(
series
);
},
[]);
},
chartOptions
()
{
return
{
xAxis
:
{
name
:
__
(
'
Time
'
),
type
:
'
time
'
,
axisLabel
:
{
formatter
:
date
=>
dateFormat
(
date
,
'
h:MM TT
'
),
},
axisPointer
:
{
snap
:
true
,
},
},
yAxis
:
{
name
:
this
.
yAxisLabel
,
axisLabel
:
{
formatter
:
num
=>
roundOffFloat
(
num
,
3
).
toString
(),
},
},
series
:
this
.
scatterSeries
,
dataZoom
:
[
this
.
dataZoomConfig
],
};
},
dataZoomConfig
()
{
const
handleIcon
=
this
.
svgs
[
'
scroll-handle
'
];
return
handleIcon
?
{
handleIcon
}
:
{};
},
earliestDatapoint
()
{
return
this
.
chartData
.
reduce
((
acc
,
series
)
=>
{
const
{
data
}
=
series
;
const
{
length
}
=
data
;
if
(
!
length
)
{
return
acc
;
}
const
[
first
]
=
data
[
0
];
const
[
last
]
=
data
[
length
-
1
];
const
seriesEarliest
=
first
<
last
?
first
:
last
;
return
seriesEarliest
<
acc
||
acc
===
null
?
seriesEarliest
:
acc
;
},
null
);
},
isMultiSeries
()
{
return
this
.
tooltip
.
content
.
length
>
1
;
},
recentDeployments
()
{
return
this
.
deploymentData
.
reduce
((
acc
,
deployment
)
=>
{
if
(
deployment
.
created_at
>=
this
.
earliestDatapoint
)
{
acc
.
push
({
id
:
deployment
.
id
,
createdAt
:
deployment
.
created_at
,
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
,
showDeploymentFlag
:
false
,
});
}
return
acc
;
},
[]);
},
scatterSeries
()
{
return
{
type
:
graphTypes
.
deploymentData
,
data
:
this
.
recentDeployments
.
map
(
deployment
=>
[
deployment
.
createdAt
,
0
]),
symbol
:
this
.
svgs
.
rocket
,
symbolSize
:
14
,
itemStyle
:
{
color
:
this
.
primaryColor
,
},
};
},
yAxisLabel
()
{
return
`
${
this
.
graphData
.
y_label
}
`
;
},
},
watch
:
{
containerWidth
:
'
onResize
'
,
},
beforeDestroy
()
{
window
.
removeEventListener
(
'
resize
'
,
debouncedResize
);
},
created
()
{
debouncedResize
=
debounceByAnimationFrame
(
this
.
onResize
);
window
.
addEventListener
(
'
resize
'
,
debouncedResize
);
this
.
setSvg
(
'
rocket
'
);
this
.
setSvg
(
'
scroll-handle
'
);
},
methods
:
{
formatLegendLabel
(
query
)
{
return
`
${
query
.
label
}
`
;
},
formatTooltipText
(
params
)
{
this
.
tooltip
.
title
=
dateFormat
(
params
.
value
,
'
dd mmm yyyy, h:MMTT
'
);
this
.
tooltip
.
content
=
[];
params
.
seriesData
.
forEach
(
seriesData
=>
{
this
.
tooltip
.
isDeployment
=
seriesData
.
componentSubType
===
graphTypes
.
deploymentData
;
if
(
this
.
tooltip
.
isDeployment
)
{
const
[
deploy
]
=
this
.
recentDeployments
.
filter
(
deployment
=>
deployment
.
createdAt
===
seriesData
.
value
[
0
],
);
this
.
tooltip
.
sha
=
deploy
.
sha
.
substring
(
0
,
8
);
this
.
tooltip
.
commitUrl
=
deploy
.
commitUrl
;
}
else
{
const
{
seriesName
,
color
}
=
seriesData
;
// seriesData.value contains the chart's [x, y] value pair
// seriesData.value[1] is threfore the chart y value
const
value
=
seriesData
.
value
[
1
].
toFixed
(
3
);
this
.
tooltip
.
content
.
push
({
name
:
seriesName
,
value
,
color
,
});
}
});
},
setSvg
(
name
)
{
getSvgIconPathContent
(
name
)
.
then
(
path
=>
{
if
(
path
)
{
this
.
$set
(
this
.
svgs
,
name
,
`path://
${
path
}
`
);
}
})
.
catch
(()
=>
{});
},
onChartUpdated
(
chart
)
{
[
this
.
primaryColor
]
=
chart
.
getOption
().
color
;
},
onResize
()
{
if
(
!
this
.
$refs
.
areaChart
)
return
;
const
{
width
}
=
this
.
$refs
.
areaChart
.
$el
.
getBoundingClientRect
();
this
.
width
=
width
;
},
},
};
</
script
>
<
template
>
<div
class=
"prometheus-graph col-12"
:class=
"[showBorder ? 'p-2' : 'p-0',
{ 'col-lg-6': !singleEmbed }]"
>
<div
:class=
"
{ 'prometheus-graph-embed w-100 p-3': showBorder }">
<div
class=
"prometheus-graph-header"
>
<h5
ref=
"graphTitle"
class=
"prometheus-graph-title"
>
{{
graphData
.
title
}}
</h5>
<div
ref=
"graphWidgets"
class=
"prometheus-graph-widgets"
><slot></slot></div>
</div>
<gl-area-chart
ref=
"areaChart"
v-bind=
"$attrs"
:data=
"chartData"
:option=
"chartOptions"
:format-tooltip-text=
"formatTooltipText"
:thresholds=
"thresholds"
:width=
"width"
:height=
"height"
@
updated=
"onChartUpdated"
>
<template
v-if=
"tooltip.isDeployment"
>
<template
slot=
"tooltipTitle"
>
{{
__
(
'
Deployed
'
)
}}
</
template
>
<div
slot=
"tooltipContent"
class=
"d-flex align-items-center"
>
<icon
name=
"commit"
class=
"mr-2"
/>
<gl-link
:href=
"tooltip.commitUrl"
>
{{ tooltip.sha }}
</gl-link>
</div>
</template>
<
template
v-else
>
<template
slot=
"tooltipTitle"
>
<div
class=
"text-nowrap"
>
{{
tooltip
.
title
}}
</div>
</
template
>
<
template
slot=
"tooltipContent"
>
<div
v-for=
"(content, key) in tooltip.content"
:key=
"key"
class=
"d-flex justify-content-between"
>
<gl-chart-series-label
:color=
"isMultiSeries ? content.color : ''"
>
{{
content
.
name
}}
</gl-chart-series-label>
<div
class=
"prepend-left-32"
>
{{
content
.
value
}}
</div>
</div>
</
template
>
</template>
</gl-area-chart>
</div>
</div>
</template>
spec/javascripts/monitoring/charts/area_spec.js
deleted
100644 → 0
View file @
8112fb37
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
createStore
}
from
'
~/monitoring/stores
'
;
import
{
GlLink
}
from
'
@gitlab/ui
'
;
import
{
GlAreaChart
,
GlChartSeriesLabel
}
from
'
@gitlab/ui/dist/charts
'
;
import
{
shallowWrapperContainsSlotText
}
from
'
spec/helpers/vue_test_utils_helper
'
;
import
Area
from
'
~/monitoring/components/charts/area.vue
'
;
import
*
as
types
from
'
~/monitoring/stores/mutation_types
'
;
import
{
TEST_HOST
}
from
'
spec/test_constants
'
;
import
MonitoringMock
,
{
deploymentData
}
from
'
../mock_data
'
;
describe
(
'
Area component
'
,
()
=>
{
const
mockSha
=
'
mockSha
'
;
const
mockWidgets
=
'
mockWidgets
'
;
const
mockSvgPathContent
=
'
mockSvgPathContent
'
;
const
projectPath
=
`
${
TEST_HOST
}
/path/to/project`
;
const
commitUrl
=
`
${
projectPath
}
/commit/
${
mockSha
}
`
;
let
mockGraphData
;
let
areaChart
;
let
spriteSpy
;
let
store
;
beforeEach
(()
=>
{
store
=
createStore
();
store
.
commit
(
`monitoringDashboard/
${
types
.
RECEIVE_METRICS_DATA_SUCCESS
}
`
,
MonitoringMock
.
data
);
store
.
commit
(
`monitoringDashboard/
${
types
.
RECEIVE_DEPLOYMENTS_DATA_SUCCESS
}
`
,
deploymentData
);
[
mockGraphData
]
=
store
.
state
.
monitoringDashboard
.
groups
[
0
].
metrics
;
areaChart
=
shallowMount
(
Area
,
{
propsData
:
{
graphData
:
mockGraphData
,
containerWidth
:
0
,
deploymentData
:
store
.
state
.
monitoringDashboard
.
deploymentData
,
projectPath
,
},
slots
:
{
default
:
mockWidgets
,
},
store
,
});
spriteSpy
=
spyOnDependency
(
Area
,
'
getSvgIconPathContent
'
).
and
.
callFake
(
()
=>
new
Promise
(
resolve
=>
resolve
(
mockSvgPathContent
)),
);
});
afterEach
(()
=>
{
areaChart
.
destroy
();
});
it
(
'
renders chart title
'
,
()
=>
{
expect
(
areaChart
.
find
({
ref
:
'
graphTitle
'
}).
text
()).
toBe
(
mockGraphData
.
title
);
});
it
(
'
contains graph widgets from slot
'
,
()
=>
{
expect
(
areaChart
.
find
({
ref
:
'
graphWidgets
'
}).
text
()).
toBe
(
mockWidgets
);
});
describe
(
'
wrapped components
'
,
()
=>
{
describe
(
'
GitLab UI area chart
'
,
()
=>
{
let
glAreaChart
;
beforeEach
(()
=>
{
glAreaChart
=
areaChart
.
find
(
GlAreaChart
);
});
it
(
'
is a Vue instance
'
,
()
=>
{
expect
(
glAreaChart
.
isVueInstance
()).
toBe
(
true
);
});
it
(
'
receives data properties needed for proper chart render
'
,
()
=>
{
const
props
=
glAreaChart
.
props
();
expect
(
props
.
data
).
toBe
(
areaChart
.
vm
.
chartData
);
expect
(
props
.
option
).
toBe
(
areaChart
.
vm
.
chartOptions
);
expect
(
props
.
formatTooltipText
).
toBe
(
areaChart
.
vm
.
formatTooltipText
);
expect
(
props
.
thresholds
).
toBe
(
areaChart
.
vm
.
thresholds
);
});
it
(
'
recieves a tooltip title
'
,
()
=>
{
const
mockTitle
=
'
mockTitle
'
;
areaChart
.
vm
.
tooltip
.
title
=
mockTitle
;
expect
(
shallowWrapperContainsSlotText
(
glAreaChart
,
'
tooltipTitle
'
,
mockTitle
)).
toBe
(
true
);
});
describe
(
'
when tooltip is showing deployment data
'
,
()
=>
{
beforeEach
(()
=>
{
areaChart
.
vm
.
tooltip
.
isDeployment
=
true
;
});
it
(
'
uses deployment title
'
,
()
=>
{
expect
(
shallowWrapperContainsSlotText
(
glAreaChart
,
'
tooltipTitle
'
,
'
Deployed
'
)).
toBe
(
true
,
);
});
it
(
'
renders clickable commit sha in tooltip content
'
,
()
=>
{
areaChart
.
vm
.
tooltip
.
sha
=
mockSha
;
areaChart
.
vm
.
tooltip
.
commitUrl
=
commitUrl
;
const
commitLink
=
areaChart
.
find
(
GlLink
);
expect
(
shallowWrapperContainsSlotText
(
commitLink
,
'
default
'
,
mockSha
)).
toBe
(
true
);
expect
(
commitLink
.
attributes
(
'
href
'
)).
toEqual
(
commitUrl
);
});
});
});
});
describe
(
'
methods
'
,
()
=>
{
describe
(
'
formatTooltipText
'
,
()
=>
{
const
mockDate
=
deploymentData
[
0
].
created_at
;
const
generateSeriesData
=
type
=>
({
seriesData
:
[
{
seriesName
:
areaChart
.
vm
.
chartData
[
0
].
name
,
componentSubType
:
type
,
value
:
[
mockDate
,
5.55555
],
seriesIndex
:
0
,
},
],
value
:
mockDate
,
});
describe
(
'
when series is of line type
'
,
()
=>
{
beforeEach
(()
=>
{
areaChart
.
vm
.
formatTooltipText
(
generateSeriesData
(
'
line
'
));
});
it
(
'
formats tooltip title
'
,
()
=>
{
expect
(
areaChart
.
vm
.
tooltip
.
title
).
toBe
(
'
31 May 2017, 9:23PM
'
);
});
it
(
'
formats tooltip content
'
,
()
=>
{
const
name
=
'
Core Usage
'
;
const
value
=
'
5.556
'
;
const
seriesLabel
=
areaChart
.
find
(
GlChartSeriesLabel
);
expect
(
seriesLabel
.
vm
.
color
).
toBe
(
''
);
expect
(
shallowWrapperContainsSlotText
(
seriesLabel
,
'
default
'
,
name
)).
toBe
(
true
);
expect
(
areaChart
.
vm
.
tooltip
.
content
).
toEqual
([{
name
,
value
,
color
:
undefined
}]);
expect
(
shallowWrapperContainsSlotText
(
areaChart
.
find
(
GlAreaChart
),
'
tooltipContent
'
,
value
),
).
toBe
(
true
);
});
});
describe
(
'
when series is of scatter type
'
,
()
=>
{
beforeEach
(()
=>
{
areaChart
.
vm
.
formatTooltipText
(
generateSeriesData
(
'
scatter
'
));
});
it
(
'
formats tooltip title
'
,
()
=>
{
expect
(
areaChart
.
vm
.
tooltip
.
title
).
toBe
(
'
31 May 2017, 9:23PM
'
);
});
it
(
'
formats tooltip sha
'
,
()
=>
{
expect
(
areaChart
.
vm
.
tooltip
.
sha
).
toBe
(
'
f5bcd1d9
'
);
});
});
});
describe
(
'
setSvg
'
,
()
=>
{
const
mockSvgName
=
'
mockSvgName
'
;
beforeEach
(()
=>
{
areaChart
.
vm
.
setSvg
(
mockSvgName
);
});
it
(
'
gets svg path content
'
,
()
=>
{
expect
(
spriteSpy
).
toHaveBeenCalledWith
(
mockSvgName
);
});
it
(
'
sets svg path content
'
,
done
=>
{
areaChart
.
vm
.
$nextTick
(()
=>
{
expect
(
areaChart
.
vm
.
svgs
[
mockSvgName
]).
toBe
(
`path://
${
mockSvgPathContent
}
`
);
done
();
});
});
});
describe
(
'
onResize
'
,
()
=>
{
const
mockWidth
=
233
;
beforeEach
(()
=>
{
spyOn
(
Element
.
prototype
,
'
getBoundingClientRect
'
).
and
.
callFake
(()
=>
({
width
:
mockWidth
,
}));
areaChart
.
vm
.
onResize
();
});
it
(
'
sets area chart width
'
,
()
=>
{
expect
(
areaChart
.
vm
.
width
).
toBe
(
mockWidth
);
});
});
});
describe
(
'
computed
'
,
()
=>
{
describe
(
'
chartData
'
,
()
=>
{
let
chartData
;
const
seriesData
=
()
=>
chartData
[
0
];
beforeEach
(()
=>
{
({
chartData
}
=
areaChart
.
vm
);
});
it
(
'
utilizes all data points
'
,
()
=>
{
expect
(
chartData
.
length
).
toBe
(
1
);
expect
(
seriesData
().
data
.
length
).
toBe
(
297
);
});
it
(
'
creates valid data
'
,
()
=>
{
const
{
data
}
=
seriesData
();
expect
(
data
.
filter
(([
time
,
value
])
=>
new
Date
(
time
).
getTime
()
>
0
&&
typeof
value
===
'
number
'
)
.
length
,
).
toBe
(
data
.
length
);
});
it
(
'
formats line width correctly
'
,
()
=>
{
expect
(
chartData
[
0
].
lineStyle
.
width
).
toBe
(
2
);
});
});
describe
(
'
chartOptions
'
,
()
=>
{
describe
(
'
dataZoom
'
,
()
=>
{
it
(
'
contains an svg object within an array to properly render icon
'
,
()
=>
{
const
dataZoomObject
=
[{}];
expect
(
areaChart
.
vm
.
chartOptions
.
dataZoom
).
toEqual
(
dataZoomObject
);
});
});
describe
(
'
yAxis formatter
'
,
()
=>
{
let
format
;
beforeEach
(()
=>
{
format
=
areaChart
.
vm
.
chartOptions
.
yAxis
.
axisLabel
.
formatter
;
});
it
(
'
rounds to 3 decimal places
'
,
()
=>
{
expect
(
format
(
0.88888
)).
toBe
(
'
0.889
'
);
});
});
});
describe
(
'
scatterSeries
'
,
()
=>
{
it
(
'
utilizes deployment data
'
,
()
=>
{
expect
(
areaChart
.
vm
.
scatterSeries
.
data
).
toEqual
([
[
'
2017-05-31T21:23:37.881Z
'
,
0
],
[
'
2017-05-30T20:08:04.629Z
'
,
0
],
[
'
2017-05-30T17:42:38.409Z
'
,
0
],
]);
});
});
describe
(
'
yAxisLabel
'
,
()
=>
{
it
(
'
constructs a label for the chart y-axis
'
,
()
=>
{
expect
(
areaChart
.
vm
.
yAxisLabel
).
toBe
(
'
CPU
'
);
});
});
});
});
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