Merge branch 'master' into design/refinements-2

# Conflicts:
#	client/app/pages/dashboards/public-dashboard-page.html
This commit is contained in:
Zsolt Kocsmarszky 2017-11-25 06:27:52 +01:00
commit a488de22c4
19 changed files with 456 additions and 416 deletions

View File

@ -1,282 +1,282 @@
/* --------------------------------------------------------
Paths
-----------------------------------------------------------*/
@imgpath: ~'../img';
@fontpath: ~'../fonts';
/* --------------------------------------------------------
Container
-----------------------------------------------------------*/
@container-tablet: 100%;
@container-desktop: 100%;
@container-large-desktop: 100%;
/* --------------------------------------------------------
Template Variables
-----------------------------------------------------------*/
@header-height: 50px;
@footer-height: 95px;
@sidebar-left-width: 240px;
@sidebar-left-mid-width: 64px;
@logo-width: @sidebar-left-width;
@logo-height: @header-height;
@boxed-width: 1170px;
@body-bg: #edecec;
/* --------------------------------------------------------
Branding
-----------------------------------------------------------*/
@brand-bg: #191C22;
@sidebar: @brand-bg;
@sidebar-active-bg: #121419;
@color-dark: #9BA1B1;
/* --------------------------------------------------------
Font
-----------------------------------------------------------*/
@font-icon: 'Material-Design-Iconic-Font';
@font-family-sans-serif: 'Roboto', sans-serif;
@font-size-base: 13px;
/* --------------------------------------------------------
Typograpgy
-----------------------------------------------------------*/
@text-color: #767676;
@link: #02a4c4;
@link-hover-decoration: none;
@headings-color: #333;
/* --------------------------------------------------------
Form
-----------------------------------------------------------*/
@input-color-placeholder: #b4b4b4;
@input-border: #e8e8e8;
@input-border-radius: 0;
@input-border-radius-large: 0px;
@input-height-large: 40px;
@input-height-base: 35px;
@input-height-small: 30px;
@input-border-focus: #79c2ff;
@input-group-addon-bg: @light-gray;
/* --------------------------------------------------------
Colors
-----------------------------------------------------------*/
@white: #ffffff;
@black: #000000;
@blue: #2196F3;
@red: #F44336;
@purple: #9C27B0;
@deeppurple: #673AB7;
@lightblue: #03A9F4;
@cyan: #00BCD4;
@teal: #009688;
@green: #4CAF50;
@lightgreen: #8BC34A;
@lime: #CDDC39;
@yellow: #FFEB3B;
@amber: #FFC107;
@orange: #FF9800;
@deeporange: #FF5722;
@gray: #9E9E9E;
@bluegray: #607D8B;
@indigo: #3F51B5;
@pink: #E91E63;
@brown: #795548;
@light-gray: #FCFCFC;
@gray-light: #828282;
@ace: #f8f8f8;
/** Form States **/
@state-success-text: @green;
@state-info-text: @blue;
@state-danger-text: lighten(@red, 5%);
@state-warning-text: @orange;
/* --------------------------------------------------------
Alert
-----------------------------------------------------------*/
@alert-success-border: transparent;
@alert-info-border: transparent;
@alert-warning-border: transparent;
@alert-danger-border: transparent;
@alert-inverse-border: transparent;
@alert-success-bg: fade(@green, 70%);
@alert-info-bg: fade(@blue, 70%);
@alert-warning-bg: fade(@amber, 70%);
@alert-danger-bg: fade(@red, 70%);
@alert-inverse-bg: #333;
@alert-success-text: #fff;
@alert-info-text: #fff;
@alert-warning-text: #fff;
@alert-danger-text: #fff;
@alert-inverse-text: #fff;
/* --------------------------------------------------------
Bootstrap Brands
-----------------------------------------------------------*/
@brand-default: #eee;
@brand-primary: @blue;
@brand-info: @cyan;
@brand-success: @green;
@brand-warning: @orange;
@brand-danger: @red;
/* --------------------------------------------------------
Border Radius
-----------------------------------------------------------*/
@border-radius-base: 2px;
@border-radius-large: 2px;
@border-radius-small: 2px;
/* --------------------------------------------------------
Dropdown
-----------------------------------------------------------*/
@dropdown-fallback-border: transparent;
@dropdown-border: transparent;
@dropdown-divider-bg: '';
@dropdown-link-hover-bg: rgba(0,0,0,0.075);
@dropdown-link-color: #333;
@dropdown-link-hover-color: #333;
@dropdown-link-disabled-color: #e4e4e4;
@dropdown-divider-bg: rgba(0,0,0,0.08);
@dropdown-link-active-color: #333;
@dropdown-link-active-bg: rgba(0, 0, 0, 0.075);
@zindex-dropdown: 9;
@dropdown-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
/* --------------------------------------------------------
Page Header
-----------------------------------------------------------*/
@page-header-border-color: transparent;
/* --------------------------------------------------------
Buttons
-----------------------------------------------------------*/
@btn-default-border: @input-border;
@btn-font-weight: 400;
/* --------------------------------------------------------
Tables
-----------------------------------------------------------*/
@table-bg: #fff;
@table-border-color: #f0f0f0;
@table-cell-padding: 10px;
@table-condensed-cell-padding: 7px;
@table-bg-accent: @light-gray;
@table-bg-active: #FFFCBE;
@table-bg-hover: lighten(@light-gray, 2%);
/* --------------------------------------------------------
Pagination
-----------------------------------------------------------*/
@pagination-bg: #E2E2E2;
@pagination-border: #fff;
@pagination-color: #7E7E7E;
@pagination-active-bg: @lightblue;
@pagination-active-border: @pagination-border;
@pagination-disabled-bg: #E2E2E2;
@pagination-disabled-border: @pagination-border;
@pagination-hover-color: #333;
@pagination-hover-bg: #d7d7d7;
@pagination-hover-border: @pagination-border;
@pager-border-radius: 5px;
/* --------------------------------------------------------
Thumbnail
-----------------------------------------------------------*/
@thumbnail-bg: #fff;
@thumbnail-border: #eee;
/* --------------------------------------------------------
Carousel
-----------------------------------------------------------*/
@carousel-caption-color: #fff;
/* --------------------------------------------------------
Modal
-----------------------------------------------------------*/
@modal-content-fallback-border-color: transparent;
@modal-content-border-color: transparent;
@modal-backdrop-bg: #000;
@modal-header-border-color: transparent;
@modal-title-line-height: transparent;
@modal-footer-border-color: transparent;
@zindex-modal-background: 10;
/* --------------------------------------------------------
Tooltips
-----------------------------------------------------------*/
@tooltip-bg: #333;
@tooltip-opacity: 1;
/* --------------------------------------------------------
Popobver
-----------------------------------------------------------*/
@zindex-popover: 9;
@popover-title-bg: #fff;
@popover-border-color: #fff;
@popover-fallback-border-color: #fff;
/* --------------------------------------------------------
Breacrumb
-----------------------------------------------------------*/
@breadcrumb-bg: transparent;
@breadcrumb-padding-horizontal: 20px;
@breadcrumb-active-color: #7c7c7c;
/* --------------------------------------------------------
Jumbotron
-----------------------------------------------------------*/
@jumbotron-bg: #F7F7F7;
/* --------------------------------------------------------
List Group
-----------------------------------------------------------*/
@list-group-border: #f4f4f4;
@list-group-active-color: #000;
@list-group-active-bg: #f5f5f5;
@list-group-active-border: @list-group-border;
@list-group-disabled-color: #B5B4B4;
@list-group-disabled-bg: #fff;
@list-group-disabled-text-color: #B5B4B4;
/* --------------------------------------------------------
Badges
-----------------------------------------------------------*/
@badge-color: #fff;
@badge-bg: @brand-primary;
@badge-border-radius: 2px;
@badge-font-weight: 400;
@badge-active-color: #fff;
@badge-active-bg: @brand-primary;
/* --------------------------------------------------------
Misc
-----------------------------------------------------------*/
@code-bg: transparent;
@tile-shadow: 0 1px 1px rgba(0,0,0,0.07);
/* --------------------------------------------------------
Paths
-----------------------------------------------------------*/
@imgpath: ~'../img';
@fontpath: ~'../fonts';
/* --------------------------------------------------------
Container
-----------------------------------------------------------*/
@container-tablet: 100%;
@container-desktop: 100%;
@container-large-desktop: 100%;
/* --------------------------------------------------------
Template Variables
-----------------------------------------------------------*/
@header-height: 60px;
@footer-height: 95px;
@sidebar-left-width: 240px;
@sidebar-left-mid-width: 64px;
@logo-width: @sidebar-left-width;
@logo-height: @header-height;
@boxed-width: 1170px;
@body-bg: #edecec;
/* --------------------------------------------------------
Branding
-----------------------------------------------------------*/
@brand-bg: #191C22;
@sidebar: @brand-bg;
@sidebar-active-bg: #121419;
@color-dark: #9BA1B1;
/* --------------------------------------------------------
Font
-----------------------------------------------------------*/
@font-icon: 'Material-Design-Iconic-Font';
@font-family-sans-serif: 'Roboto', sans-serif;
@font-size-base: 13px;
/* --------------------------------------------------------
Typograpgy
-----------------------------------------------------------*/
@text-color: #767676;
@link: #02a4c4;
@link-hover-decoration: none;
@headings-color: #333;
/* --------------------------------------------------------
Form
-----------------------------------------------------------*/
@input-color-placeholder: #b4b4b4;
@input-border: #e8e8e8;
@input-border-radius: 0;
@input-border-radius-large: 0px;
@input-height-large: 40px;
@input-height-base: 35px;
@input-height-small: 30px;
@input-border-focus: #79c2ff;
@input-group-addon-bg: @light-gray;
/* --------------------------------------------------------
Colors
-----------------------------------------------------------*/
@white: #ffffff;
@black: #000000;
@blue: #2196F3;
@red: #F44336;
@purple: #9C27B0;
@deeppurple: #673AB7;
@lightblue: #03A9F4;
@cyan: #00BCD4;
@teal: #009688;
@green: #4CAF50;
@lightgreen: #8BC34A;
@lime: #CDDC39;
@yellow: #FFEB3B;
@amber: #FFC107;
@orange: #FF9800;
@deeporange: #FF5722;
@gray: #9E9E9E;
@bluegray: #607D8B;
@indigo: #3F51B5;
@pink: #E91E63;
@brown: #795548;
@light-gray: #FCFCFC;
@gray-light: #828282;
@ace: #f8f8f8;
/** Form States **/
@state-success-text: @green;
@state-info-text: @blue;
@state-danger-text: lighten(@red, 5%);
@state-warning-text: @orange;
/* --------------------------------------------------------
Alert
-----------------------------------------------------------*/
@alert-success-border: transparent;
@alert-info-border: transparent;
@alert-warning-border: transparent;
@alert-danger-border: transparent;
@alert-inverse-border: transparent;
@alert-success-bg: fade(@green, 70%);
@alert-info-bg: fade(@blue, 70%);
@alert-warning-bg: fade(@amber, 70%);
@alert-danger-bg: fade(@red, 70%);
@alert-inverse-bg: #333;
@alert-success-text: #fff;
@alert-info-text: #fff;
@alert-warning-text: #fff;
@alert-danger-text: #fff;
@alert-inverse-text: #fff;
/* --------------------------------------------------------
Bootstrap Brands
-----------------------------------------------------------*/
@brand-default: #eee;
@brand-primary: @blue;
@brand-info: @cyan;
@brand-success: @green;
@brand-warning: @orange;
@brand-danger: @red;
/* --------------------------------------------------------
Border Radius
-----------------------------------------------------------*/
@border-radius-base: 2px;
@border-radius-large: 2px;
@border-radius-small: 2px;
/* --------------------------------------------------------
Dropdown
-----------------------------------------------------------*/
@dropdown-fallback-border: transparent;
@dropdown-border: transparent;
@dropdown-divider-bg: '';
@dropdown-link-hover-bg: rgba(0,0,0,0.075);
@dropdown-link-color: #333;
@dropdown-link-hover-color: #333;
@dropdown-link-disabled-color: #e4e4e4;
@dropdown-divider-bg: rgba(0,0,0,0.08);
@dropdown-link-active-color: #333;
@dropdown-link-active-bg: rgba(0, 0, 0, 0.075);
@zindex-dropdown: 9;
@dropdown-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
/* --------------------------------------------------------
Page Header
-----------------------------------------------------------*/
@page-header-border-color: transparent;
/* --------------------------------------------------------
Buttons
-----------------------------------------------------------*/
@btn-default-border: @input-border;
@btn-font-weight: 400;
/* --------------------------------------------------------
Tables
-----------------------------------------------------------*/
@table-bg: #fff;
@table-border-color: #f0f0f0;
@table-cell-padding: 10px;
@table-condensed-cell-padding: 7px;
@table-bg-accent: @light-gray;
@table-bg-active: #FFFCBE;
@table-bg-hover: lighten(@light-gray, 2%);
/* --------------------------------------------------------
Pagination
-----------------------------------------------------------*/
@pagination-bg: #E2E2E2;
@pagination-border: #fff;
@pagination-color: #7E7E7E;
@pagination-active-bg: @lightblue;
@pagination-active-border: @pagination-border;
@pagination-disabled-bg: #E2E2E2;
@pagination-disabled-border: @pagination-border;
@pagination-hover-color: #333;
@pagination-hover-bg: #d7d7d7;
@pagination-hover-border: @pagination-border;
@pager-border-radius: 5px;
/* --------------------------------------------------------
Thumbnail
-----------------------------------------------------------*/
@thumbnail-bg: #fff;
@thumbnail-border: #eee;
/* --------------------------------------------------------
Carousel
-----------------------------------------------------------*/
@carousel-caption-color: #fff;
/* --------------------------------------------------------
Modal
-----------------------------------------------------------*/
@modal-content-fallback-border-color: transparent;
@modal-content-border-color: transparent;
@modal-backdrop-bg: #000;
@modal-header-border-color: transparent;
@modal-title-line-height: transparent;
@modal-footer-border-color: transparent;
@zindex-modal-background: 10;
/* --------------------------------------------------------
Tooltips
-----------------------------------------------------------*/
@tooltip-bg: #333;
@tooltip-opacity: 1;
/* --------------------------------------------------------
Popobver
-----------------------------------------------------------*/
@zindex-popover: 9;
@popover-title-bg: #fff;
@popover-border-color: #fff;
@popover-fallback-border-color: #fff;
/* --------------------------------------------------------
Breacrumb
-----------------------------------------------------------*/
@breadcrumb-bg: transparent;
@breadcrumb-padding-horizontal: 20px;
@breadcrumb-active-color: #7c7c7c;
/* --------------------------------------------------------
Jumbotron
-----------------------------------------------------------*/
@jumbotron-bg: #F7F7F7;
/* --------------------------------------------------------
List Group
-----------------------------------------------------------*/
@list-group-border: #f4f4f4;
@list-group-active-color: #000;
@list-group-active-bg: #f5f5f5;
@list-group-active-border: @list-group-border;
@list-group-disabled-color: #B5B4B4;
@list-group-disabled-bg: #fff;
@list-group-disabled-text-color: #B5B4B4;
/* --------------------------------------------------------
Badges
-----------------------------------------------------------*/
@badge-color: #fff;
@badge-bg: @brand-primary;
@badge-border-radius: 2px;
@badge-font-weight: 400;
@badge-active-color: #fff;
@badge-active-bg: @brand-primary;
/* --------------------------------------------------------
Misc
-----------------------------------------------------------*/
@code-bg: transparent;
@tile-shadow: 0 1px 1px rgba(0,0,0,0.07);

