Add markdown visualization (2182)

This commit is contained in:
lukasolson 2015-01-02 14:50:42 -07:00
parent 74a117fd14
commit 9dd44321e2
19 changed files with 182 additions and 9 deletions

View file

@ -48,7 +48,8 @@
"require-css": "~0.1.2",
"requirejs": "~2.1.10",
"requirejs-text": "~2.0.10",
"lodash-deep": "spenceralger/lodash-deep#a2768a72d7"
"lodash-deep": "spenceralger/lodash-deep#a2768a72d7",
"marked": "~0.3.2"
},
"devDependencies": {}
}

View file

@ -1,4 +1,4 @@
<div ng-if="esResp.hits.total === 0"
<div ng-if="esResp.hits.total === 0 && vis.type.name !== 'markdown'"
class="text-center visualize-error visualize-chart">
<div class="item top"></div>
<div class="item">
@ -7,7 +7,6 @@
</div>
<div class="item bottom"></div>
</div>
<div ng-hide="esResp.hits.total === 0" class="visualize-chart"></div>
<div ng-hide="esResp.hits.total === 0 && vis.type.name !== 'markdown'" class="visualize-chart"></div>
<!-- <pre>{{chartData | json}}</pre> -->
<visualize-spy></visualize-spy>
<visualize-spy ng-if="vis.type.name !== 'markdown'"></visualize-spy>

View file

@ -0,0 +1,5 @@
define(function (require) {
require('registry/vis_types').register(function (Private) {
return Private(require('plugins/markdown_vis/markdown_vis'));
});
});

View file

@ -0,0 +1,3 @@
<div ng-controller="KbnMarkdownVisController" class="markdown-vis">
<div ng-bind-html="html"></div>
</div>

View file

@ -0,0 +1,23 @@
define(function (require) {
// we need to load the css ourselves
require('css!plugins/markdown_vis/markdown_vis.css');
// we also need to load the controller and used by the template
require('plugins/markdown_vis/markdown_vis_controller');
return function (Private) {
var TemplateVisType = Private(require('plugins/vis_types/template/template_vis_type'));
// return the visType object, which kibana will use to display and configure new
// Vis object of this type.
return new TemplateVisType({
name: 'markdown',
title: 'Markdown widget',
icon: 'fa-code',
template: require('text!plugins/markdown_vis/markdown_vis.html'),
params: {
editor: require('text!plugins/markdown_vis/markdown_vis_params.html')
}
});
};
});

View file

@ -0,0 +1,11 @@
@import (reference) "../../styles/_mixins.less";
@import (reference) "lesshat.less";
.markdown-vis {
padding: 1em;
width: 100%;
}
.markdown-vis-options textarea {
font-family: monospace;
}

View file

@ -0,0 +1,12 @@
define(function (require) {
var marked = require('marked');
marked.setOptions({sanitize: true}); // Sanitize HTML tags
var module = require('modules').get('kibana/markdown_vis', ['kibana']);
module.controller('KbnMarkdownVisController', function ($scope, $sce) {
$scope.$watch('vis.params.markdown', function (html) {
if (!html) return;
$scope.html = $sce.trustAsHtml(marked(html));
});
});
});

View file

@ -0,0 +1,5 @@
<div class="markdown-vis-options form-group">
<label>Markdown</label>
<small class="pull-right"><a href="https://help.github.com/articles/markdown-basics/">Help</a></small>
<textarea ng-model="vis.params.markdown" class="form-control" rows="20"></textarea>
</div>

View file

@ -0,0 +1,4 @@
<div ng-controller="KbnMetricVisController" class="metric-vis">
<div class="metric-value" style="font-size: {{vis.params.fontSize}}pt">{{metric.value}}</div>
<div>{{metric.label}}</div>
</div>

View file

@ -0,0 +1,39 @@
define(function (require) {
// we need to load the css ourselves
require('css!plugins/metric_vis/metric_vis.css');
// we also need to load the controller and used by the template
require('plugins/metric_vis/metric_vis_controller');
return function (Private) {
var TemplateVisType = Private(require('plugins/vis_types/template/template_vis_type'));
var Schemas = Private(require('plugins/vis_types/_schemas'));
// return the visType object, which kibana will use to display and configure new
// Vis object of this type.
return new TemplateVisType({
name: 'metric',
title: 'Metric',
icon: 'fa-calculator',
template: require('text!plugins/metric_vis/metric_vis.html'),
params: {
defaults: {
fontSize: 60
},
editor: require('text!plugins/metric_vis/metric_vis_params.html')
},
schemas: new Schemas([
{
group: 'metrics',
name: 'metric',
title: 'Metric',
min: 1,
max: 1,
defaults: [
{ type: 'count', schema: 'metric' }
]
}
])
});
};
});

