mirror of
https://github.com/valitydev/redash.git
synced 2024-11-07 17:38:54 +00:00
Merge branch 'master' into design/refinements-2
# Conflicts: # client/app/pages/dashboards/public-dashboard-page.html
This commit is contained in:
commit
a488de22c4
@ -1,282 +1,282 @@
|
|||||||
/* --------------------------------------------------------
|
/* --------------------------------------------------------
|
||||||
Paths
|
Paths
|
||||||
-----------------------------------------------------------*/
|
-----------------------------------------------------------*/
|
||||||
@imgpath: ~'../img';
|
@imgpath: ~'../img';
|
||||||
@fontpath: ~'../fonts';
|
@fontpath: ~'../fonts';
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------------------------------
|
/* --------------------------------------------------------
|
||||||
Container
|
Container
|
||||||
-----------------------------------------------------------*/
|
-----------------------------------------------------------*/
|
||||||
@container-tablet: 100%;
|
@container-tablet: 100%;
|
||||||
@container-desktop: 100%;
|
@container-desktop: 100%;
|
||||||
@container-large-desktop: 100%;
|
@container-large-desktop: 100%;
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------------------------------
|
/* --------------------------------------------------------
|
||||||
Template Variables
|
Template Variables
|
||||||
-----------------------------------------------------------*/
|
-----------------------------------------------------------*/
|
||||||
@header-height: 50px;
|
@header-height: 60px;
|
||||||
@footer-height: 95px;
|
@footer-height: 95px;
|
||||||
@sidebar-left-width: 240px;
|
@sidebar-left-width: 240px;
|
||||||
@sidebar-left-mid-width: 64px;
|
@sidebar-left-mid-width: 64px;
|
||||||
@logo-width: @sidebar-left-width;
|
@logo-width: @sidebar-left-width;
|
||||||
@logo-height: @header-height;
|
@logo-height: @header-height;
|
||||||
@boxed-width: 1170px;
|
@boxed-width: 1170px;
|
||||||
@body-bg: #edecec;
|
@body-bg: #edecec;
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------------------------------
|
/* --------------------------------------------------------
|
||||||
Branding
|
Branding
|
||||||
-----------------------------------------------------------*/
|
-----------------------------------------------------------*/
|
||||||
@brand-bg: #191C22;
|
@brand-bg: #191C22;
|
||||||
@sidebar: @brand-bg;
|
@sidebar: @brand-bg;
|
||||||
@sidebar-active-bg: #121419;
|
@sidebar-active-bg: #121419;
|
||||||
@color-dark: #9BA1B1;
|
@color-dark: #9BA1B1;
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------------------------------
|
/* --------------------------------------------------------
|
||||||
Font
|
Font
|
||||||
-----------------------------------------------------------*/
|
-----------------------------------------------------------*/
|
||||||
@font-icon: 'Material-Design-Iconic-Font';
|
@font-icon: 'Material-Design-Iconic-Font';
|
||||||
@font-family-sans-serif: 'Roboto', sans-serif;
|
@font-family-sans-serif: 'Roboto', sans-serif;
|
||||||
@font-size-base: 13px;
|
@font-size-base: 13px;
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------------------------------
|
/* --------------------------------------------------------
|
||||||
Typograpgy
|
Typograpgy
|
||||||
-----------------------------------------------------------*/
|
-----------------------------------------------------------*/
|
||||||
@text-color: #767676;
|
@text-color: #767676;
|
||||||
@link: #02a4c4;
|
@link: #02a4c4;
|
||||||
@link-hover-decoration: none;
|
@link-hover-decoration: none;
|
||||||
@headings-color: #333;
|
@headings-color: #333;
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------------------------------
|
/* --------------------------------------------------------
|
||||||
Form
|
Form
|
||||||
-----------------------------------------------------------*/
|
-----------------------------------------------------------*/
|
||||||
@input-color-placeholder: #b4b4b4;
|
@input-color-placeholder: #b4b4b4;
|
||||||
@input-border: #e8e8e8;
|
@input-border: #e8e8e8;
|
||||||
@input-border-radius: 0;
|
@input-border-radius: 0;
|
||||||
@input-border-radius-large: 0px;
|
@input-border-radius-large: 0px;
|
||||||
@input-height-large: 40px;
|
@input-height-large: 40px;
|
||||||
@input-height-base: 35px;
|
@input-height-base: 35px;
|
||||||
@input-height-small: 30px;
|
@input-height-small: 30px;
|
||||||
@input-border-focus: #79c2ff;
|
@input-border-focus: #79c2ff;
|
||||||
@input-group-addon-bg: @light-gray;
|
@input-group-addon-bg: @light-gray;
|
||||||
|
|
||||||
/* --------------------------------------------------------
|
/* --------------------------------------------------------
|
||||||
Colors
|
Colors
|
||||||
-----------------------------------------------------------*/
|
-----------------------------------------------------------*/
|
||||||
@white: #ffffff;
|
@white: #ffffff;
|
||||||
@black: #000000;
|
@black: #000000;
|
||||||
@blue: #2196F3;
|
@blue: #2196F3;
|
||||||
@red: #F44336;
|
@red: #F44336;
|
||||||
@purple: #9C27B0;
|
@purple: #9C27B0;
|
||||||
@deeppurple: #673AB7;
|
@deeppurple: #673AB7;
|
||||||
@lightblue: #03A9F4;
|
@lightblue: #03A9F4;
|
||||||
@cyan: #00BCD4;
|
@cyan: #00BCD4;
|
||||||
@teal: #009688;
|
@teal: #009688;
|
||||||
@green: #4CAF50;
|
@green: #4CAF50;
|
||||||
@lightgreen: #8BC34A;
|
@lightgreen: #8BC34A;
|
||||||
@lime: #CDDC39;
|
@lime: #CDDC39;
|
||||||
@yellow: #FFEB3B;
|
@yellow: #FFEB3B;
|
||||||
@amber: #FFC107;
|
@amber: #FFC107;
|
||||||
@orange: #FF9800;
|
@orange: #FF9800;
|
||||||
@deeporange: #FF5722;
|
@deeporange: #FF5722;
|
||||||
@gray: #9E9E9E;
|
@gray: #9E9E9E;
|
||||||
@bluegray: #607D8B;
|
@bluegray: #607D8B;
|
||||||
@indigo: #3F51B5;
|
@indigo: #3F51B5;
|
||||||
@pink: #E91E63;
|
@pink: #E91E63;
|
||||||
@brown: #795548;
|
@brown: #795548;
|
||||||
@light-gray: #FCFCFC;
|
@light-gray: #FCFCFC;
|
||||||
@gray-light: #828282;
|
@gray-light: #828282;
|
||||||
@ace: #f8f8f8;
|
@ace: #f8f8f8;
|
||||||
|
|
||||||
/** Form States **/
|
/** Form States **/
|
||||||
@state-success-text: @green;
|
@state-success-text: @green;
|
||||||
@state-info-text: @blue;
|
@state-info-text: @blue;
|
||||||
@state-danger-text: lighten(@red, 5%);
|
@state-danger-text: lighten(@red, 5%);
|
||||||
@state-warning-text: @orange;
|
@state-warning-text: @orange;
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------------------------------
|
/* --------------------------------------------------------
|
||||||
Alert
|
Alert
|
||||||
-----------------------------------------------------------*/
|
-----------------------------------------------------------*/
|
||||||
@alert-success-border: transparent;
|
@alert-success-border: transparent;
|
||||||
@alert-info-border: transparent;
|
@alert-info-border: transparent;
|
||||||
@alert-warning-border: transparent;
|
@alert-warning-border: transparent;
|
||||||
@alert-danger-border: transparent;
|
@alert-danger-border: transparent;
|
||||||
@alert-inverse-border: transparent;
|
@alert-inverse-border: transparent;
|
||||||
|
|
||||||
@alert-success-bg: fade(@green, 70%);
|
@alert-success-bg: fade(@green, 70%);
|
||||||
@alert-info-bg: fade(@blue, 70%);
|
@alert-info-bg: fade(@blue, 70%);
|
||||||
@alert-warning-bg: fade(@amber, 70%);
|
@alert-warning-bg: fade(@amber, 70%);
|
||||||
@alert-danger-bg: fade(@red, 70%);
|
@alert-danger-bg: fade(@red, 70%);
|
||||||
@alert-inverse-bg: #333;
|
@alert-inverse-bg: #333;
|
||||||
|
|
||||||
@alert-success-text: #fff;
|
@alert-success-text: #fff;
|
||||||
@alert-info-text: #fff;
|
@alert-info-text: #fff;
|
||||||
@alert-warning-text: #fff;
|
@alert-warning-text: #fff;
|
||||||
@alert-danger-text: #fff;
|
@alert-danger-text: #fff;
|
||||||
@alert-inverse-text: #fff;
|
@alert-inverse-text: #fff;
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------------------------------
|
/* --------------------------------------------------------
|
||||||
Bootstrap Brands
|
Bootstrap Brands
|
||||||
-----------------------------------------------------------*/
|
-----------------------------------------------------------*/
|
||||||
@brand-default: #eee;
|
@brand-default: #eee;
|
||||||
@brand-primary: @blue;
|
@brand-primary: @blue;
|
||||||
@brand-info: @cyan;
|
@brand-info: @cyan;
|
||||||
@brand-success: @green;
|
@brand-success: @green;
|
||||||
@brand-warning: @orange;
|
@brand-warning: @orange;
|
||||||
@brand-danger: @red;
|
@brand-danger: @red;
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------------------------------
|
/* --------------------------------------------------------
|
||||||
Border Radius
|
Border Radius
|
||||||
-----------------------------------------------------------*/
|
-----------------------------------------------------------*/
|
||||||
@border-radius-base: 2px;
|
@border-radius-base: 2px;
|
||||||
@border-radius-large: 2px;
|
@border-radius-large: 2px;
|
||||||
@border-radius-small: 2px;
|
@border-radius-small: 2px;
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------------------------------
|
/* --------------------------------------------------------
|
||||||
Dropdown
|
Dropdown
|
||||||
-----------------------------------------------------------*/
|
-----------------------------------------------------------*/
|
||||||
@dropdown-fallback-border: transparent;
|
@dropdown-fallback-border: transparent;
|
||||||
@dropdown-border: transparent;
|
@dropdown-border: transparent;
|
||||||
@dropdown-divider-bg: '';
|
@dropdown-divider-bg: '';
|
||||||
@dropdown-link-hover-bg: rgba(0,0,0,0.075);
|
@dropdown-link-hover-bg: rgba(0,0,0,0.075);
|
||||||
@dropdown-link-color: #333;
|
@dropdown-link-color: #333;
|
||||||
@dropdown-link-hover-color: #333;
|
@dropdown-link-hover-color: #333;
|
||||||
@dropdown-link-disabled-color: #e4e4e4;
|
@dropdown-link-disabled-color: #e4e4e4;
|
||||||
@dropdown-divider-bg: rgba(0,0,0,0.08);
|
@dropdown-divider-bg: rgba(0,0,0,0.08);
|
||||||
@dropdown-link-active-color: #333;
|
@dropdown-link-active-color: #333;
|
||||||
@dropdown-link-active-bg: rgba(0, 0, 0, 0.075);
|
@dropdown-link-active-bg: rgba(0, 0, 0, 0.075);
|
||||||
@zindex-dropdown: 9;
|
@zindex-dropdown: 9;
|
||||||
@dropdown-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
|
@dropdown-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
|
||||||
|
|
||||||
/* --------------------------------------------------------
|
/* --------------------------------------------------------
|
||||||
Page Header
|
Page Header
|
||||||
-----------------------------------------------------------*/
|
-----------------------------------------------------------*/
|
||||||
@page-header-border-color: transparent;
|
@page-header-border-color: transparent;
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------------------------------
|
/* --------------------------------------------------------
|
||||||
Buttons
|
Buttons
|
||||||
-----------------------------------------------------------*/
|
-----------------------------------------------------------*/
|
||||||
@btn-default-border: @input-border;
|
@btn-default-border: @input-border;
|
||||||
@btn-font-weight: 400;
|
@btn-font-weight: 400;
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------------------------------
|
/* --------------------------------------------------------
|
||||||
Tables
|
Tables
|
||||||
-----------------------------------------------------------*/
|
-----------------------------------------------------------*/
|
||||||
@table-bg: #fff;
|
@table-bg: #fff;
|
||||||
@table-border-color: #f0f0f0;
|
@table-border-color: #f0f0f0;
|
||||||
@table-cell-padding: 10px;
|
@table-cell-padding: 10px;
|
||||||
@table-condensed-cell-padding: 7px;
|
@table-condensed-cell-padding: 7px;
|
||||||
@table-bg-accent: @light-gray;
|
@table-bg-accent: @light-gray;
|
||||||
@table-bg-active: #FFFCBE;
|
@table-bg-active: #FFFCBE;
|
||||||
@table-bg-hover: lighten(@light-gray, 2%);
|
@table-bg-hover: lighten(@light-gray, 2%);
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------------------------------
|
/* --------------------------------------------------------
|
||||||
Pagination
|
Pagination
|
||||||
-----------------------------------------------------------*/
|
-----------------------------------------------------------*/
|
||||||
@pagination-bg: #E2E2E2;
|
@pagination-bg: #E2E2E2;
|
||||||
@pagination-border: #fff;
|
@pagination-border: #fff;
|
||||||
@pagination-color: #7E7E7E;
|
@pagination-color: #7E7E7E;
|
||||||
@pagination-active-bg: @lightblue;
|
@pagination-active-bg: @lightblue;
|
||||||
@pagination-active-border: @pagination-border;
|
@pagination-active-border: @pagination-border;
|
||||||
@pagination-disabled-bg: #E2E2E2;
|
@pagination-disabled-bg: #E2E2E2;
|
||||||
@pagination-disabled-border: @pagination-border;
|
@pagination-disabled-border: @pagination-border;
|
||||||
@pagination-hover-color: #333;
|
@pagination-hover-color: #333;
|
||||||
@pagination-hover-bg: #d7d7d7;
|
@pagination-hover-bg: #d7d7d7;
|
||||||
@pagination-hover-border: @pagination-border;
|
@pagination-hover-border: @pagination-border;
|
||||||
@pager-border-radius: 5px;
|
@pager-border-radius: 5px;
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------------------------------
|
/* --------------------------------------------------------
|
||||||
Thumbnail
|
Thumbnail
|
||||||
-----------------------------------------------------------*/
|
-----------------------------------------------------------*/
|
||||||
@thumbnail-bg: #fff;
|
@thumbnail-bg: #fff;
|
||||||
@thumbnail-border: #eee;
|
@thumbnail-border: #eee;
|
||||||
|
|
||||||
/* --------------------------------------------------------
|
/* --------------------------------------------------------
|
||||||
Carousel
|
Carousel
|
||||||
-----------------------------------------------------------*/
|
-----------------------------------------------------------*/
|
||||||
@carousel-caption-color: #fff;
|
@carousel-caption-color: #fff;
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------------------------------
|
/* --------------------------------------------------------
|
||||||
Modal
|
Modal
|
||||||
-----------------------------------------------------------*/
|
-----------------------------------------------------------*/
|
||||||
@modal-content-fallback-border-color: transparent;
|
@modal-content-fallback-border-color: transparent;
|
||||||
@modal-content-border-color: transparent;
|
@modal-content-border-color: transparent;
|
||||||
@modal-backdrop-bg: #000;
|
@modal-backdrop-bg: #000;
|
||||||
@modal-header-border-color: transparent;
|
@modal-header-border-color: transparent;
|
||||||
@modal-title-line-height: transparent;
|
@modal-title-line-height: transparent;
|
||||||
@modal-footer-border-color: transparent;
|
@modal-footer-border-color: transparent;
|
||||||
@zindex-modal-background: 10;
|
@zindex-modal-background: 10;
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------------------------------
|
/* --------------------------------------------------------
|
||||||
Tooltips
|
Tooltips
|
||||||
-----------------------------------------------------------*/
|
-----------------------------------------------------------*/
|
||||||
@tooltip-bg: #333;
|
@tooltip-bg: #333;
|
||||||
@tooltip-opacity: 1;
|
@tooltip-opacity: 1;
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------------------------------
|
/* --------------------------------------------------------
|
||||||
Popobver
|
Popobver
|
||||||
-----------------------------------------------------------*/
|
-----------------------------------------------------------*/
|
||||||
@zindex-popover: 9;
|
@zindex-popover: 9;
|
||||||
@popover-title-bg: #fff;
|
@popover-title-bg: #fff;
|
||||||
@popover-border-color: #fff;
|
@popover-border-color: #fff;
|
||||||
@popover-fallback-border-color: #fff;
|
@popover-fallback-border-color: #fff;
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------------------------------
|
/* --------------------------------------------------------
|
||||||
Breacrumb
|
Breacrumb
|
||||||
-----------------------------------------------------------*/
|
-----------------------------------------------------------*/
|
||||||
@breadcrumb-bg: transparent;
|
@breadcrumb-bg: transparent;
|
||||||
@breadcrumb-padding-horizontal: 20px;
|
@breadcrumb-padding-horizontal: 20px;
|
||||||
@breadcrumb-active-color: #7c7c7c;
|
@breadcrumb-active-color: #7c7c7c;
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------------------------------
|
/* --------------------------------------------------------
|
||||||
Jumbotron
|
Jumbotron
|
||||||
-----------------------------------------------------------*/
|
-----------------------------------------------------------*/
|
||||||
@jumbotron-bg: #F7F7F7;
|
@jumbotron-bg: #F7F7F7;
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------------------------------
|
/* --------------------------------------------------------
|
||||||
List Group
|
List Group
|
||||||
-----------------------------------------------------------*/
|
-----------------------------------------------------------*/
|
||||||
@list-group-border: #f4f4f4;
|
@list-group-border: #f4f4f4;
|
||||||
@list-group-active-color: #000;
|
@list-group-active-color: #000;
|
||||||
@list-group-active-bg: #f5f5f5;
|
@list-group-active-bg: #f5f5f5;
|
||||||
@list-group-active-border: @list-group-border;
|
@list-group-active-border: @list-group-border;
|
||||||
@list-group-disabled-color: #B5B4B4;
|
@list-group-disabled-color: #B5B4B4;
|
||||||
@list-group-disabled-bg: #fff;
|
@list-group-disabled-bg: #fff;
|
||||||
@list-group-disabled-text-color: #B5B4B4;
|
@list-group-disabled-text-color: #B5B4B4;
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------------------------------
|
/* --------------------------------------------------------
|
||||||
Badges
|
Badges
|
||||||
-----------------------------------------------------------*/
|
-----------------------------------------------------------*/
|
||||||
@badge-color: #fff;
|
@badge-color: #fff;
|
||||||
@badge-bg: @brand-primary;
|
@badge-bg: @brand-primary;
|
||||||
@badge-border-radius: 2px;
|
@badge-border-radius: 2px;
|
||||||
@badge-font-weight: 400;
|
@badge-font-weight: 400;
|
||||||
@badge-active-color: #fff;
|
@badge-active-color: #fff;
|
||||||
@badge-active-bg: @brand-primary;
|
@badge-active-bg: @brand-primary;
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------------------------------
|
/* --------------------------------------------------------
|
||||||
Misc
|
Misc
|
||||||
-----------------------------------------------------------*/
|
-----------------------------------------------------------*/
|
||||||
@code-bg: transparent;
|
@code-bg: transparent;
|
||||||
@tile-shadow: 0 1px 1px rgba(0,0,0,0.07);
|
@tile-shadow: 0 1px 1px rgba(0,0,0,0.07);
|
||||||
|
10
client/app/assets/less/inc/visualizations/cohort.less
Normal file
10
client/app/assets/less/inc/visualizations/cohort.less
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
cohort-renderer {
|
||||||
|
display: block;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cornelius-container {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0 10px;
|
||||||
|
}
|
@ -7,6 +7,7 @@ counter-renderer {
|
|||||||
|
|
||||||
counter-renderer counter {
|
counter-renderer counter {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
display: block;
|
display: block;
|
||||||
font-size: 80px;
|
font-size: 80px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
@ -12,3 +12,8 @@
|
|||||||
stroke: #000;
|
stroke: #000;
|
||||||
stroke-opacity: .2;
|
stroke-opacity: .2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sankey-visualization-container {
|
||||||
|
height: 500px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
36
client/app/assets/less/inc/visualizations/sunburst.less
Normal file
36
client/app/assets/less/inc/visualizations/sunburst.less
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
.sunburst-visualization-container {
|
||||||
|
height: 400px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
> div {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
flex-grow: 0;
|
||||||
|
}
|
||||||
|
&:last-child {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sunburst-container,
|
||||||
|
.summary-container {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: auto;
|
||||||
|
height: auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-container {
|
||||||
|
font-size: 11px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
}
|
@ -61,6 +61,8 @@
|
|||||||
@import 'inc/visualizations/pivot-table';
|
@import 'inc/visualizations/pivot-table';
|
||||||
@import 'inc/visualizations/map';
|
@import 'inc/visualizations/map';
|
||||||
@import 'inc/visualizations/chart';
|
@import 'inc/visualizations/chart';
|
||||||
|
@import 'inc/visualizations/sunburst';
|
||||||
|
@import 'inc/visualizations/cohort';
|
||||||
@import 'inc/visualizations/misc';
|
@import 'inc/visualizations/misc';
|
||||||
|
|
||||||
/** VENDOR OVERRIDES **/
|
/** VENDOR OVERRIDES **/
|
||||||
@ -71,4 +73,4 @@
|
|||||||
@import 'inc/vendor-overrides/ui-select';
|
@import 'inc/vendor-overrides/ui-select';
|
||||||
|
|
||||||
/** REDASH STYLING **/
|
/** REDASH STYLING **/
|
||||||
@import 'redash-newstyle';
|
@import 'redash-newstyle';
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<nav class="navbar navbar-default app-header" role="navigation">
|
<nav class="navbar navbar-default app-header" role="navigation">
|
||||||
<div class="container"">
|
<div class="container">
|
||||||
<div class="navbar-header">
|
<div class="navbar-header">
|
||||||
<button type="button" class="navbar-toggle" ng-click="isNavOpen = !isNavOpen">
|
<button type="button" class="navbar-toggle" ng-click="isNavOpen = !isNavOpen">
|
||||||
<span class="sr-only">Toggle navigation</span>
|
<span class="sr-only">Toggle navigation</span>
|
||||||
|
@ -28,9 +28,8 @@ function Sunburst(scope, element) {
|
|||||||
this.watches = [];
|
this.watches = [];
|
||||||
|
|
||||||
// svg dimensions
|
// svg dimensions
|
||||||
const width = element[0].parentElement.clientWidth;
|
const width = element.clientWidth;
|
||||||
const height = scope.visualization.options.height;
|
const height = element.offsetHeight;
|
||||||
const radius = Math.min(width, height) / 2;
|
|
||||||
|
|
||||||
// Breadcrumb dimensions: width, height, spacing, width of tip/tail.
|
// Breadcrumb dimensions: width, height, spacing, width of tip/tail.
|
||||||
const b = {
|
const b = {
|
||||||
@ -40,6 +39,11 @@ function Sunburst(scope, element) {
|
|||||||
t: 10,
|
t: 10,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const radius = Math.min(width - b.h, height - b.h) / 2 - 5;
|
||||||
|
if (radius <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// margins
|
// margins
|
||||||
const margin = {
|
const margin = {
|
||||||
top: radius,
|
top: radius,
|
||||||
@ -77,14 +81,7 @@ function Sunburst(scope, element) {
|
|||||||
*
|
*
|
||||||
* e.g. vis, breadcrumbs, lastCrumb, summary, sunburst, legend
|
* e.g. vis, breadcrumbs, lastCrumb, summary, sunburst, legend
|
||||||
*/
|
*/
|
||||||
// create main vis selection
|
const vis = d3.select(element);
|
||||||
const vis = d3
|
|
||||||
.select(element[0])
|
|
||||||
.append('div')
|
|
||||||
.classed('vis-container', true)
|
|
||||||
.style('position', 'relative')
|
|
||||||
.style('margin-top', '5px')
|
|
||||||
.style('height', `${height + 2 * b.h}px`);
|
|
||||||
|
|
||||||
// create and position breadcrumbs container and svg
|
// create and position breadcrumbs container and svg
|
||||||
const breadcrumbs = vis
|
const breadcrumbs = vis
|
||||||
@ -96,39 +93,26 @@ function Sunburst(scope, element) {
|
|||||||
.attr('fill', 'white')
|
.attr('fill', 'white')
|
||||||
.attr('font-weight', 600);
|
.attr('font-weight', 600);
|
||||||
|
|
||||||
const marginLeft = (width - radius * 2) / 2;
|
|
||||||
|
|
||||||
// create and position SVG
|
// create and position SVG
|
||||||
const sunburst = vis
|
const container = vis.append('div');
|
||||||
|
|
||||||
|
// create and position summary container
|
||||||
|
const summary = container
|
||||||
|
.append('div')
|
||||||
|
.classed('summary-container', true);
|
||||||
|
|
||||||
|
const sunburst = container
|
||||||
.append('div')
|
.append('div')
|
||||||
.classed('sunburst-container', true)
|
.classed('sunburst-container', true)
|
||||||
.style('z-index', '2')
|
|
||||||
// .style("margin-left", marginLeft + "px")
|
|
||||||
.style('left', `${marginLeft}px`)
|
|
||||||
.style('position', 'absolute')
|
|
||||||
.append('svg')
|
.append('svg')
|
||||||
.attr('width', width)
|
.attr('width', radius * 2)
|
||||||
.attr('height', height)
|
.attr('height', radius * 2)
|
||||||
.append('g')
|
.append('g')
|
||||||
.attr('transform', `translate(${margin.left},${margin.top})`);
|
.attr('transform', `translate(${margin.left},${margin.top})`);
|
||||||
|
|
||||||
// create last breadcrumb element
|
// create last breadcrumb element
|
||||||
const lastCrumb = breadcrumbs.append('text').classed('lastCrumb', true);
|
const lastCrumb = breadcrumbs.append('text').classed('lastCrumb', true);
|
||||||
|
|
||||||
// create and position summary container
|
|
||||||
const summary = vis
|
|
||||||
.append('div')
|
|
||||||
.classed('summary-container', true)
|
|
||||||
.style('position', 'absolute')
|
|
||||||
.style('top', `${b.h + radius * 0.8}px`)
|
|
||||||
.style('left', `${marginLeft + radius / 2}px`)
|
|
||||||
.style('width', `${radius}px`)
|
|
||||||
.style('height', `${radius}px`)
|
|
||||||
.style('text-align', 'center')
|
|
||||||
.style('font-size', '11px')
|
|
||||||
.style('color', '#666')
|
|
||||||
.style('z-index', '1');
|
|
||||||
|
|
||||||
// Generate a string representation for drawing a breadcrumb polygon.
|
// Generate a string representation for drawing a breadcrumb polygon.
|
||||||
function breadcrumbPoints(d, i) {
|
function breadcrumbPoints(d, i) {
|
||||||
const points = [];
|
const points = [];
|
||||||
@ -208,8 +192,11 @@ function Sunburst(scope, element) {
|
|||||||
.attr('opacity', 1);
|
.attr('opacity', 1);
|
||||||
|
|
||||||
// update summary
|
// update summary
|
||||||
summary.html(`Stage: ${d.depth}<br />` +
|
summary.html(`
|
||||||
`<span class='percentage' style='font-size: 2em;'>${percentageString}</span><br />${d.value} of ${totalSize}<br />`);
|
<span>Stage: ${d.depth}</span>
|
||||||
|
<span class='percentage' style='font-size: 2em;'>${percentageString}</span>
|
||||||
|
<span>${d.value} of ${totalSize}</span>
|
||||||
|
`);
|
||||||
|
|
||||||
// display summary and breadcrumbs if hidden
|
// display summary and breadcrumbs if hidden
|
||||||
summary.style('visibility', '');
|
summary.style('visibility', '');
|
||||||
@ -394,7 +381,7 @@ Sunburst.prototype.remove = function remove() {
|
|||||||
this.watches.forEach((unregister) => {
|
this.watches.forEach((unregister) => {
|
||||||
unregister();
|
unregister();
|
||||||
});
|
});
|
||||||
angular.element(this.element[0]).empty('.vis-container');
|
angular.element(this.element).empty('.vis-container');
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Sunburst;
|
export default Sunburst;
|
||||||
|
@ -1,12 +1,9 @@
|
|||||||
.dashboard-wrapper {
|
.dashboard-wrapper {
|
||||||
.tile {
|
.tile {
|
||||||
position: absolute;
|
display: flex;
|
||||||
left: 0;
|
position: static;
|
||||||
top: 0;
|
height: auto;
|
||||||
right: 0;
|
margin-bottom: 15px;
|
||||||
bottom: 0;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pivot-table-renderer > table, grid-renderer > div, visualization-renderer > div {
|
pivot-table-renderer > table, grid-renderer > div, visualization-renderer > div {
|
||||||
@ -31,36 +28,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.map-visualization-container {
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
width: auto;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
counter {
|
|
||||||
position: absolute;
|
|
||||||
left: 10px;
|
|
||||||
top: 15px;
|
|
||||||
right: 10px;
|
|
||||||
bottom: 15px;
|
|
||||||
overflow: hidden;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.plotly-chart-container {
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
height: auto;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gridster-preview-holder {
|
.gridster-preview-holder {
|
||||||
background: #aaa;
|
background: #aaa;
|
||||||
}
|
}
|
||||||
@ -72,31 +39,46 @@
|
|||||||
margin-left: 0 !important;
|
margin-left: 0 !important;
|
||||||
margin-right: 0 !important;
|
margin-right: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tile {
|
|
||||||
display: block;
|
|
||||||
position: static;
|
|
||||||
height: auto;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.gridster-mobile, .gridster-auto-height-enabled {
|
&:not(.gridster-mobile) {
|
||||||
counter {
|
.tile {
|
||||||
position: static;
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: auto;
|
||||||
|
height: auto;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.plotly-chart-container {
|
.gridster-item:not(.gridster-auto-height-enabled) {
|
||||||
position: static;
|
.sunburst-visualization-container,
|
||||||
height: 400px;
|
.sankey-visualization-container,
|
||||||
overflow: hidden;
|
.map-visualization-container,
|
||||||
}
|
.plotly-chart-container {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: auto;
|
||||||
|
height: auto;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
.map-visualization-container {
|
counter {
|
||||||
position: static;
|
position: absolute;
|
||||||
height: 500px;
|
left: 10px;
|
||||||
|
top: 15px;
|
||||||
|
right: 10px;
|
||||||
|
bottom: 15px;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,17 @@
|
|||||||
|
<<<<<<< HEAD
|
||||||
<div class="container m-t-10">
|
<div class="container m-t-10">
|
||||||
|
=======
|
||||||
|
<!-- simple nav bar -->
|
||||||
|
<nav class="navbar navbar-inverse" role="navigation" ng-if="!$ctrl.headless">
|
||||||
|
<div class="container">
|
||||||
|
<div class="navbar-header">
|
||||||
|
<a class="navbar-brand" href="/" target="_self"><img ng-src="{{$ctrl.logoUrl}}"/></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
>>>>>>> master
|
||||||
<page-header title="{{$ctrl.dashboard.name}}">
|
<page-header title="{{$ctrl.dashboard.name}}">
|
||||||
</page-header>
|
</page-header>
|
||||||
|
|
||||||
@ -16,5 +29,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
<footer>
|
<footer>
|
||||||
</footer>
|
</footer>
|
||||||
|
=======
|
||||||
|
<style>
|
||||||
|
body { padding-bottom: 15px; }
|
||||||
|
</style>
|
||||||
|
>>>>>>> master
|
||||||
|
@ -123,13 +123,6 @@
|
|||||||
</ui-select>
|
</ui-select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group" ng-if="options.globalSeriesType == 'box'">
|
|
||||||
<label>
|
|
||||||
<label class="control-label">Graph Height</label>
|
|
||||||
<input name="graph-height" type="number" class="form-control" ng-model="options.height">
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group" ng-if="options.globalSeriesType == 'custom'">
|
<div class="form-group" ng-if="options.globalSeriesType == 'custom'">
|
||||||
|
@ -65,10 +65,6 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="control-label">Map Height (px)</label>
|
|
||||||
<input class="form-control" type="number" ng-model="visualization.options.height"/>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label">Map Tiles</label>
|
<label class="control-label">Map Tiles</label>
|
||||||
<select ng-options="tile.url as tile.name for tile in mapTiles" ng-model="visualization.options.mapTileUrl"
|
<select ng-options="tile.url as tile.name for tile in mapTiles" ng-model="visualization.options.mapTileUrl"
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import angular from 'angular';
|
import angular from 'angular';
|
||||||
import _ from 'underscore';
|
import _ from 'underscore';
|
||||||
import $ from 'jquery';
|
|
||||||
import d3 from 'd3';
|
import d3 from 'd3';
|
||||||
|
|
||||||
import d3sankey from '@/lib/visualizations/d3sankey';
|
import d3sankey from '@/lib/visualizations/d3sankey';
|
||||||
@ -95,12 +94,16 @@ function spreadNodes(height, data) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function createSankey(element, sankeyHeight, data) {
|
function createSankey(element, data) {
|
||||||
const margin = {
|
const margin = {
|
||||||
top: 10, right: 10, bottom: 10, left: 10,
|
top: 10, right: 10, bottom: 10, left: 10,
|
||||||
};
|
};
|
||||||
const width = $(element).parent().width() - margin.left - margin.right;
|
const width = element.offsetWidth - margin.left - margin.right;
|
||||||
const height = sankeyHeight - margin.top - margin.bottom;
|
const height = element.offsetHeight - margin.top - margin.bottom;
|
||||||
|
|
||||||
|
if ((width <= 0) || (height <= 0)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const format = d => d3.format(',.0f')(d);
|
const format = d => d3.format(',.0f')(d);
|
||||||
const color = d3.scale.category20();
|
const color = d3.scale.category20();
|
||||||
@ -216,17 +219,20 @@ function createSankey(element, sankeyHeight, data) {
|
|||||||
function sankeyRenderer() {
|
function sankeyRenderer() {
|
||||||
return {
|
return {
|
||||||
restrict: 'E',
|
restrict: 'E',
|
||||||
|
template: '<div class="sankey-visualization-container" resize-event="handleResize()"></div>',
|
||||||
link(scope, element) {
|
link(scope, element) {
|
||||||
|
const container = element[0].querySelector('.sankey-visualization-container');
|
||||||
|
|
||||||
function refreshData() {
|
function refreshData() {
|
||||||
const queryData = scope.queryResult.getData();
|
const queryData = scope.queryResult.getData();
|
||||||
if (queryData) {
|
if (queryData) {
|
||||||
// do the render logic.
|
// do the render logic.
|
||||||
angular.element(element[0]).empty();
|
angular.element(container).empty();
|
||||||
createSankey(element[0], scope.visualization.options.height, queryData);
|
createSankey(container, queryData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
angular.element(window).on('resize', refreshData);
|
scope.handleResize = _.debounce(refreshData, 50);
|
||||||
scope.$watch('queryResult && queryResult.getData()', refreshData);
|
scope.$watch('queryResult && queryResult.getData()', refreshData);
|
||||||
scope.$watch('visualization.options.height', (oldValue, newValue) => {
|
scope.$watch('visualization.options.height', (oldValue, newValue) => {
|
||||||
if (oldValue !== newValue) {
|
if (oldValue !== newValue) {
|
||||||
@ -250,11 +256,11 @@ export default function init(ngModule) {
|
|||||||
|
|
||||||
ngModule.config((VisualizationProvider) => {
|
ngModule.config((VisualizationProvider) => {
|
||||||
const renderTemplate =
|
const renderTemplate =
|
||||||
'<sankey-renderer options="visualization.options" query-result="queryResult"></sankey-renderer>';
|
'<sankey-renderer options="visualization.options" query-result="queryResult"></sankey-renderer>';
|
||||||
|
|
||||||
const editTemplate = '<sankey-editor></sankey-editor>';
|
const editTemplate = '<sankey-editor></sankey-editor>';
|
||||||
const defaultOptions = {
|
const defaultOptions = {
|
||||||
height: 300,
|
defaultRows: 7,
|
||||||
};
|
};
|
||||||
|
|
||||||
VisualizationProvider.registerVisualization({
|
VisualizationProvider.registerVisualization({
|
||||||
|
@ -1,12 +1,5 @@
|
|||||||
<div class="form-horizontal">
|
<div class="form-horizontal">
|
||||||
<div class="form-group">
|
|
||||||
<label class="col-lg-6">Height</label>
|
|
||||||
<div class="col-lg-6">
|
|
||||||
<input type="number" ng-model="visualization.options.height" min="1" class="form-control">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
<div>
|
||||||
<hr>
|
|
||||||
This visualization expects the query result to have rows in the following format:
|
This visualization expects the query result to have rows in the following format:
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -1,19 +1,22 @@
|
|||||||
import jQuery from 'jquery';
|
import { debounce } from 'underscore';
|
||||||
import Sunburst from '@/lib/visualizations/sunburst';
|
import Sunburst from '@/lib/visualizations/sunburst';
|
||||||
import editorTemplate from './sunburst-sequence-editor.html';
|
import editorTemplate from './sunburst-sequence-editor.html';
|
||||||
|
|
||||||
function sunburstSequenceRenderer() {
|
function sunburstSequenceRenderer() {
|
||||||
return {
|
return {
|
||||||
restrict: 'E',
|
restrict: 'E',
|
||||||
|
template: '<div class="sunburst-visualization-container" resize-event="handleResize()"></div>',
|
||||||
link(scope, element) {
|
link(scope, element) {
|
||||||
let sunburst = new Sunburst(scope, element);
|
const container = element[0].querySelector('.sunburst-visualization-container');
|
||||||
|
let sunburst = new Sunburst(scope, container);
|
||||||
|
|
||||||
function resize() {
|
function resize() {
|
||||||
sunburst.remove();
|
sunburst.remove();
|
||||||
sunburst = new Sunburst(scope, element);
|
sunburst = new Sunburst(scope, container);
|
||||||
}
|
}
|
||||||
|
|
||||||
jQuery(window).on('resize', resize);
|
scope.handleResize = debounce(resize, 50);
|
||||||
|
|
||||||
scope.$watch('visualization.options.height', (oldValue, newValue) => {
|
scope.$watch('visualization.options.height', (oldValue, newValue) => {
|
||||||
if (oldValue !== newValue) {
|
if (oldValue !== newValue) {
|
||||||
resize();
|
resize();
|
||||||
@ -40,7 +43,7 @@ export default function init(ngModule) {
|
|||||||
|
|
||||||
const editTemplate = '<sunburst-sequence-editor></sunburst-sequence-editor>';
|
const editTemplate = '<sunburst-sequence-editor></sunburst-sequence-editor>';
|
||||||
const defaultOptions = {
|
const defaultOptions = {
|
||||||
height: 300,
|
defaultRows: 7,
|
||||||
};
|
};
|
||||||
|
|
||||||
VisualizationProvider.registerVisualization({
|
VisualizationProvider.registerVisualization({
|
||||||
|
@ -1,12 +1,5 @@
|
|||||||
<div class="form-horizontal">
|
<div class="form-horizontal">
|
||||||
<div class="form-group">
|
|
||||||
<label class="col-lg-6">Height</label>
|
|
||||||
<div class="col-lg-6">
|
|
||||||
<input type="number" ng-model="visualization.options.height" min="1" class="form-control">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
<div>
|
||||||
<hr>
|
|
||||||
This visualization expects the query result to have rows in one of the following formats:
|
This visualization expects the query result to have rows in one of the following formats:
|
||||||
|
|
||||||
<strong>Option 1:</strong>
|
<strong>Option 1:</strong>
|
||||||
|
@ -238,5 +238,15 @@ class Redshift(PostgreSQL):
|
|||||||
|
|
||||||
return schema.values()
|
return schema.values()
|
||||||
|
|
||||||
|
|
||||||
|
class CockroachDB(PostgreSQL):
|
||||||
|
def __init__(self, configuration):
|
||||||
|
super(CockroachDB, self).__init__(configuration)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def type(cls):
|
||||||
|
return "cockroach"
|
||||||
|
|
||||||
register(PostgreSQL)
|
register(PostgreSQL)
|
||||||
register(Redshift)
|
register(Redshift)
|
||||||
|
register(CockroachDB)
|
||||||
|
@ -43,7 +43,7 @@ def _guess_type(value):
|
|||||||
|
|
||||||
|
|
||||||
def extract_query_ids(query):
|
def extract_query_ids(query):
|
||||||
queries = re.findall(r'(?:join|from) query_(\d+)', query, re.IGNORECASE)
|
queries = re.findall(r'(?:join|from)\s+query_(\d+)', query, re.IGNORECASE)
|
||||||
return [int(q) for q in queries]
|
return [int(q) for q in queries]
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,6 +19,10 @@ class TestExtractQueryIds(TestCase):
|
|||||||
query = "SELECT * FROM query_123 JOIN query_4566"
|
query = "SELECT * FROM query_123 JOIN query_4566"
|
||||||
self.assertEquals([123, 4566], extract_query_ids(query))
|
self.assertEquals([123, 4566], extract_query_ids(query))
|
||||||
|
|
||||||
|
def test_finds_queries_with_whitespace_characters(self):
|
||||||
|
query = "SELECT * FROM query_123 a JOIN\tquery_4566 b ON a.id=b.parent_id JOIN\r\nquery_78 c ON b.id=c.parent_id"
|
||||||
|
self.assertEquals([123, 4566, 78], extract_query_ids(query))
|
||||||
|
|
||||||
|
|
||||||
class TestCreateTable(TestCase):
|
class TestCreateTable(TestCase):
|
||||||
def test_creates_table_with_colons_in_column_name(self):
|
def test_creates_table_with_colons_in_column_name(self):
|
||||||
|
Loading…
Reference in New Issue
Block a user