View File

@ -0,0 +1,10 @@
cohort-renderer {
display: block;
text-align: center;
}
.cornelius-container {
display: inline-block;
padding: 0;
margin: 0 10px;
}

View File

@ -7,6 +7,7 @@ counter-renderer {
counter-renderer counter {
margin: 0;
padding: 0;
display: block;
font-size: 80px;
overflow: hidden;

View File

@ -12,3 +12,8 @@
stroke: #000;
stroke-opacity: .2;
}
.sankey-visualization-container {
height: 500px;
overflow: hidden;
}

View 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;
}
}

View File

@ -61,6 +61,8 @@
@import 'inc/visualizations/pivot-table';
@import 'inc/visualizations/map';
@import 'inc/visualizations/chart';
@import 'inc/visualizations/sunburst';
@import 'inc/visualizations/cohort';
@import 'inc/visualizations/misc';
/** VENDOR OVERRIDES **/
@ -71,4 +73,4 @@
@import 'inc/vendor-overrides/ui-select';
/** REDASH STYLING **/
@import 'redash-newstyle';
@import 'redash-newstyle';

View File

@ -1,5 +1,5 @@
<nav class="navbar navbar-default app-header" role="navigation">
<div class="container"">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" ng-click="isNavOpen = !isNavOpen">
<span class="sr-only">Toggle navigation</span>

