@@ -6,7 +6,7 @@
< div class = "sidebar-info" >
< div class = "sidebar-info-item " @click ="jumpTo('overview')" > {{ $ t ( ' dashboard.overview.title ' ) }} < / div >
< div class = "sidebar-info-item" @click ="jumpTo('panel')" > {{ $ t ( ' dashboard.panel.title ' ) }} < / div >
< div class = "sidebar-info-item sidebar-info-item-active" > { { $t ( 'dashboard.metricPreview.title' ) } } < / div >
< div class = "sidebar-info-item sidebar-info-item-active" > { { $t ( 'dashboard.metricPreview.title' ) } } < / div >
< / div >
< / div >
< div slot = "content-right" class = "slot-content" >
@@ -14,7 +14,9 @@
< el-scrollbar style = "height: 100%" >
<!-- 顶部工具栏 -- >
< div class = "top-tools" style = "z-index: 1" >
< button :disabled = "saveDisabled" type = "button" @click ="saveChart" class = "nz-btn nz-btn-size-large nz-btn-style-normal nz-btn-min-width-120" : class = "{'nz-btn-disabled btn-disabled-cursor-not-allowed' : saveDisabled}" >
< button :disabled = "saveDisabled" type = "button" @click ="saveChart"
class = "nz-btn nz-btn-size-large nz-btn-style-normal nz-btn-min-width-120"
: class = "{'nz-btn-disabled btn-disabled-cursor-not-allowed' : saveDisabled}" >
{ { $t ( 'dashboard.metric.saveChart' ) } }
< / button >
< div class = "nz-btn-group nz-btn-group-size-normal nz-btn-group-light margin-r-20" >
@@ -51,9 +53,11 @@
< / el-date-picker >
< / div >
< div class = "expression-room" >
<!-- 坑 , 这个index居然是从1开始 -- >
< promql-input
v-for = "index of promqlCount "
:key = "expression s[index]"
v-for = "index of promqlKeys.length "
:id = "promqlKey s[index-1 ]"
:key = "promqlKeys[index-1]"
:expression-list = "expressions"
:index = "index"
@change ="expressionChange"
@@ -61,13 +65,15 @@
@removeExpression ="removeExpression"
> < / promql-input >
< / div >
< div class = "chart-view " v-show = "!showIntroduce" :class="{'shrink-view':!chartVisible || !defaultChartVisible}" >
< div class = "chart-view " v-show = "!showIntroduce"
: class = "{'shrink-view':!chartVisible || !defaultChartVisible}" >
< div class = "view-title" @click ="changeChartVisible" > < i class = "el-icon-caret-top" > < / i > & nbsp ; graph < / div >
< div class = "chart-room" >
< chart ref = "exploreChart" > < / chart >
< / div >
< / div >
< div class = "table-view " v-show = "!showIntroduce" :class="{'shrink-view':!tableVisible || !defaultTableVisible}" >
< div class = "table-view " v-show = "!showIntroduce"
: class = "{'shrink-view':!tableVisible || !defaultTableVisible}" >
< div class = "view-title" @click ="changeTableVisible" > < i class = "el-icon-caret-top" > < / i > & nbsp ; table < / div >
< div class = "table-room" >
< el-table class = "nz-table explore-table"
@@ -80,49 +86,131 @@
style = "width: 100%;" >
< el-table-column
:resizable = "false"
v-for = "(item, index) in t ableLabels"
v-for = "(item, index) in showT ableLabels"
v-if = "item.show"
:key = "`col-${index}`"
:label = "item.label"
:prop = "item.prop"
show -overflow -tooltip
min -width = " 110px "
> < / el-table-column >
< el-table-column width = "28" >
< template slot = "header" slot -scope = " scope " :resizable = "false" >
< span @click.stop ="elementsetShow('shezhi',$event)" class = "nz-table-gear" >
< i class = "nz-icon nz-icon-gear" > < / i >
< / span >
< / template >
< / el-table-column >
< / el-table >
< pagination :page-obj = "pageObj" @ pageNo = 'pageNo' @ pageSize = 'pageSize' ref = "Pagination" :append-to-body = "false" > < / pagination >
< pagination :page-obj = "pageObj" @ pageNo = 'pageNo' @ pageSize = 'pageSize' ref = "Pagination"
:append-to-body = "false" > < / pagination >
< / div >
< / div >
< div class = "introduce-view" v-show = "showIntroduce" >
< div class = "info-room" >
< div > < h2 > PromQL Cheat Sheet < / h2 >
< div class = "cheat-sheet-item" >
< div class = "cheat-sheet-item__title" > Requ est Rate < / div >
< div class = "cheat-sheet-item__example" > < code > rate ( http _request _total [ 5 m ] ) < / code > < / div >
< div class = "cheat-sheet-item__label" > Given an HTTP request counter , this query calculates the
per - second average request rate over the last 5 minutes .
< / div >
< / div >
< div class = "cheat-sheet-item" >
< div class = "cheat-sheet-item__title" > 95 th Percentile of Request Latencies < / div >
< div class = "cheat-sheet-item__example" > < code > histogram _quantile ( 0.95 ,
sum ( rate ( prometheus _ http_request _duration _seconds _bucket [ 5 m ] ) ) by ( le ) ) < / code > < / div >
< div class = "cheat-sheet-item__label" > Calculates the 95 th percentile of HTTP request rate over 5
minute w indows .
< / div >
< / div >
< div class = "cheat-sheet-item" >
< div class = "cheat-sheet-item__title" > Alerts Firing < / div >
< div class = "cheat-sheet-item__example" > < code > sort _desc ( sum ( sum _over _time ( ALERTS { alertstate = "firing" } [ 24 h ] ) )
by ( alertname ) ) < / code > < / div >
< div class = "cheat-sheet-item__label" > Sums up the alerts that have been firing over the last 24
h ours .
< / div >
< / div >
< div class = "col-md-9 doc-content" >
< h2 >
Simple time seri es selection
< / h2 >
< p > Return all time series with the metric < code > http _requests _total < / code > : < / p >
< pre > < code > http _requests _total < / code > < / pre >
< p > Return all time series with the metric < code > http _requests _total < / code > and the given < code > job < / code > and < code > handler < / code > labels : < / p >
< pre > < code > http _requests _total { job = "apiserver" , handler = "/api/comments" } < / code > < / pre >
< p > Return a whole range of time ( in this case 5 m inutes ) for the same vector ,
making it a range vector : < / p >
< pre > < code > http _requests _total { job = "apiserver" , handler = "/api/comments" } [ 5 m ] < / code > < / pre >
< p > Note that an expression resulting in a range vector cannot be graphed directly ,
but viewed in the tabular ( "Console" ) view of the expression browser . < / p >
< p > Using regular expressions , you c ould select time series only for jobs whose
name match a certain pattern , in this case , all jobs that end with < code > server < / code > : < / p >
< pre > < code > http _requests _total { job = ~ ".*server" } < / code > < / pre >
< p > All regular expressions in Prometheus use RE2 syntax . < / p >
< p > To select all HTTP status codes except 4 xx ones , you could run : < / p >
< pre > < code > http _requests _total { status ! ~ "4.." } < / code > < / pre >
< h2 >
Subquery
< / h2 >
< p > Return the 5 - minute rate of the < code > http _requests _total < / code > metric for the past 30 minutes , with a resolution of 1 minute . < / p >
< pre > < code > rate ( http _requests _total [ 5 m ] ) [ 30 m : 1 m ] < / code > < / pre >
< p > This is an example of a nested subquery . The subquery for the < code > deriv < / code > function uses the default resolution . Note that using subqueries unnecessarily is unwise . < / p >
< pre > < code > max _over _time ( deriv ( rate ( distance _covered _total [ 5 s ] ) [ 30 s : 5 s ] ) [ 10 m : ] ) < / code > < / pre >
< h2 >
Using functions , operators , etc .
< / h2 >
< p > Return the per - second rate for all time series with the < code > http _requests _total < / code >
metric name , as measured over the last 5 minutes : < / p >
< pre > < code > rate ( http _requests _total [ 5 m ] ) < / code > < / pre >
< p > Assuming that the < code > http _requests _total < / code > time series all have the labels < code > job < / code >
( fanout by job name ) and < code > instance < / code > ( fanout by instance of the job ) , we might
want to sum over the rate of all instances , so we get fewer output time series ,
but still preserve the < code > job < / code > dimension : < / p >
< pre > < code > sum by ( job ) ( rate ( http _requests _total [ 5 m ] ) ) < / code > < / pre >
< p > If we have two different metrics with the same dimensional labels , we can apply
binary operators to them and elements on both sides with the same label set
will get matched and propagated to the output . For example , this expression
returns the unused memory in MiB for every instance ( on a fictional cluster
scheduler exposing these metrics about the instances it runs ) : < / p >
< pre > < code > ( instance _memory _limit _bytes - instance _memory _usage _bytes ) / 1024 / 1024 < / code > < / pre >
< p > The same expression , but summed by application , could be written like this : < / p >
< pre > < code > sum by ( app , proc ) ( instance _memory _limit _bytes - instance _memory _usage _bytes ) / 1024 / 1024 < / code > < / pre >
< p > If the same fictional cluster scheduler exposed CPU usage metrics like the following for every instance : < / p >
< pre > < code > instance _cpu _time _ns { app = "lion" , proc = "web" , rev = "34d0f99" , env = "prod" , job = "cluster-manager" }
instance _cpu _time _ns { app = "elephant" , proc = "worker" , rev = "34d0f99" , env = "prod" , job = "cluster-manager" }
instance _cpu _time _ns { app = "turtle" , proc = "api" , rev = "4d3a513" , env = "prod" , job = "cluster-manager" }
instance _cpu _time _ns { app = "fox" , proc = "widget" , rev = "4d3a513" , env = "prod" , job = "cluster-manager" }
...
< / code > < / pre >
< p > ... we could get the top 3 CPU users grouped by application ( < code > app < / code > ) and process type ( < code > proc < / code > ) like this : < / p >
< pre > < code > topk ( 3 , sum by ( app , proc ) ( rate ( instance _cpu _time _ns [ 5 m ] ) ) ) < / code > < / pre >
< p > Assuming this metric contains one time series per running instance , you could count the number of running instances per application like this : < / p >
< pre > < code > count by ( app ) ( instance _cpu _time _ns ) < / code > < / pre >
< / div >
< / div >
< / div >
< / el-scrollbar >
< / div >
< chart-box ref = "addChartModal" :panel-data = "panelData" @ on -create -success = " createSuccess " > < / chart-box >
< chart-box ref = "addChartModal" :panel-data = "panelData" @ on -create -success = " createSuccess " > < / chart-box >
< element-set
:allowed-all = "true"
v-clickoutside = "elementsetHide"
:dropCol = "dropCol"
@tablelable ="tablelabelEmit"
:table-title = "tableLabels"
ref = "elementset"
> < / element-set >
< / div >
< / left-menu >
< / div >
@@ -134,23 +222,25 @@
import chart from "../overview/chart" ;
import axios from 'axios' ;
import chartBox from "../../../page/dashboard/chartBox" ;
export default {
name : "explore" ,
components : {
'promql-input' : promqlInput ,
'chart' : chart ,
'chart-box' : chartBox ,
'chart-box' : chartBox ,
} ,
data ( ) {
return {
promqlCount : 1 ,
promqlKeys : [ ] ,
expressions : [ '' ] ,
searchTime : [ new Date ( ) . setHours ( new Date ( ) . getHours ( ) - 1 ) , new Date ( ) ] ,
filterTime : { } ,
visible : false ,
showIntroduce : true ,
defaultChartVisible : true ,
defaultTableVisible : true ,
showIntroduce : true ,
defaultChartVisible : true ,
defaultTableVisible : true ,
chartVisible : true ,
tableVisible : true ,
pageObj : {
@@ -158,8 +248,10 @@
pageSize : 20 ,
total : 0
} ,
dropCol : [ ] ,
tableData : [ ] ,
tableLabels : [ ] ,
showTableLabels : [ ] ,
tableLoading : false ,
intervalTimer : null ,
intervalList : [ {
@@ -179,8 +271,8 @@
name : this . $t ( "dashboard.panel.refreshInterval.tenMinutes" ) ,
} ] ,
interval : 0 ,
saveDisabled : true ,
panelData : [ ] ,
saveDisabled : true ,
panelData : [ ] ,
pickerOptions : {
shortcuts : [
{
@@ -268,18 +360,19 @@
this . filterTime . startTime = bus . timeFormate ( this . searchTime [ 0 ] , 'yyyy-MM-dd hh:mm:ss' ) ;
this . filterTime . endTime = bus . timeFormate ( this . searchTime [ 1 ] , 'yyyy-MM-dd hh:mm:ss' ) ;
this . getPanelData ( ) ;
this . promqlKeys . push ( this . guid ( ) ) ;
} ,
methods : {
pageNo ( val ) {
this . pageObj . pageNo = val ;
this . tableData = this . filterShowData ( this . storedTableData , this . pageObj )
this . tableData = this . filterShowData ( this . storedTableData , this . pageObj )
} ,
pageSize ( val ) {
this . pageObj . pageSize = val ;
this . tableData = this . filterShowData ( this . storedTableData , this . pageObj )
this . tableData = this . filterShowData ( this . storedTableData , this . pageObj )
} ,
filterShowData ( source , pageObj ) {
return source . slice ( ( pageObj . pageNo - 1 ) * pageObj . pageSize , pageObj . pageNo * pageObj . pageSize )
filterShowData ( source , pageObj ) {
return source . slice ( ( pageObj . pageNo - 1 ) * pageObj . pageSize , pageObj . pageNo * pageObj . pageSize )
} ,
queryChartData : function ( ) {
this . $refs . exploreChart . startLoading ( ) ;
@@ -291,9 +384,9 @@
requestArr . push ( axios . get ( '/prom/api/v1/query_range?query=' + item + '&start=' + this . filterTime . startTime + '&end=' + this . filterTime . endTime + '&step=15' ) )
}
} )
if ( requestArr . length > 0 ) {
this . showIntroduce = false ;
this . saveDisabled = false ;
if ( requestArr . length > 0 ) {
this . showIntroduce = false ;
this . saveDisabled = false ;
}
axios . all ( requestArr ) . then ( res => {
let series = [ ] ;
@@ -313,7 +406,6 @@
seriesItem . data = result . values . map ( ( item ) => {
return [ item [ 0 ] * 1000 , item [ 1 ] ] ;
} )
// console.log(seriesItem);
let metric = Object . assign ( { } , result . metric ) ;
seriesItem . name += metric . _ _name _ _ + '{' ;
delete metric . _ _name _ _ ;
@@ -330,7 +422,7 @@
this . $refs . exploreChart . setLegend ( legend ) ;
this . $refs . exploreChart . setSeries ( series )
}
this . defaultChartVisible = true ;
this . defaultChartVisible = true ;
this . $refs . exploreChart . endLoading ( ) ;
} )
}
@@ -340,15 +432,14 @@
this . tableLoading = true ,
setTimeout ( ( ) => {
if ( this . expressions . length > 0 ) {
console . log ( this . expressions )
let requestArr = [ ] ;
this . expressions . forEach ( ( item , index ) => {
if ( item != '' ) {
requestArr . push ( axios . get ( '/prom/api/v1/query?query=' + item ) )
}
} )
if ( requestArr . length > 0 ) {
this . showIntroduce = false ;
if ( requestArr . length > 0 ) {
this . showIntroduce = false ;
}
axios . all ( requestArr ) . then ( res => {
let tData = [ ] ;
@@ -365,8 +456,9 @@
this . $set ( metrics , 'value#' + index , result . value [ 1 ] ) ;
for ( let key in metrics ) {
let label = {
label : key ,
prop : key
label : key == '__name__' ? 'metric' : key ,
prop : key ,
show : true ,
}
let temp = tLabels . find ( ( item , index ) => {
return item . prop == label . prop
@@ -383,12 +475,14 @@
return a . prop . charCodeAt ( 0 ) - b . prop . charCodeAt ( 0 ) ;
} )
} )
this . storedTableData = Object . assign ( [ ] , tData ) ;
this . pageObj . total = this . storedTableData . length ;
this . tableData = this . filterShowData ( this . storedTableData , this . pageObj ) ;
this . tableLabels = tLabels ;
this . storedTableData = Object . assign ( [ ] , tData ) ;
this . pageObj . total = this . storedTableData . length ;
this . tableData = this . filterShowData ( this . storedTableData , this . pageObj ) ;
this . tableLabels = Object . assign ( [ ] , tLabels ) ;
this . showTableLabels = Object . assign ( [ ] , tLabels ) ;
this . dropCol = Object . assign ( [ ] , tLabels ) ;
}
this . defaultTableVisible = true ;
this . defaultTableVisible = true ;
this . tableLoading = false ;
} )
}
@@ -402,11 +496,13 @@
} ,
addExpression : function ( index ) {
this . expressions . splice ( index + 1 , 0 , '' ) ;
this . promqlKeys . splice ( index + 1 , 0 , this . guid ( ) ) ;
this . promqlCount ++ ;
} ,
removeExpression : function ( index ) {
if ( this . promqlCount > 1 ) {
this . expressions . splice ( index , 1 ) ;
this . promqlKeys . splice ( index , 1 ) ;
this . promqlCount -- ;
}
} ,
@@ -445,30 +541,29 @@
//刷新数据
this . expressionChange ( ) ;
} ,
changeChartVisible : function ( ) {
this . chartVisible = ! this . chartVisible ;
changeChartVisible : function ( ) {
this . chartVisible = ! this . chartVisible ;
} ,
changeTableVisible : function ( ) {
this . tableVisible = ! this . tableVisible ;
changeTableVisible : function ( ) {
this . tableVisible = ! this . tableVisible ;
} ,
saveChart : function ( ) {
saveChart : function ( ) {
this . $refs . addChartModal . setTitle ( this . $t ( "dashboard.panel.createChartTitle" ) ) ;
this . $refs . addChartModal . show ( true ) ;
let metricInfo = { } ;
metricInfo . elements = [ ] ;
// {"metric":"ALERTS_FOR_STATE","elements":[{"expression":"ALERTS_FOR_STATE{project='kafka',module='node_exporter'}","type":"normal"}]}
for ( let i = 0 ; i < this . expressions . length ; i ++ ) {
if ( this . expressions [ i ] != '' ) {
for ( let i = 0 ; i < this . expressions . length ; i ++ ) {
if ( this . expressions [ i ] != '' ) {
let type = 'expert' ;
metricInfo . metric = this . expressions [ i ] ;
metricInfo . metric = this . expressions [ i ] ;
metricInfo . elements . push ( { expression : this . expressions [ i ] , type : type } ) ;
}
}
console . log ( metricInfo )
this . $refs . addChartModal . createData ( - 1 , metricInfo ) ;
} ,
createSuccess ( type , response , param , panel ) { //添加chart成功
this . $confirm ( this . $t ( "dashboard.metric.goPanelTip" ) , this . $t ( "tip.saveSuccess" ) , {
this . $confirm ( this . $t ( "dashboard.metric.goPanelTip" ) , this . $t ( "tip.saveSuccess" ) , {
confirmButtonText : this . $t ( "tip.yes" ) ,
cancelButtonText : this . $t ( "tip.no" ) ,
type : 'success'
@@ -491,6 +586,45 @@
}
} ) ;
} ,
guid ( ) {
function S4 ( ) {
return ( ( ( 1 + Math . random ( ) ) * 0x10000 ) | 0 ) . toString ( 16 ) . substring ( 1 ) ;
}
return ( S4 ( ) + S4 ( ) + "-" + S4 ( ) + "-" + S4 ( ) + "-" + S4 ( ) + "-" + S4 ( ) + S4 ( ) + S4 ( ) ) ;
} ,
elementsetShow ( s , e ) {
var eventfixed = {
shezhi : 0 ,
screen : 0
} ;
eventfixed [ s ] = 1 ;
e . preventDefault ( ) ;
this . $store . commit ( 'setEventfixed' , eventfixed ) ;
const h = document . documentElement . clientHeight ;
const w = document . documentElement . clientWidth ;
const dw = this . $refs . elementset . $el . offsetWidth ;
const dh = this . $refs . elementset . $el . offsetHeight ;
let positionx =
e . clientX + dw <= w - 10 ? e . clientX + 14 : e . clientX + 14 - dw ;
console . log ( e . clientY + dh )
console . log ( h )
let positiony =
e . clientY + dh <= h - 10
? e . clientY + 20
: e . clientY + 20 - ( e . clientY + dh - h + 30 ) ;
this . $store . commit ( 'setPosition' , { positionx , positiony } ) ;
} ,
elementsetHide ( ) {
//悬浮点击空白隐藏
this . $refs . elementset . elementsetHide ( ) ;
} ,
tablelabelEmit ( data ) {
//获取子组件传过来的参数
this . $store . commit ( 'setHeaderTable' , data ) ;
console . log ( data )
this . showTableLabels = data ;
} ,
jumpTo ( data , id ) {
bus . $emit ( "menu-change" , data ) ;
this . $router . push ( {
@@ -501,24 +635,28 @@
} ) ;
} ,
} ,
mounted ( ) {
} ,
watch : {
promqlCount : function ( n , o ) {
this . expressionChange ( ) ;
} ,
expressions : {
immediate : true ,
handler : function ( n , o ) {
if ( this . promqlCount == 1 && ( ! n [ 0 ] || n [ 0 ] == '' ) ) {
this . showIntroduce = true
} else if ( this . promqlCount > 1 ) {
let temp = n . find ( ( item , index ) => {item != '' } ) ;
if ( typeof temp != undefined ) {
this . showIntroduce = false ;
} else {
this . showIntroduce = true ;
expressions : {
immediate : true ,
handler : function ( n , o ) {
if ( n . length == 1 && ( ! n [ 0 ] || n [ 0 ] == '' ) ) {
this . showIntroduce = true
} else if ( n . length > 1 ) {
let temp = n . find ( ( item , index ) => {
return i tem != ''
} ) ;
if ( ! temp ) {
this . showIntroduce = true ;
} else {
this . showIntroduce = false ;
}
} else {
this . showIntroduce = false ;
} else {
this . showIntroduce = false ;
}
}
}
@@ -536,57 +674,66 @@
height : 500 px
}
. explore . chart - view , . table - view {
. explore . chart - view , . table - view {
padding : 10 px ;
border : 1 px solid lightgrey ;
box - sizing : inherit ;
margin - bottom : 5 px ;
transition : height 1 s ;
}
. shrink - view {
. shrink - view {
height : 30 px ;
. view - title i {
. view - title i {
transform : rotate ( 180 deg ) ;
}
. chart - room , . table - room {
. chart - room , . table - room {
height : 0 px ;
visibility : hidden ;
}
}
. explore . view - title {
font - weight : 500 ;
margin - right : 8 px ;
font - size : 14 px ;
box - shadow : none ;
}
. introduce - view . info - room {
. introduce - view . info - room {
padding : 24 px ;
background - color : # e9edf2 ;
border - top : 3 px solid # 3274 d9 ;
margin - bottom : 16 px ;
margin - right : 4 px ;
- webkit - box - shadow : - 1 px - 1 px 0 0 hsla ( 0 , 0 % , 100 % , .1 ) , 1 px 1 px 0 0 rgba ( 0 , 0 , 0 , .1 ) ;
box - shadow : - 1 px - 1 px 0 0 hsla ( 0 , 0 % , 100 % , .1 ) , 1 px 1 px 0 0 rgba ( 0 , 0 , 0 , .1 ) ;
- webkit - box - shadow : - 1 px - 1 px 0 0 hsla ( 0 , 0 % , 100 % , .1 ) , 1 px 1 px 0 0 rgba ( 0 , 0 , 0 , .1 ) ;
box - shadow : - 1 px - 1 px 0 0 hsla ( 0 , 0 % , 100 % , .1 ) , 1 px 1 px 0 0 rgba ( 0 , 0 , 0 , .1 ) ;
- webkit - box - flex : 1 ;
- webkit - flex - grow : 1 ;
- ms - flex - positive : 1 ;
flex - grow : 1 ;
}
. info - room . cheat - sheet - item _ _title {
font - size : 21 px ;
}
. info - room . cheat - sheet - item _ _label {
. info - room . cheat - sheet - item _ _label {
font - size : 13 px ;
}
. info - room code {
font - family : Menlo , Monaco , Consolas , Courier New , monospace ;
. info - room code {
font - family : Menlo , Monaco , Consolas , Courier New , monospace ;
font - size : 11 px ;
background - color : # e9edf2 ;
color : # 52545 c ;
border : 1 px solid # c7d0d9 ;
border - radius : 4 px ;
}
. popover _ul li {
padding : 10 px 3 px ;
cursor : pointer ;
@@ -596,6 +743,164 @@
background : $dropdown - hover - background - color ! important ;
color : $global - text - color - active ! important ;
}
/*外部引用 样式start*/
. doc - content {
font - size : 16 px ;
}
. doc - content p , . doc - content . ul , . doc - content . alert {
margin : 15 px 0 15 px 0 ;
line - height : 1.5 ;
}
. doc - content > h1 {
color : # e6522c ;
font - size : 30 px ;
text - transform : uppercase ;
margin : 40 px 0 10 px 0 ;
}
. doc - content > h1 a {
color : # e6522c ;
}
. doc - content . blog > h1 {
text - transform : none ;
}
. doc - content . blog . sponsor - logos > a > img {
width : 250 px ;
display : inline - block ! important ;
margin : 15 px 55 px ;
}
. doc - content > h2 {
color : # e6522c ;
font - size : 22 px ;
}
. doc - content > h2 code {
color : # e6522c ;
background : none ;
}
. doc - content > h3 {
font - size : 20 px ;
font - weight : bold ;
}
. doc - content > h4 {
font - weight : bold ;
font - size : 18 px ;
margin - top : 20 px ;
}
. doc - content a . header - anchor {
padding - left : 15 px ;
}
. doc - content a . header - anchor : after {
content : "\F0C1" ;
font - family : FontAwesome ;
font - weight : normal ;
font - size : .8 em ;
}
. doc - content a . header - anchor : link ,
. doc - content a . header - anchor : visited {
visibility : hidden ;
}
. doc - content h1 : hover a . header - anchor : hover ,
. doc - content h2 : hover a . header - anchor : hover ,
. doc - content h3 : hover a . header - anchor : hover ,
. doc - content h4 : hover a . header - anchor : hover ,
. doc - content h5 : hover a . header - anchor : hover ,
. doc - content h6 : hover a . header - anchor : hover {
color : # 000 ;
}
. doc - content h1 : hover a . header - anchor ,
. doc - content h2 : hover a . header - anchor ,
. doc - content h3 : hover a . header - anchor ,
. doc - content h4 : hover a . header - anchor ,
. doc - content h5 : hover a . header - anchor ,
. doc - content h6 : hover a . header - anchor {
color : # 999 ;
visibility : visible ;
}
. doc - content img {
width : 90 % ;
margin - left : auto ;
margin - right : auto ;
display : block ;
}
. doc - content img . orig - size {
width : auto ;
margin - left : 0 ;
}
. doc - content . open - source - notice {
color : # 666 ;
background - color : # f5f5f5 ;
text - align : center ;
padding : 0.8 em ;
margin - top : 1.5 em ;
}
. toc {
padding : 1 em ;
background - color : # f5f5f5 ;
}
. toc - right {
float : right ;
width : 40 % ;
margin : 0 0 0.5 em 0.5 em ;
}
. toc ul {
padding : 0 0 0 1.5 em ;
margin : 0 ;
}
. toc a code {
color : # 337 ab7 ;
background - color : transparent ;
}
pre {
border : 1 px solid # ddd ;
border - left : 4 px solid # e6522c ;
border - radius : 0 ;
font - family : "Courier New" , Monaco , Menlo , Consolas , monospace ;
background - color : # f5f5f5 ;
color : # 333 ;
padding : 15 px ;
}
pre code {
white - space : pre ;
}
code {
color : # 333 ;
}
aside {
color : # 888 ;
padding - bottom : 8 px ;
border - bottom : 1 px solid # aaa ;
}
article {
margin : 10 px 0 60 px 0 ;
}
/*外部引用 样式end*/
< / style >
< style >
. explore - table tr td . cell {