View file

@ -0,0 +1,13 @@
@import (reference) "../../styles/_mixins.less";
@import (reference) "lesshat.less";
.metric-vis {
text-align: center;
.flex-parent();
.justify-content(center);
.metric-value {
font-weight: bold;
.ellipsis();
}
}

View file

@ -0,0 +1,23 @@
define(function (require) {
// get the kibana/metric_vis module, and make sure that it requires the "kibana" module if it
// didn't already
var module = require('modules').get('kibana/metric_vis', ['kibana']);
module.controller('KbnMetricVisController', function ($scope) {
var metric = $scope.metric = {
label: null,
value: null
};
$scope.$watch('esResponse', function (resp) {
if (!resp) {
metric.label = metric.value = null;
} else {
var agg = $scope.vis.aggs[0];
metric.label = agg.makeLabel();
if (agg.type.name === 'count') metric.value = resp.hits.total;
else metric.value = resp.aggregations[agg.id].value;
}
});
});
});

View file

@ -0,0 +1,4 @@
<div class="form-group">
<label>Font Size</label>
<input type="range" ng-model="vis.params.fontSize" class="form-control" min="12" max="120" />
</div>

View file

@ -15,7 +15,7 @@ define(function (require) {
template: require('text!plugins/visualize/editor/editor.html'),
resolve: {
savedVis: function (savedVisualizations, courier, $route) {
if (!$route.current.params.indexPattern && !$route.current.params.savedSearchId) {
if (!$route.current.params.indexPattern && !$route.current.params.savedSearchId && $route.current.params.type !== 'markdown') {
throw new Error('You must provide either an indexPattern or a savedSearchId');
}

View file

@ -17,7 +17,7 @@ define(function (require) {
var $editor = $compile($scope.vis.type.params.editor)($scope);
$optionContainer.append($editor);
$scope.$watch('vis.type.schemas.length', function (len) {
$scope.$watch('vis.type.schemas.all.length', function (len) {
$scope.alwaysShowOptions = len === 0;
});
}

View file

@ -24,6 +24,7 @@ define(function (require) {
$scope.visTypes = Private(require('registry/vis_types'));
$scope.visTypeUrl = function (visType) {
if (visType.name === 'markdown') return '#/visualize/create?type=markdown';
return '#/visualize/step/2?type=' + encodeURIComponent(visType.name);
};
});

View file

@ -33,7 +33,8 @@ require.config({
moment: 'bower_components/moment/moment',
'ng-clip': 'bower_components/ng-clip/src/ngClip',
text: 'bower_components/requirejs-text/text',
zeroclipboard: 'bower_components/zeroclipboard/dist/ZeroClipboard'
zeroclipboard: 'bower_components/zeroclipboard/dist/ZeroClipboard',
marked: 'bower_components/marked/lib/marked'
},
shim: {
angular: {
@ -56,6 +57,9 @@ require.config({
},
leaflet: {
deps: ['css!bower_components/leaflet/dist/leaflet.css']
},
marked: {
exports: 'marked'
}
},
waitSeconds: 60

View file

@ -13,7 +13,8 @@ module.exports = {
'<%= plugins %>/visualize/styles/visualization.less',
'<%= plugins %>/visualize/styles/main.less',
'<%= plugins %>/table_vis/table_vis.less',
'<%= plugins %>/metric_vis/metric_vis.less'
'<%= plugins %>/metric_vis/metric_vis.less',
'<%= plugins %>/markdown_vis/markdown_vis.less'
],
expand: true,
ext: '.css',

View file

@ -0,0 +1,25 @@
define(function (require) {
describe('markdown vis controller', function () {
var $scope, $el;
beforeEach(module('kibana/markdown_vis'));
beforeEach(inject(function ($rootScope, $controller) {
$scope = $rootScope.$new();
$controller('KbnMarkdownVisController', {$scope: $scope});
$scope.$digest();
}));
it('should set html from markdown params', function () {
expect($scope).to.not.have.property('html');
$scope.vis = {
params: {
markdown: 'This is a test of the [markdown](http://daringfireball.net/projects/markdown) vis.'
}
};
$scope.$digest();
expect($scope).to.have.property('html');
expect($scope.html.toString().indexOf('<a href')).to.be.greaterThan(-1);
});
});
});