View File

@ -28,9 +28,8 @@ function Sunburst(scope, element) {
this.watches = [];
// svg dimensions
const width = element[0].parentElement.clientWidth;
const height = scope.visualization.options.height;
const radius = Math.min(width, height) / 2;
const width = element.clientWidth;
const height = element.offsetHeight;
// Breadcrumb dimensions: width, height, spacing, width of tip/tail.
const b = {
@ -40,6 +39,11 @@ function Sunburst(scope, element) {
t: 10,
};
const radius = Math.min(width - b.h, height - b.h) / 2 - 5;
if (radius <= 0) {
return;
}
// margins
const margin = {
top: radius,
@ -77,14 +81,7 @@ function Sunburst(scope, element) {
*
* e.g. vis, breadcrumbs, lastCrumb, summary, sunburst, legend
*/
// create main vis selection
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`);
const vis = d3.select(element);
// create and position breadcrumbs container and svg
const breadcrumbs = vis
@ -96,39 +93,26 @@ function Sunburst(scope, element) {
.attr('fill', 'white')
.attr('font-weight', 600);
const marginLeft = (width - radius * 2) / 2;
// 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')
.classed('sunburst-container', true)
.style('z-index', '2')
// .style("margin-left", marginLeft + "px")
.style('left', `${marginLeft}px`)
.style('position', 'absolute')
.append('svg')
.attr('width', width)
.attr('height', height)
.attr('width', radius * 2)
.attr('height', radius * 2)
.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`);
// create last breadcrumb element
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.
function breadcrumbPoints(d, i) {
const points = [];
@ -208,8 +192,11 @@ function Sunburst(scope, element) {
.attr('opacity', 1);
// update summary
summary.html(`Stage: ${d.depth}<br />` +
`<span class='percentage' style='font-size: 2em;'>${percentageString}</span><br />${d.value} of ${totalSize}<br />`);
summary.html(`
<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
summary.style('visibility', '');
@ -394,7 +381,7 @@ Sunburst.prototype.remove = function remove() {
this.watches.forEach((unregister) => {
unregister();
});
angular.element(this.element[0]).empty('.vis-container');
angular.element(this.element).empty('.vis-container');
};
export default Sunburst;

View File

@ -1,12 +1,9 @@
.dashboard-wrapper {
.tile {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: 0;
padding: 0;
display: flex;
position: static;
height: auto;
margin-bottom: 15px;
}
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 {
background: #aaa;
}
@ -72,31 +39,46 @@
margin-left: 0 !important;
margin-right: 0 !important;
}
.tile {
display: block;
position: static;
height: auto;
margin-bottom: 15px;
}
}
&.gridster-mobile, .gridster-auto-height-enabled {
counter {
position: static;
&:not(.gridster-mobile) {
.tile {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
width: auto;
height: auto;
overflow: hidden;
margin: 0;
padding: 0;
}
.plotly-chart-container {
position: static;
height: 400px;
overflow: hidden;
}
.gridster-item:not(.gridster-auto-height-enabled) {
.sunburst-visualization-container,
.sankey-visualization-container,
.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 {
position: static;
height: 500px;
counter {
position: absolute;
left: 10px;
top: 15px;
right: 10px;
bottom: 15px;
overflow: hidden;
padding: 0;
}
}
}

View File

@ -1,4 +1,17 @@
<<<<<<< HEAD
<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>
@ -16,5 +29,11 @@
</div>
</div>
<<<<<<< HEAD
<footer>
</footer>
=======
<style>
body { padding-bottom: 15px; }
</style>
>>>>>>> master

View File

@ -123,13 +123,6 @@
</ui-select>
</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 class="form-group" ng-if="options.globalSeriesType == 'custom'">

View File

@ -65,10 +65,6 @@
</label>
</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">
<label class="control-label">Map Tiles</label>
<select ng-options="tile.url as tile.name for tile in mapTiles" ng-model="visualization.options.mapTileUrl"

View File

@ -1,6 +1,5 @@
import angular from 'angular';
import _ from 'underscore';
import $ from 'jquery';
import d3 from 'd3';
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 = {
top: 10, right: 10, bottom: 10, left: 10,
};
const width = $(element).parent().width() - margin.left - margin.right;
const height = sankeyHeight - margin.top - margin.bottom;
const width = element.offsetWidth - margin.left - margin.right;
const height = element.offsetHeight - margin.top - margin.bottom;
if ((width <= 0) || (height <= 0)) {
return;
}
const format = d => d3.format(',.0f')(d);
const color = d3.scale.category20();
@ -216,17 +219,20 @@ function createSankey(element, sankeyHeight, data) {
function sankeyRenderer() {
return {
restrict: 'E',
template: '<div class="sankey-visualization-container" resize-event="handleResize()"></div>',
link(scope, element) {
const container = element[0].querySelector('.sankey-visualization-container');
function refreshData() {
const queryData = scope.queryResult.getData();
if (queryData) {
// do the render logic.
angular.element(element[0]).empty();
createSankey(element[0], scope.visualization.options.height, queryData);
angular.element(container).empty();
createSankey(container, queryData);
}
}
angular.element(window).on('resize', refreshData);
scope.handleResize = _.debounce(refreshData, 50);
scope.$watch('queryResult && queryResult.getData()', refreshData);
scope.$watch('visualization.options.height', (oldValue, newValue) => {
if (oldValue !== newValue) {
@ -250,11 +256,11 @@ export default function init(ngModule) {
ngModule.config((VisualizationProvider) => {
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 defaultOptions = {
height: 300,
defaultRows: 7,
};
VisualizationProvider.registerVisualization({

View File

@ -1,12 +1,5 @@
<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>
<hr>
This visualization expects the query result to have rows in the following format:
<ul>

View File

@ -1,19 +1,22 @@
import jQuery from 'jquery';
import { debounce } from 'underscore';
import Sunburst from '@/lib/visualizations/sunburst';
import editorTemplate from './sunburst-sequence-editor.html';
function sunburstSequenceRenderer() {
return {
restrict: 'E',
template: '<div class="sunburst-visualization-container" resize-event="handleResize()"></div>',
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() {
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) => {
if (oldValue !== newValue) {
resize();
@ -40,7 +43,7 @@ export default function init(ngModule) {
const editTemplate = '<sunburst-sequence-editor></sunburst-sequence-editor>';
const defaultOptions = {
height: 300,
defaultRows: 7,
};
VisualizationProvider.registerVisualization({

View File

@ -1,12 +1,5 @@
<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>
<hr>
This visualization expects the query result to have rows in one of the following formats:
<strong>Option 1:</strong>

View File

@ -238,5 +238,15 @@ class Redshift(PostgreSQL):
return schema.values()
class CockroachDB(PostgreSQL):
def __init__(self, configuration):
super(CockroachDB, self).__init__(configuration)
@classmethod
def type(cls):
return "cockroach"
register(PostgreSQL)
register(Redshift)
register(CockroachDB)

View File

@ -43,7 +43,7 @@ def _guess_type(value):
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]

View File

@ -19,6 +19,10 @@ class TestExtractQueryIds(TestCase):
query = "SELECT * FROM query_123 JOIN query_4566"
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):
def test_creates_table_with_colons_in_column_name(self):