Merge branch 'master' into gh-pages

This commit is contained in:
Matt Fullerton 2015-02-17 20:25:51 +01:00
commit c9ff4d219d
39 changed files with 10156 additions and 8389 deletions

1
.gitignore vendored
View File

@ -3,3 +3,4 @@ sandbox/*
.*.swp
.*.swo
_site/*
node_modules/*

View File

@ -33,7 +33,11 @@ Note that the demos and documentation utilize the [jekyll templating
system][jekyll] and to use them *locally* you will need to build them using
jekyll. Once installed, all you need to do from the command line is run jekyll:
jekyll
jekyll serve
or if you're actively developing and want auto-reloading:
jekyll serve --watch
[jekyll]: https://github.com/mojombo/jekyll

View File

@ -1,5 +1,4 @@
pygments: true
auto: true
highlighter: pygments
markdown: kramdown
title: Recline Data Explorer and Library

View File

@ -14,7 +14,8 @@ dataset.fetch();
// show the data for illustrations sake
var grid = new recline.View.SlickGrid({
model: dataset
model: dataset,
el: $('#my-online-csv')
});
$('#my-online-csv').append(grid.el);
grid.visible = true;

View File

@ -1,6 +1,6 @@
<link rel="stylesheet" href="{{page.root}}vendor/leaflet/0.4.4/leaflet.css">
<link rel="stylesheet" href="{{page.root}}vendor/leaflet/0.7.3/leaflet.css">
<!--[if lte IE 8]>
<link rel="stylesheet" href="{{page.root}}vendor/leaflet/0.4.4/leaflet.ie.css" />
<link rel="stylesheet" href="{{page.root}}vendor/leaflet/0.7.3/leaflet.ie.css" />
<![endif]-->
<link rel="stylesheet" href="{{page.root}}vendor/leaflet.markercluster/MarkerCluster.css">
<link rel="stylesheet" href="{{page.root}}vendor/leaflet.markercluster/MarkerCluster.Default.css">
@ -31,7 +31,7 @@
<![endif]-->
<script type="text/javascript" src="{{page.root}}vendor/flot/jquery.flot.js"></script>
<script type="text/javascript" src="{{page.root}}vendor/flot/jquery.flot.time.js"></script>
<script type="text/javascript" src="{{page.root}}vendor/leaflet/0.4.4/leaflet.js"></script>
<script type="text/javascript" src="{{page.root}}vendor/leaflet/0.7.3/leaflet.js"></script>
<script type="text/javascript" src="{{page.root}}vendor/leaflet.markercluster/leaflet.markercluster.js"></script>
<script type="text/javascript" src="{{page.root}}vendor/slickgrid/2.0.1/jquery-ui-1.8.16.custom.min.js"></script>
<script src="{{page.root}}vendor/slickgrid/2.0.1/jquery.event.drag-2.2.js"></script>

View File

@ -0,0 +1,7 @@
* <a href="{{page.root}}/docs/src/view.grid.html">Grid (simple)</a>
* <a href="{{page.root}}/docs/src/view.slickgrid.html">Grid (SlickGrid)</a>
* <a href="{{page.root}}/docs/src/view.map.html">Map</a>
* <a href="https://github.com/NuCivic/recline.view.choroplethmap.js">Choropleth Map</a>
* <a href="{{page.root}}/docs/src/view.graph.html">Graph</a>
* <a href="{{page.root}}/docs/src/view.timeline.html">Timeline</a>
* <a href="{{page.root}}/docs/src/view.multiview.html">Multiview (combines views)</a>

View File

@ -66,11 +66,20 @@ a:hover {
font-weight:400;
letter-spacing:-1px;
line-height: 32px;
text-shadow: none !important;
color: #ffffff;
}
.navbar .nav > li > a {
padding: 15px 10px;
font-size: 13px;
text-shadow: none !important;
color: #999999;
}
.navbar .nav > li > a:focus,
.navbar .nav > li > a:hover {
color: #ffffff;
}
.navbar .divider-vertical {
@ -212,3 +221,6 @@ section {
margin-bottom: 20px;
}
#my-online-csv {
height: 100px;
}

View File

@ -77,7 +77,7 @@ var createMultiView = function(dataset, state) {
enabledAddRow: true,
// Enable support for row delete
enabledDelRow: true,
// Enable support for row Reoder
// Enable support for row ReOrder
enableReOrderRow:true,
autoEdit: false,
enableCellNavigation: true

283
dist/recline.js vendored
View File

@ -3066,37 +3066,7 @@ this.recline.View = this.recline.View || {};
(function($, my) {
"use strict";
// Add new grid Control to display a new row add menu bouton
// It display a simple side-bar menu ,for user to add new
// row to grid
my.GridControl= Backbone.View.extend({
className: "recline-row-add",
// Template for row edit menu , change it if you don't love
template: '<h1><a href="#" class="recline-row-add btn">Add row</a></h1>',
initialize: function(options){
var self = this;
_.bindAll(this, 'render');
this.state = new recline.Model.ObjectState();
this.render();
},
render: function() {
var self = this;
this.$el.html(this.template)
},
events : {
"click .recline-row-add" : "addNewRow"
},
addNewRow : function(e){
e.preventDefault()
this.state.trigger("change")
}
}
);
// ## SlickGrid Dataset View
//
// Provides a tabular view on a Dataset, based on SlickGrid.
@ -3117,7 +3087,11 @@ this.recline.View = this.recline.View || {};
// state: {
// gridOptions: {
// editable: true,
// enableAddRows: true
// enableAddRow: true
// // Enable support for row delete
// enabledDelRow: true,
// // Enable support for row Reorder
// enableReOrderRow:true,
// ...
// },
// columnsEditor: [
@ -3131,10 +3105,10 @@ my.SlickGrid = Backbone.View.extend({
initialize: function(modelEtc) {
var self = this;
this.$el.addClass('recline-slickgrid');
// Template for row delete menu , change it if you don't love
this.templates = {
"deleterow" : '<a href="#" class="recline-row-delete btn" title="Delete row">X</a>'
"deleterow" : '<a href="#" class="recline-row-delete btn" title="Delete row">X</a>'
};
_.bindAll(this, 'render', 'onRecordChanged');
@ -3156,15 +3130,16 @@ my.SlickGrid = Backbone.View.extend({
//add menu for new row , check if enableAddRow is set to true or not set
if(this.state.get("gridOptions")
&& this.state.get("gridOptions").enabledAddRow != undefined
&& this.state.get("gridOptions").enabledAddRow != undefined
&& this.state.get("gridOptions").enabledAddRow == true ){
this.editor = new my.GridControl()
this.elSidebar = this.editor.$el
this.listenTo(this.editor.state, 'change', function(){
this.model.records.add(new recline.Model.Record())
this.listenTo(this.editor.state, 'change', function(){
this.model.records.add(new recline.Model.Record())
});
}
},
onRecordChanged: function(record) {
// Ignore if the grid is not yet drawn
if (!this.grid) {
@ -3176,7 +3151,8 @@ my.SlickGrid = Backbone.View.extend({
this.grid.getData().updateItem(record, row_index);
this.grid.render();
},
render: function() {
render: function() {
var self = this;
var options = _.extend({
enableCellNavigation: true,
@ -3188,43 +3164,40 @@ my.SlickGrid = Backbone.View.extend({
// We need all columns, even the hidden ones, to show on the column picker
var columns = [];
// custom formatter as default one escapes html
// plus this way we distinguish between rendering/formatting and computed value (so e.g. sort still works ...)
// row = row index, cell = cell index, value = value, columnDef = column definition, dataContext = full row values
var formatter = function(row, cell, value, columnDef, dataContext) {
if(columnDef.id == "del"){
return self.templates.deleterow
}
var field = self.model.fields.get(columnDef.id);
}
var field = self.model.fields.get(columnDef.id);
if (field.renderer) {
return field.renderer(value, field, dataContext);
}else {
} else {
return value
}
};
// we need to be sure that user is entering a valid input , for exemple if
// field is date type and field.format ='YY-MM-DD', we should be sure that
// user enter a correct value
var validator = function(field){
return function(value){
if(field.type == "date" && isNaN(Date.parse(value))){
return {
valid: false,
msg: "A date is required, check field field-date-format"};
}else {
return {valid: true, msg :null }
}
}
var validator = function(field) {
return function(value){
if (field.type == "date" && isNaN(Date.parse(value))){
return {
valid: false,
msg: "A date is required, check field field-date-format"
};
} else {
return {valid: true, msg :null }
}
}
};
//Add row delete support, check if enableReOrderRow is set to true , by
//default it is set to false
// state: {
// gridOptions: {
// enableReOrderRow: true,
// },
if(this.state.get("gridOptions")
&& this.state.get("gridOptions").enableReOrderRow != undefined
&& this.state.get("gridOptions").enableReOrderRow == true ){
// Add column for row reorder support
if (this.state.get("gridOptions") && this.state.get("gridOptions").enableReOrderRow == true) {
columns.push({
id: "#",
name: "",
@ -3235,15 +3208,8 @@ my.SlickGrid = Backbone.View.extend({
cssClass: "recline-cell-reorder"
})
}
//Add row delete support, check if enabledDelRow is set to true , by
//default it is set to false
// state: {
// gridOptions: {
// enabledDelRow: true,
// },
if(this.state.get("gridOptions")
&& this.state.get("gridOptions").enabledDelRow != undefined
&& this.state.get("gridOptions").enabledDelRow == true ){
// Add column for row delete support
if (this.state.get("gridOptions") && this.state.get("gridOptions").enabledDelRow == true) {
columns.push({
id: 'del',
name: '',
@ -3254,6 +3220,7 @@ my.SlickGrid = Backbone.View.extend({
validator:validator
})
}
_.each(this.model.fields.toJSON(),function(field){
var column = {
id: field.id,
@ -3315,16 +3282,17 @@ my.SlickGrid = Backbone.View.extend({
}
}
columns = columns.concat(tempHiddenColumns);
// Transform a model object into a row
function toRow(m) {
var row = {};
self.model.fields.each(function(field){
var render = "";
self.model.fields.each(function(field) {
var render = "";
//when adding row from slickgrid the field value is undefined
if(!_.isUndefined(m.getFieldValueUnrendered(field))){
render =m.getFieldValueUnrendered(field)
}
row[field.id] = render
if(!_.isUndefined(m.getFieldValueUnrendered(field))){
render =m.getFieldValueUnrendered(field)
}
row[field.id] = render
});
return row;
}
@ -3347,7 +3315,6 @@ my.SlickGrid = Backbone.View.extend({
rows[i] = toRow(m);
models[i] = m;
};
}
var data = new RowSet();
@ -3365,70 +3332,9 @@ my.SlickGrid = Backbone.View.extend({
this.grid.setSortColumn(column, sortAsc);
}
/* Row reordering support based on
https://github.com/mleibman/SlickGrid/blob/gh-pages/examples/example9-row-reordering.html
*/
self.grid.setSelectionModel(new Slick.RowSelectionModel());
var moveRowsPlugin = new Slick.RowMoveManager({
cancelEditOnDrag: true
});
moveRowsPlugin.onBeforeMoveRows.subscribe(function (e, data) {
for (var i = 0; i < data.rows.length; i++) {
// no point in moving before or after itself
if (data.rows[i] == data.insertBefore || data.rows[i] == data.insertBefore - 1) {
e.stopPropagation();
return false;
}
}
return true;
});
moveRowsPlugin.onMoveRows.subscribe(function (e, args) {
var extractedRows = [], left, right;
var rows = args.rows;
var insertBefore = args.insertBefore;
var data = self.model.records.toJSON()
left = data.slice(0, insertBefore);
right= data.slice(insertBefore, data.length);
rows.sort(function(a,b) { return a-b; });
for (var i = 0; i < rows.length; i++) {
extractedRows.push(data[rows[i]]);
}
rows.reverse();
for (var i = 0; i < rows.length; i++) {
var row = rows[i];
if (row < insertBefore) {
left.splice(row, 1);
} else {
right.splice(row - insertBefore, 1);
}
}
data = left.concat(extractedRows.concat(right));
var selectedRows = [];
for (var i = 0; i < rows.length; i++)
selectedRows.push(left.length + i);
self.model.records.reset(data)
});
//register The plugin to handle row Reorder
if(this.state.get("gridOptions")
&& this.state.get("gridOptions").enableReOrderRow != undefined
&& this.state.get("gridOptions").enableReOrderRow == true ){
self.grid.registerPlugin(moveRowsPlugin);
if (this.state.get("gridOptions") && this.state.get("gridOptions").enableReOrderRow) {
this._setupRowReordering();
}
/* end row reordering support*/
this._slickHandler.subscribe(this.grid.onSort, function(e, args){
var order = (args.sortAsc) ? 'asc':'desc';
@ -3475,7 +3381,7 @@ my.SlickGrid = Backbone.View.extend({
// that handle row Reoder.
var cell =0
if(self.state.get("gridOptions")
&& self.state.get("gridOptions").enableReOrderRow != undefined
&& self.state.get("gridOptions").enableReOrderRow != undefined
&& self.state.get("gridOptions").enableReOrderRow == true ){
cell =1
}
@ -3495,7 +3401,67 @@ my.SlickGrid = Backbone.View.extend({
self.rendered = false;
}
return this;
},
// Row reordering support based on
// https://github.com/mleibman/SlickGrid/blob/gh-pages/examples/example9-row-reordering.html
_setupRowReordering: function() {
var self = this;
self.grid.setSelectionModel(new Slick.RowSelectionModel());
var moveRowsPlugin = new Slick.RowMoveManager({
cancelEditOnDrag: true
});
moveRowsPlugin.onBeforeMoveRows.subscribe(function (e, data) {
for (var i = 0; i < data.rows.length; i++) {
// no point in moving before or after itself
if (data.rows[i] == data.insertBefore || data.rows[i] == data.insertBefore - 1) {
e.stopPropagation();
return false;
}
}
return true;
});
moveRowsPlugin.onMoveRows.subscribe(function (e, args) {
var extractedRows = [], left, right;
var rows = args.rows;
var insertBefore = args.insertBefore;
var data = self.model.records.toJSON()
left = data.slice(0, insertBefore);
right= data.slice(insertBefore, data.length);
rows.sort(function(a,b) { return a-b; });
for (var i = 0; i < rows.length; i++) {
extractedRows.push(data[rows[i]]);
}
rows.reverse();
for (var i = 0; i < rows.length; i++) {
var row = rows[i];
if (row < insertBefore) {
left.splice(row, 1);
} else {
right.splice(row - insertBefore, 1);
}
}
data = left.concat(extractedRows.concat(right));
var selectedRows = [];
for (var i = 0; i < rows.length; i++)
selectedRows.push(left.length + i);
self.model.records.reset(data)
});
//register The plugin to handle row Reorder
if(this.state.get("gridOptions") && this.state.get("gridOptions").enableReOrderRow) {
self.grid.registerPlugin(moveRowsPlugin);
}
},
remove: function () {
@ -3521,6 +3487,36 @@ my.SlickGrid = Backbone.View.extend({
}
});
// Add new grid Control to display a new row add menu bouton
// It display a simple side-bar menu ,for user to add new
// row to grid
my.GridControl= Backbone.View.extend({
className: "recline-row-add",
// Template for row edit menu , change it if you don't love
template: '<h1><a href="#" class="recline-row-add btn">Add row</a></h1>',
initialize: function(options){
var self = this;
_.bindAll(this, 'render');
this.state = new recline.Model.ObjectState();
this.render();
},
render: function() {
var self = this;
this.$el.html(this.template)
},
events : {
"click .recline-row-add" : "addNewRow"
},
addNewRow : function(e){
e.preventDefault()
this.state.trigger("change")
}
});
})(jQuery, recline.View);
/*
@ -3639,7 +3635,14 @@ my.SlickGrid = Backbone.View.extend({
}
// Slick.Controls.ColumnPicker
$.extend(true, window, { Slick:{ Controls:{ ColumnPicker:SlickColumnPicker }}});
$.extend(true, window, {
Slick: {
Controls: {
ColumnPicker: SlickColumnPicker
}
}
});
})(jQuery);
/*jshint multistr:true */

View File

@ -0,0 +1,52 @@
---
layout: container
title: Grids - Advanced use of grids in Recline - Tutorial
recline-deps: true
root: ../
---
<div class="page-header">
<h1>
Doing More with Grids
<br />
<small>This tutorial goes beyond the <a href="tutorial-views.html">basic
views tutorial</a> and shows you how to do more with grids</small>
</h1>
</div>
### How much can I do with a simple grid view
### Benefits of SlickGrid
What does Recline give you out of the box, what does SlickGrid have built in and how to use it (reference to stuff below).
### Preparing your page
See the instructions in the [basic views tutorial](tutorial-views.html).
### Creating a Dataset
Just like in the main tutorial, here's some example data We are going to work with:
{% highlight javascript %}
{% include data.js %}
var dataset = new recline.Model.Dataset({
records: data
});
{% endhighlight %}
<script type="text/javascript">
{% include data.js %}
var dataset = new recline.Model.Dataset({
records: data
});
</script>
### Accessing SlickGrid features
Show how we can customize SlickGrid grid "normally" - i.e. you can get access to underlying grid and tweak it as you want.
Suggest we demonstrate using this example: https://github.com/mleibman/SlickGrid/blob/gh-pages/examples/example-plugin-headermenu.html
Idea here is: we don't want to mimic all that slickgrid can do through recline interface - just let people do it directly themselves ...

View File

@ -0,0 +1,50 @@
---
layout: container
title: Timelines - Advanced use of timelines in Recline - Tutorial
recline-deps: true
root: ../
---
<div class="page-header">
<h1>
Doing More with Timelines
<br />
<small>This tutorial goes beyond the <a href="tutorial-views.html">basic
views tutorial</a> and shows you how to do more with timelines</small>
</h1>
</div>
### Preparing your page
See the instructions in the [basic views tutorial](tutorial-views.html).
### Creating a Dataset
Just like in the main tutorial, here's some example data We are going to work with:
{% highlight javascript %}
{% include data.js %}
var dataset = new recline.Model.Dataset({
records: data
});
{% endhighlight %}
<script type="text/javascript">
{% include data.js %}
var dataset = new recline.Model.Dataset({
records: data
});
</script>
### Underlying library and Recline extensions
### Handling dates
### Customizing the rendering

View File

@ -9,10 +9,14 @@ root: ../
<h1>
Views Tutorial
<br />
<small>This step-by-step tutorial will quickly get you started with Recline basics, including creating a dataset from local data and setting up a grid, graph and map to display it.</small>
<small>This step-by-step tutorial will quickly get you started with Recline basics, including creating a dataset from local data and setting up a grid, graph, map and timeline to display it.</small>
</h1>
</div>
### Views
Views display Recline datasets in different ways. This page covers the interesting built-in views. For a full list of views including extensions outside of the Recline.js core, see the [list of currently available views]({{page.root}}docs/views.html#dataset-views-currently-available).
### Preparing your page
Before writing any code with Recline, you need to do the following preparation steps on your page:
@ -37,7 +41,7 @@ Before writing any code with Recline, you need to do the following preparation s
<script type="text/javascript" src="vendor/slickgrid/2.0.1/slick.grid.js"></script>
<!-- note that we could include individual components rather than whole of recline e.g.
<script type="text/javascript" src="src/model.js"></script>
<script type="text/javascript" src="src/backend/memory.js"></script>
<script type="text/javascript" src="src/backend.memory.js"></script>
<script type="text/javascript" src="src/view-grid.js"></script>
-->
<script type="text/javascript" src="dist/recline.js"></script>{% endhighlight %}
@ -62,11 +66,17 @@ We can now create a recline Dataset object (and memory backend) from this raw da
var dataset = new recline.Model.Dataset({
records: data
});
{% endhighlight %}
//Depending on the view, it may be important to set the date type
dataset.fields.models[1].attributes.type = 'date';
{% endhighlight %}
### Setting up the Grid
<div class="alert alert-info">
The source code along with all dependencies for the grid part of the tutorial can be found at <a href="https://github.com/mattfullerton/recline-view-slickgrid-demo">this GitHub repository</a>. See it in action via <a href="http://mattfullerton.github.io/recline-view-slickgrid-demo/">GitHub Pages</a>.
Although it's not demonstrated here, you can also use the simpler Grid view without SlickGrid. Source code along with all dependencies for that can be found at <a href="https://github.com/mattfullerton/recline-view-grid-demo">this GitHub repository</a>. Demo on <a href="http://mattfullerton.github.io/recline-view-grid-demo/">GitHub Pages</a>.
</div>
Let's create a data grid view to display the dataset we have just created. We're going to use the SlickGrid-based grid so we need the following CSS and JS dependencies in addition to those above:
@ -81,7 +91,7 @@ Let's create a data grid view to display the dataset we have just created. We'r
<script type="text/javascript" src="vendor/slickgrid/2.0.1/plugins/slick.rowselectionmodel.js"></script>
<script type="text/javascript" src="vendor/slickgrid/2.0.1/plugins/slick.rowmovemanager.js"></script>
<!-- Recline -->
<!-- Recline (only needed when NOT including the combined JS file as shown above) -->
<script type="text/javascript" src="src/view.slickgrid.js"></script>
{% endhighlight %}
@ -123,6 +133,10 @@ grid.render();
### Creating a Graph
<div class="alert alert-info">
The source code along with all dependencies for the graph part of the tutorial can be found at <a href="https://github.com/mattfullerton/recline-view-graph-demo">this GitHub repository</a>. See it in action via <a href="http://mattfullerton.github.io/recline-view-graph-demo/">GitHub Pages</a>.
</div>
Let's create a graph view to display a line graph for this dataset.
First, add the additional dependencies for this view. These are the Flot
@ -140,6 +154,8 @@ library and the Recline Flot Graph view:
<script type="text/javascript" src="vendor/flot/jquery.flot.js"></script>
<script type="text/javascript" src="vendor/flot/jquery.flot.time.js"></script>
<!-- Recline (only needed when NOT including the combined JS file as shown above) -->
<script type="text/javascript" src="src/view.graph.js"></script>
{% endhighlight %}
@ -164,8 +180,9 @@ var $el = $('#mygraph');
var graph = new recline.View.Graph({
model: dataset,
state: {
graphType: "lines-and-points",
group: "date",
series: ["x", "z"]
series: ["y", "z"]
}
});
$el.append(graph.el);
@ -173,17 +190,18 @@ graph.render();
graph.redraw();
{% endhighlight %}
The result is the following graph:
For the axis date formatting to work, it is crucial that the date type is set for that field as shown in the code concerning the dataset above. The result is the following graph:
<div id="mygraph" style="margin-bottom: 30px;">&nbsp;</div>
<script type="text/javascript">
dataset.fields.models[1].attributes.type = 'date';
var $el = $('#mygraph');
var graph = new recline.View.Graph({
model: dataset,
state: {
graphType: "lines-and-points",
group: "x",
group: "date",
series: ["y", "z"]
}
});
@ -194,6 +212,10 @@ graph.redraw();
### Creating a Map
<div class="alert alert-info">
The source code along with all dependencies for the map part of the tutorial can be found at <a href="https://github.com/mattfullerton/recline-view-map-demo">this GitHub repository</a>. See it in action via <a href="http://mattfullerton.github.io/recline-view-map-demo/">GitHub Pages</a>.
</div>
Now, let's create a map of this dataset using the lon/lat information which is
present on these data points.
@ -202,9 +224,9 @@ library and the Recline Map view:
{% highlight html %}
<!-- css -->
<link rel="stylesheet" href="vendor/leaflet/0.4.4/leaflet.css">
<link rel="stylesheet" href="vendor/leaflet/0.7.3/leaflet.css">
<!--[if lte IE 8]>
<link rel="stylesheet" href="vendor/leaflet/0.4.4/leaflet.ie.css" />
<link rel="stylesheet" href="vendor/leaflet/0.7.3/leaflet.ie.css" />
<![endif]-->
<link rel="stylesheet" href="vendor/leaflet.markercluster/MarkerCluster.css">
<link rel="stylesheet" href="vendor/leaflet.markercluster/MarkerCluster.Default.css">
@ -214,8 +236,10 @@ library and the Recline Map view:
<link rel="stylesheet" href="css/map.css">
<!-- javascript -->
<script type="text/javascript" src="vendor/leaflet/0.4.4/leaflet.js"></script>
<script type="text/javascript" src="vendor/leaflet/0.7.3/leaflet.js"></script>
<script type="text/javascript" src="vendor/leaflet.markercluster/leaflet.markercluster.js"></script>
<!-- Recline (only needed when NOT including the combined JS file as shown above) -->
<script type="text/javascript" src="src/view-map.js"></script>
{% endhighlight %}
@ -250,6 +274,10 @@ map.render();
### Creating a Timeline
<div class="alert alert-info">
The source code along with all dependencies for the map part of the tutorial can be found at <a href="https://github.com/mattfullerton/recline-view-timeline-demo">this GitHub repository</a>. See it in action via <a href="http://mattfullerton.github.io/recline-view-timeline-demo/">GitHub Pages</a>.
</div>
Now, let's create a timeline for this dataset using the date information which is
present on these data points.
@ -258,6 +286,7 @@ First, add the additional dependencies for the timeline view. The timeline is bu
{% highlight html %}
<!-- css -->
<link rel="stylesheet" href="vendor/timeline/css/timeline.css">
<link rel="stylesheet" href="css/map.css">
<!-- javascript -->
<script type="text/javascript" src="vendor/moment/2.0.0/moment.js"></script>

View File

@ -44,14 +44,13 @@ root: ../
</div>
</div>
<h3>Views &ndash; Grids, Maps, Graphs and More!</h3>
<h3>Views &ndash; visualize data</h3>
<hr />
<div class="tutorials">
<div class="row">
<div class="span4">
<div class="well">
<h4><a href="tutorial-views.html">Views Quickstart - Grids, Graphs and Maps</a></h4>
<h4><a href="tutorial-views.html">Views Quickstart - Grids, Graphs, Maps &amp; Timelines</a></h4>
</div>
</div>
<div class="span4">

View File

@ -16,6 +16,9 @@ views they have a pointer to a model (or a collection) and have an associated
DOM-style element (usually this element will be bound into the page at some
point).
<div class="alert alert-info">Looking for quickstart tutorial rather than reference documentation? See the <a href="tutorial-views.html">Views Tutorial</a>.</div>
Views provided by core Recline are crudely divided into two types:
* Dataset Views: a View intended for displaying a recline.Model.Dataset in some
@ -25,6 +28,9 @@ Views provided by core Recline are crudely divided into two types:
which both provide a way for editing (a part of) a `recline.Model.Query`
associated to a Dataset.
## Dataset Views currently available
{% include views-list.html %}
## Dataset View
These views are just Backbone views with a few additional conventions:

View File

@ -19,9 +19,9 @@ title: Home
and allows you to connect them with your data in seconds.
</p>
<p class="links">
<a href="docs/" class="btn btn-large">Documentation &raquo;</a>
<a href="docs/tutorials.html" class="btn btn-large">Tutorials &raquo;</a>
<a href="demos/" class="btn btn-large">Demos &raquo;</a>
<a href="docs/" class="btn">Documentation &raquo;</a>
<a href="docs/tutorials.html" class="btn">Tutorials &raquo;</a>
<a href="demos/" class="btn">Demos &raquo;</a>
</p>
<h3 style="color: white; margin-top: 40px;">Get started fast</h3>

View File

@ -26,11 +26,9 @@
},
"lib" : "src",
"main" : "dist/recline.js",
"repositories": [
{
"type": "git",
"url": "http://github.com/okfn/recline.git",
"path": "src"
}
]
"repository": {
"type": "git",
"url": "http://github.com/okfn/recline.git",
"path": "src"
}
}

View File

@ -318,7 +318,7 @@ my.Map = Backbone.View.extend({
_.each(docs,function(doc){
for (var key in self.features._layers){
if (self.features._layers[key].feature.properties.cid == doc.cid){
if (self.features._layers[key].feature.geometry.properties.cid == doc.cid){
self.features.removeLayer(self.features._layers[key]);
}
}
@ -337,7 +337,7 @@ my.Map = Backbone.View.extend({
var dms = coord.split(/[^-?\.\d\w]+/);
var deg = 0; var m = 0;
var toDeg = [1, 60, 3600]; // conversion factors for Deg, min, sec
var i;
var i;
for (i = 0; i < dms.length; ++i) {
if (isNaN(parseFloat(dms[i]))) {
continue;
@ -461,8 +461,8 @@ my.Map = Backbone.View.extend({
var self = this;
this.map = new L.Map(this.$map.get(0));
var mapUrl = "//otile{s}-s.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png";
var osmAttribution = 'Map data &copy; 2011 OpenStreetMap contributors, Tiles Courtesy of <a href="http://www.mapquest.com/" target="_blank">MapQuest</a> <img src="//developer.mapquest.com/content/osm/mq_logo.png">';
var mapUrl = "http://otile{s}-s.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png";
var osmAttribution = 'Map data &copy; 2011 OpenStreetMap contributors, Tiles Courtesy of <a href="http://www.mapquest.com/" target="_blank">MapQuest</a> <img src="http://developer.mapquest.com/content/osm/mq_logo.png">';
var bg = new L.TileLayer(mapUrl, {maxZoom: 18, attribution: osmAttribution ,subdomains: '1234'});
this.map.addLayer(bg);
@ -670,4 +670,3 @@ my.MapMenu = Backbone.View.extend({
});
})(jQuery, recline.View);

View File

@ -5,37 +5,7 @@ this.recline.View = this.recline.View || {};
(function($, my) {
"use strict";
// Add new grid Control to display a new row add menu bouton
// It display a simple side-bar menu ,for user to add new
// row to grid
my.GridControl= Backbone.View.extend({
className: "recline-row-add",
// Template for row edit menu , change it if you don't love
template: '<h1><a href="#" class="recline-row-add btn">Add row</a></h1>',
initialize: function(options){
var self = this;
_.bindAll(this, 'render');
this.state = new recline.Model.ObjectState();
this.render();
},
render: function() {
var self = this;
this.$el.html(this.template)
},
events : {
"click .recline-row-add" : "addNewRow"
},
addNewRow : function(e){
e.preventDefault()
this.state.trigger("change")
}
}
);
// ## SlickGrid Dataset View
//
// Provides a tabular view on a Dataset, based on SlickGrid.
@ -56,7 +26,11 @@ this.recline.View = this.recline.View || {};
// state: {
// gridOptions: {
// editable: true,
// enableAddRows: true
// enableAddRow: true
// // Enable support for row delete
// enabledDelRow: true,
// // Enable support for row Reorder
// enableReOrderRow:true,
// ...
// },
// columnsEditor: [
@ -70,10 +44,10 @@ my.SlickGrid = Backbone.View.extend({
initialize: function(modelEtc) {
var self = this;
this.$el.addClass('recline-slickgrid');
// Template for row delete menu , change it if you don't love
this.templates = {
"deleterow" : '<a href="#" class="recline-row-delete btn" title="Delete row">X</a>'
"deleterow" : '<a href="#" class="recline-row-delete btn" title="Delete row">X</a>'
};
_.bindAll(this, 'render', 'onRecordChanged');
@ -95,15 +69,16 @@ my.SlickGrid = Backbone.View.extend({
//add menu for new row , check if enableAddRow is set to true or not set
if(this.state.get("gridOptions")
&& this.state.get("gridOptions").enabledAddRow != undefined
&& this.state.get("gridOptions").enabledAddRow != undefined
&& this.state.get("gridOptions").enabledAddRow == true ){
this.editor = new my.GridControl()
this.elSidebar = this.editor.$el
this.listenTo(this.editor.state, 'change', function(){
this.model.records.add(new recline.Model.Record())
this.listenTo(this.editor.state, 'change', function(){
this.model.records.add(new recline.Model.Record())
});
}
},
onRecordChanged: function(record) {
// Ignore if the grid is not yet drawn
if (!this.grid) {
@ -115,7 +90,8 @@ my.SlickGrid = Backbone.View.extend({
this.grid.getData().updateItem(record, row_index);
this.grid.render();
},
render: function() {
render: function() {
var self = this;
var options = _.extend({
enableCellNavigation: true,
@ -127,43 +103,40 @@ my.SlickGrid = Backbone.View.extend({
// We need all columns, even the hidden ones, to show on the column picker
var columns = [];
// custom formatter as default one escapes html
// plus this way we distinguish between rendering/formatting and computed value (so e.g. sort still works ...)
// row = row index, cell = cell index, value = value, columnDef = column definition, dataContext = full row values
var formatter = function(row, cell, value, columnDef, dataContext) {
if(columnDef.id == "del"){
return self.templates.deleterow
}
var field = self.model.fields.get(columnDef.id);
}
var field = self.model.fields.get(columnDef.id);
if (field.renderer) {
return field.renderer(value, field, dataContext);
}else {
} else {
return value
}
};
// we need to be sure that user is entering a valid input , for exemple if
// field is date type and field.format ='YY-MM-DD', we should be sure that
// user enter a correct value
var validator = function(field){
return function(value){
if(field.type == "date" && isNaN(Date.parse(value))){
return {
valid: false,
msg: "A date is required, check field field-date-format"};
}else {
return {valid: true, msg :null }
}
}
var validator = function(field) {
return function(value){
if (field.type == "date" && isNaN(Date.parse(value))){
return {
valid: false,
msg: "A date is required, check field field-date-format"
};
} else {
return {valid: true, msg :null }
}
}
};
//Add row delete support, check if enableReOrderRow is set to true , by
//default it is set to false
// state: {
// gridOptions: {
// enableReOrderRow: true,
// },
if(this.state.get("gridOptions")
&& this.state.get("gridOptions").enableReOrderRow != undefined
&& this.state.get("gridOptions").enableReOrderRow == true ){
// Add column for row reorder support
if (this.state.get("gridOptions") && this.state.get("gridOptions").enableReOrderRow == true) {
columns.push({
id: "#",
name: "",
@ -174,15 +147,8 @@ my.SlickGrid = Backbone.View.extend({
cssClass: "recline-cell-reorder"
})
}
//Add row delete support, check if enabledDelRow is set to true , by
//default it is set to false
// state: {
// gridOptions: {
// enabledDelRow: true,
// },
if(this.state.get("gridOptions")
&& this.state.get("gridOptions").enabledDelRow != undefined
&& this.state.get("gridOptions").enabledDelRow == true ){
// Add column for row delete support
if (this.state.get("gridOptions") && this.state.get("gridOptions").enabledDelRow == true) {
columns.push({
id: 'del',
name: '',
@ -193,6 +159,7 @@ my.SlickGrid = Backbone.View.extend({
validator:validator
})
}
_.each(this.model.fields.toJSON(),function(field){
var column = {
id: field.id,
@ -254,16 +221,17 @@ my.SlickGrid = Backbone.View.extend({
}
}
columns = columns.concat(tempHiddenColumns);
// Transform a model object into a row
function toRow(m) {
var row = {};
self.model.fields.each(function(field){
var render = "";
self.model.fields.each(function(field) {
var render = "";
//when adding row from slickgrid the field value is undefined
if(!_.isUndefined(m.getFieldValueUnrendered(field))){
render =m.getFieldValueUnrendered(field)
}
row[field.id] = render
if(!_.isUndefined(m.getFieldValueUnrendered(field))){
render =m.getFieldValueUnrendered(field)
}
row[field.id] = render
});
return row;
}
@ -286,7 +254,6 @@ my.SlickGrid = Backbone.View.extend({
rows[i] = toRow(m);
models[i] = m;
};
}
var data = new RowSet();
@ -304,70 +271,9 @@ my.SlickGrid = Backbone.View.extend({
this.grid.setSortColumn(column, sortAsc);
}
/* Row reordering support based on
https://github.com/mleibman/SlickGrid/blob/gh-pages/examples/example9-row-reordering.html
*/
self.grid.setSelectionModel(new Slick.RowSelectionModel());
var moveRowsPlugin = new Slick.RowMoveManager({
cancelEditOnDrag: true
});
moveRowsPlugin.onBeforeMoveRows.subscribe(function (e, data) {
for (var i = 0; i < data.rows.length; i++) {
// no point in moving before or after itself
if (data.rows[i] == data.insertBefore || data.rows[i] == data.insertBefore - 1) {
e.stopPropagation();
return false;
}
}
return true;
});
moveRowsPlugin.onMoveRows.subscribe(function (e, args) {
var extractedRows = [], left, right;
var rows = args.rows;
var insertBefore = args.insertBefore;
var data = self.model.records.toJSON()
left = data.slice(0, insertBefore);
right= data.slice(insertBefore, data.length);
rows.sort(function(a,b) { return a-b; });
for (var i = 0; i < rows.length; i++) {
extractedRows.push(data[rows[i]]);
}
rows.reverse();
for (var i = 0; i < rows.length; i++) {
var row = rows[i];
if (row < insertBefore) {
left.splice(row, 1);
} else {
right.splice(row - insertBefore, 1);
}
}
data = left.concat(extractedRows.concat(right));
var selectedRows = [];
for (var i = 0; i < rows.length; i++)
selectedRows.push(left.length + i);
self.model.records.reset(data)
});
//register The plugin to handle row Reorder
if(this.state.get("gridOptions")
&& this.state.get("gridOptions").enableReOrderRow != undefined
&& this.state.get("gridOptions").enableReOrderRow == true ){
self.grid.registerPlugin(moveRowsPlugin);
if (this.state.get("gridOptions") && this.state.get("gridOptions").enableReOrderRow) {
this._setupRowReordering();
}
/* end row reordering support*/
this._slickHandler.subscribe(this.grid.onSort, function(e, args){
var order = (args.sortAsc) ? 'asc':'desc';
@ -414,7 +320,7 @@ my.SlickGrid = Backbone.View.extend({
// that handle row Reoder.
var cell =0
if(self.state.get("gridOptions")
&& self.state.get("gridOptions").enableReOrderRow != undefined
&& self.state.get("gridOptions").enableReOrderRow != undefined
&& self.state.get("gridOptions").enableReOrderRow == true ){
cell =1
}
@ -434,7 +340,67 @@ my.SlickGrid = Backbone.View.extend({
self.rendered = false;
}
return this;
},
// Row reordering support based on
// https://github.com/mleibman/SlickGrid/blob/gh-pages/examples/example9-row-reordering.html
_setupRowReordering: function() {
var self = this;
self.grid.setSelectionModel(new Slick.RowSelectionModel());
var moveRowsPlugin = new Slick.RowMoveManager({
cancelEditOnDrag: true
});
moveRowsPlugin.onBeforeMoveRows.subscribe(function (e, data) {
for (var i = 0; i < data.rows.length; i++) {
// no point in moving before or after itself
if (data.rows[i] == data.insertBefore || data.rows[i] == data.insertBefore - 1) {
e.stopPropagation();
return false;
}
}
return true;
});
moveRowsPlugin.onMoveRows.subscribe(function (e, args) {
var extractedRows = [], left, right;
var rows = args.rows;
var insertBefore = args.insertBefore;
var data = self.model.records.toJSON()
left = data.slice(0, insertBefore);
right= data.slice(insertBefore, data.length);
rows.sort(function(a,b) { return a-b; });
for (var i = 0; i < rows.length; i++) {
extractedRows.push(data[rows[i]]);
}
rows.reverse();
for (var i = 0; i < rows.length; i++) {
var row = rows[i];
if (row < insertBefore) {
left.splice(row, 1);
} else {
right.splice(row - insertBefore, 1);
}
}
data = left.concat(extractedRows.concat(right));
var selectedRows = [];
for (var i = 0; i < rows.length; i++)
selectedRows.push(left.length + i);
self.model.records.reset(data)
});
//register The plugin to handle row Reorder
if(this.state.get("gridOptions") && this.state.get("gridOptions").enableReOrderRow) {
self.grid.registerPlugin(moveRowsPlugin);
}
},
remove: function () {
@ -460,6 +426,36 @@ my.SlickGrid = Backbone.View.extend({
}
});
// Add new grid Control to display a new row add menu bouton
// It display a simple side-bar menu ,for user to add new
// row to grid
my.GridControl= Backbone.View.extend({
className: "recline-row-add",
// Template for row edit menu , change it if you don't love
template: '<h1><a href="#" class="recline-row-add btn">Add row</a></h1>',
initialize: function(options){
var self = this;
_.bindAll(this, 'render');
this.state = new recline.Model.ObjectState();
this.render();
},
render: function() {
var self = this;
this.$el.html(this.template)
},
events : {
"click .recline-row-add" : "addNewRow"
},
addNewRow : function(e){
e.preventDefault()
this.state.trigger("change")
}
});
})(jQuery, recline.View);
/*
@ -578,6 +574,13 @@ my.SlickGrid = Backbone.View.extend({
}
// Slick.Controls.ColumnPicker
$.extend(true, window, { Slick:{ Controls:{ ColumnPicker:SlickColumnPicker }}});
$.extend(true, window, {
Slick: {
Controls: {
ColumnPicker: SlickColumnPicker
}
}
});
})(jQuery);

View File

@ -99,7 +99,8 @@ my.Timeline = Backbone.View.extend({
"startDate": start,
"endDate": end,
"headline": String(record.get('title') || ''),
"text": record.get('description') || record.summary()
"text": record.get('description') || record.summary(),
"tag": record.get('tags')
};
return tlEntry;
} else {

View File

@ -8,7 +8,7 @@
<link rel="stylesheet" href="../css/timeline.css" type="text/css" media="screen" />
<style type="text/css">.recline-timeline { height: 400px; }</style>
<link rel="stylesheet" href="../css/flot.css">
<link rel="stylesheet" href="../vendor/leaflet/0.4.4/leaflet.css">
<link rel="stylesheet" href="../vendor/leaflet/0.7.3/leaflet.css">
<link rel="stylesheet" href="../vendor/leaflet.markercluster/MarkerCluster.css">
<link rel="stylesheet" href="../vendor/leaflet.markercluster/MarkerCluster.Default.css">
<link rel="stylesheet" href="../css/map.css">
@ -21,7 +21,7 @@
<script type="text/javascript" src="../vendor/bootstrap/2.3.2/bootstrap.js"></script>
<script type="text/javascript" src="../vendor/flot/jquery.flot.js"></script>
<script type="text/javascript" src="../vendor/flot/jquery.flot.time.js"></script>
<script type="text/javascript" src="../vendor/leaflet/0.4.4/leaflet-src.js"></script>
<script type="text/javascript" src="../vendor/leaflet/0.7.3/leaflet-src.js"></script>
<script type="text/javascript" src="../vendor/leaflet.markercluster/leaflet.markercluster.js"></script>
<script type="text/javascript" src="../vendor/slickgrid/2.0.1/jquery-ui-1.8.16.custom.min.js"></script>
<script type="text/javascript" src="../vendor/slickgrid/2.0.1/jquery.event.drag-2.0.min.js"></script>
@ -52,12 +52,11 @@
<script type="text/javascript" src="../src/model.js"></script>
<script type="text/javascript" src="../src/backend.memory.js"></script>
<script type="text/javascript" src="../src/backend.dataproxy.js"></script>
<script type="text/javascript" src="../src/backend.csv.js"></script>
<script type="text/javascript" src="http://okfnlabs.org/csv.js/csv.js"></script>
<script type="text/javascript" src="model.test.js"></script>
<script type="text/javascript" src="backend.memory.test.js"></script>
<script type="text/javascript" src="backend.dataproxy.test.js"></script>
<script type="text/javascript" src="backend.csv.test.js"></script>
<!-- views and view tests -->
<script type="text/javascript" src="../src/view.grid.js"></script>

View File

@ -202,6 +202,8 @@ test('query with plain object', function () {
});
});
// TODO: this has a dependency on the external csv backend
// May want to refactor or remove (?)
test('fetch without and with explicit fields', function () {
var dataset = new recline.Model.Dataset({
backend: 'csv',

View File

@ -20,6 +20,7 @@ test('extract dates and timelineJSON', function () {
'date': [
{
'startDate': '2012,03,20',
'tag': undefined,
'endDate': null,
'headline': '1',
'text': '<div class="recline-record-summary"><div class="Date"><strong>Date</strong>: 2012-03-20</div><div class="title"><strong>title</strong>: 1</div></div>'
@ -28,6 +29,7 @@ test('extract dates and timelineJSON', function () {
'startDate': '2012,03,25',
'endDate': null,
'headline': '2',
'tag': undefined,
'text': '<div class="recline-record-summary"><div class="Date"><strong>Date</strong>: 2012-03-25</div><div class="title"><strong>title</strong>: 2</div></div>'
}
]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 963 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 959 B

File diff suppressed because it is too large Load Diff

View File

@ -1,379 +0,0 @@
/* required styles */
.leaflet-map-pane,
.leaflet-tile,
.leaflet-marker-icon,
.leaflet-marker-shadow,
.leaflet-tile-pane,
.leaflet-overlay-pane,
.leaflet-shadow-pane,
.leaflet-marker-pane,
.leaflet-popup-pane,
.leaflet-overlay-pane svg,
.leaflet-zoom-box,
.leaflet-image-layer,
.leaflet-layer { /* TODO optimize classes */
position: absolute;
}
.leaflet-container {
overflow: hidden;
outline: 0;
}
.leaflet-tile,
.leaflet-marker-icon,
.leaflet-marker-shadow {
-moz-user-select: none;
-webkit-user-select: none;
user-select: none;
}
.leaflet-marker-icon,
.leaflet-marker-shadow {
display: block;
}
.leaflet-clickable {
cursor: pointer;
}
.leaflet-dragging, .leaflet-dragging .leaflet-clickable {
cursor: move;
}
.leaflet-container img {
/* map is broken in FF if you have max-width: 100% on tiles */
max-width: none !important;
}
.leaflet-container img.leaflet-image-layer {
/* stupid Android 2 doesn't understand "max-width: none" properly */
max-width: 15000px !important;
}
.leaflet-tile-pane { z-index: 2; }
.leaflet-objects-pane { z-index: 3; }
.leaflet-overlay-pane { z-index: 4; }
.leaflet-shadow-pane { z-index: 5; }
.leaflet-marker-pane { z-index: 6; }
.leaflet-popup-pane { z-index: 7; }
.leaflet-tile {
filter: inherit;
visibility: hidden;
}
.leaflet-tile-loaded {
visibility: inherit;
}
.leaflet-zoom-box {
width: 0;
height: 0;
}
/* Leaflet controls */
.leaflet-control {
position: relative;
z-index: 7;
pointer-events: auto;
}
.leaflet-top,
.leaflet-bottom {
position: absolute;
z-index: 1000;
pointer-events: none;
}
.leaflet-top {
top: 0;
}
.leaflet-right {
right: 0;
}
.leaflet-bottom {
bottom: 0;
}
.leaflet-left {
left: 0;
}
.leaflet-control {
float: left;
clear: both;
}
.leaflet-right .leaflet-control {
float: right;
}
.leaflet-top .leaflet-control {
margin-top: 10px;
}
.leaflet-bottom .leaflet-control {
margin-bottom: 10px;
}
.leaflet-left .leaflet-control {
margin-left: 10px;
}
.leaflet-right .leaflet-control {
margin-right: 10px;
}
.leaflet-control-zoom {
-moz-border-radius: 7px;
-webkit-border-radius: 7px;
border-radius: 7px;
}
.leaflet-control-zoom {
padding: 5px;
background: rgba(0, 0, 0, 0.25);
}
.leaflet-control-zoom a {
background-color: rgba(255, 255, 255, 0.75);
}
.leaflet-control-zoom a, .leaflet-control-layers a {
background-position: 50% 50%;
background-repeat: no-repeat;
display: block;
}
.leaflet-control-zoom a {
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px;
width: 19px;
height: 19px;
}
.leaflet-control-zoom a:hover {
background-color: #fff;
}
.leaflet-touch .leaflet-control-zoom a {
width: 27px;
height: 27px;
}
.leaflet-control-zoom-in {
background-image: url(images/zoom-in.png);
margin-bottom: 5px;
}
.leaflet-control-zoom-out {
background-image: url(images/zoom-out.png);
}
.leaflet-control-layers {
box-shadow: 0 1px 7px #999;
background: #f8f8f9;
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
border-radius: 8px;
}
.leaflet-control-layers a {
background-image: url(images/layers.png);
width: 36px;
height: 36px;
}
.leaflet-touch .leaflet-control-layers a {
width: 44px;
height: 44px;
}
.leaflet-control-layers .leaflet-control-layers-list,
.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
display: none;
}
.leaflet-control-layers-expanded .leaflet-control-layers-list {
display: block;
position: relative;
}
.leaflet-control-layers-expanded {
padding: 6px 10px 6px 6px;
font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
color: #333;
background: #fff;
}
.leaflet-control-layers input {
margin-top: 2px;
position: relative;
top: 1px;
}
.leaflet-control-layers label {
display: block;
}
.leaflet-control-layers-separator {
height: 0;
border-top: 1px solid #ddd;
margin: 5px -10px 5px -6px;
}
.leaflet-container .leaflet-control-attribution {
background-color: rgba(255, 255, 255, 0.7);
box-shadow: 0 0 5px #bbb;
margin: 0;
}
.leaflet-control-attribution,
.leaflet-control-scale-line {
padding: 0 5px;
color: #333;
}
.leaflet-container .leaflet-control-attribution,
.leaflet-container .leaflet-control-scale {
font: 11px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
}
.leaflet-left .leaflet-control-scale {
margin-left: 5px;
}
.leaflet-bottom .leaflet-control-scale {
margin-bottom: 5px;
}
.leaflet-control-scale-line {
border: 2px solid #777;
border-top: none;
color: black;
line-height: 1;
font-size: 10px;
padding-bottom: 2px;
text-shadow: 1px 1px 1px #fff;
background-color: rgba(255, 255, 255, 0.5);
}
.leaflet-control-scale-line:not(:first-child) {
border-top: 2px solid #777;
padding-top: 1px;
border-bottom: none;
margin-top: -2px;
}
.leaflet-control-scale-line:not(:first-child):not(:last-child) {
border-bottom: 2px solid #777;
}
.leaflet-touch .leaflet-control-attribution, .leaflet-touch .leaflet-control-layers {
box-shadow: none;
}
.leaflet-touch .leaflet-control-layers {
border: 5px solid #bbb;
}
/* Zoom and fade animations */
.leaflet-fade-anim .leaflet-tile, .leaflet-fade-anim .leaflet-popup {
opacity: 0;
-webkit-transition: opacity 0.2s linear;
-moz-transition: opacity 0.2s linear;
-o-transition: opacity 0.2s linear;
transition: opacity 0.2s linear;
}
.leaflet-fade-anim .leaflet-tile-loaded, .leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
opacity: 1;
}
.leaflet-zoom-anim .leaflet-zoom-animated {
-webkit-transition: -webkit-transform 0.25s cubic-bezier(0.25,0.1,0.25,0.75);
-moz-transition: -moz-transform 0.25s cubic-bezier(0.25,0.1,0.25,0.75);
-o-transition: -o-transform 0.25s cubic-bezier(0.25,0.1,0.25,0.75);
transition: transform 0.25s cubic-bezier(0.25,0.1,0.25,0.75);
}
.leaflet-zoom-anim .leaflet-tile,
.leaflet-pan-anim .leaflet-tile,
.leaflet-touching .leaflet-zoom-animated {
-webkit-transition: none;
-moz-transition: none;
-o-transition: none;
transition: none;
}
.leaflet-zoom-anim .leaflet-zoom-hide {
visibility: hidden;
}
/* Popup layout */
.leaflet-popup {
position: absolute;
text-align: center;
}
.leaflet-popup-content-wrapper {
padding: 1px;
text-align: left;
}
.leaflet-popup-content {
margin: 14px 20px;
}
.leaflet-popup-tip-container {
margin: 0 auto;
width: 40px;
height: 20px;
position: relative;
overflow: hidden;
}
.leaflet-popup-tip {
width: 15px;
height: 15px;
padding: 1px;
margin: -8px auto 0;
-moz-transform: rotate(45deg);
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
}
.leaflet-container a.leaflet-popup-close-button {
position: absolute;
top: 0;
right: 0;
padding: 4px 5px 0 0;
text-align: center;
width: 18px;
height: 14px;
font: 16px/14px Tahoma, Verdana, sans-serif;
color: #c3c3c3;
text-decoration: none;
font-weight: bold;
}
.leaflet-container a.leaflet-popup-close-button:hover {
color: #999;
}
.leaflet-popup-content p {
margin: 18px 0;
}
.leaflet-popup-scrolled {
overflow: auto;
border-bottom: 1px solid #ddd;
border-top: 1px solid #ddd;
}
/* Visual appearance */
.leaflet-container {
background: #ddd;
}
.leaflet-container a {
color: #0078A8;
}
.leaflet-container a.leaflet-active {
outline: 2px solid orange;
}
.leaflet-zoom-box {
border: 2px dotted #05f;
background: white;
opacity: 0.5;
}
.leaflet-div-icon {
background: #fff;
border: 1px solid #666;
}
.leaflet-editing-icon {
border-radius: 2px;
}
.leaflet-popup-content-wrapper, .leaflet-popup-tip {
background: white;
box-shadow: 0 3px 10px #888;
-moz-box-shadow: 0 3px 10px #888;
-webkit-box-shadow: 0 3px 14px #999;
}
.leaflet-popup-content-wrapper {
-moz-border-radius: 20px;
-webkit-border-radius: 20px;
border-radius: 20px;
}
.leaflet-popup-content {
font: 12px/1.4 "Helvetica Neue", Arial, Helvetica, sans-serif;
}

View File

@ -1,44 +0,0 @@
.leaflet-vml-shape {
width: 1px;
height: 1px;
}
.lvml {
behavior: url(#default#VML);
display: inline-block;
position: absolute;
}
.leaflet-control {
display: inline;
}
.leaflet-popup-tip {
width: 21px;
_width: 27px;
margin: 0 auto;
_margin-top: -3px;
filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
}
.leaflet-popup-tip-container {
margin-top: -1px;
}
.leaflet-popup-content-wrapper, .leaflet-popup-tip {
border: 1px solid #bbb;
}
.leaflet-control-zoom {
filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#3F000000',EndColorStr='#3F000000');
}
.leaflet-control-zoom a {
background-color: #eee;
}
.leaflet-control-zoom a:hover {
background-color: #fff;
}
.leaflet-control-layers-toggle {
}
.leaflet-control-attribution, .leaflet-control-layers {
background: white;
}

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
vendor/leaflet/0.7.3/images/layers.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 797 B

9180
vendor/leaflet/0.7.3/leaflet-src.js vendored Normal file

File diff suppressed because it is too large Load Diff

478
vendor/leaflet/0.7.3/leaflet.css vendored Normal file
View File

@ -0,0 +1,478 @@
/* required styles */
.leaflet-map-pane,
.leaflet-tile,
.leaflet-marker-icon,
.leaflet-marker-shadow,
.leaflet-tile-pane,
.leaflet-tile-container,
.leaflet-overlay-pane,
.leaflet-shadow-pane,
.leaflet-marker-pane,
.leaflet-popup-pane,
.leaflet-overlay-pane svg,
.leaflet-zoom-box,
.leaflet-image-layer,
.leaflet-layer {
position: absolute;
left: 0;
top: 0;
}
.leaflet-container {
overflow: hidden;
-ms-touch-action: none;
}
.leaflet-tile,
.leaflet-marker-icon,
.leaflet-marker-shadow {
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
-webkit-user-drag: none;
}
.leaflet-marker-icon,
.leaflet-marker-shadow {
display: block;
}
/* map is broken in FF if you have max-width: 100% on tiles */
.leaflet-container img {
max-width: none !important;
}
/* stupid Android 2 doesn't understand "max-width: none" properly */
.leaflet-container img.leaflet-image-layer {
max-width: 15000px !important;
}
.leaflet-tile {
filter: inherit;
visibility: hidden;
}
.leaflet-tile-loaded {
visibility: inherit;
}
.leaflet-zoom-box {
width: 0;
height: 0;
}
/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */
.leaflet-overlay-pane svg {
-moz-user-select: none;
}
.leaflet-tile-pane { z-index: 2; }
.leaflet-objects-pane { z-index: 3; }
.leaflet-overlay-pane { z-index: 4; }
.leaflet-shadow-pane { z-index: 5; }
.leaflet-marker-pane { z-index: 6; }
.leaflet-popup-pane { z-index: 7; }
.leaflet-vml-shape {
width: 1px;
height: 1px;
}
.lvml {
behavior: url(#default#VML);
display: inline-block;
position: absolute;
}
/* control positioning */
.leaflet-control {
position: relative;
z-index: 7;
pointer-events: auto;
}
.leaflet-top,
.leaflet-bottom {
position: absolute;
z-index: 1000;
pointer-events: none;
}
.leaflet-top {
top: 0;
}
.leaflet-right {
right: 0;
}
.leaflet-bottom {
bottom: 0;
}
.leaflet-left {
left: 0;
}
.leaflet-control {
float: left;
clear: both;
}
.leaflet-right .leaflet-control {
float: right;
}
.leaflet-top .leaflet-control {
margin-top: 10px;
}
.leaflet-bottom .leaflet-control {
margin-bottom: 10px;
}
.leaflet-left .leaflet-control {
margin-left: 10px;
}
.leaflet-right .leaflet-control {
margin-right: 10px;
}
/* zoom and fade animations */
.leaflet-fade-anim .leaflet-tile,
.leaflet-fade-anim .leaflet-popup {
opacity: 0;
-webkit-transition: opacity 0.2s linear;
-moz-transition: opacity 0.2s linear;
-o-transition: opacity 0.2s linear;
transition: opacity 0.2s linear;
}
.leaflet-fade-anim .leaflet-tile-loaded,
.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
opacity: 1;
}
.leaflet-zoom-anim .leaflet-zoom-animated {
-webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
-moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
-o-transition: -o-transform 0.25s cubic-bezier(0,0,0.25,1);
transition: transform 0.25s cubic-bezier(0,0,0.25,1);
}
.leaflet-zoom-anim .leaflet-tile,
.leaflet-pan-anim .leaflet-tile,
.leaflet-touching .leaflet-zoom-animated {
-webkit-transition: none;
-moz-transition: none;
-o-transition: none;
transition: none;
}
.leaflet-zoom-anim .leaflet-zoom-hide {
visibility: hidden;
}
/* cursors */
.leaflet-clickable {
cursor: pointer;
}
.leaflet-container {
cursor: -webkit-grab;
cursor: -moz-grab;
}
.leaflet-popup-pane,
.leaflet-control {
cursor: auto;
}
.leaflet-dragging .leaflet-container,
.leaflet-dragging .leaflet-clickable {
cursor: move;
cursor: -webkit-grabbing;
cursor: -moz-grabbing;
}
/* visual tweaks */
.leaflet-container {
background: #ddd;
outline: 0;
}
.leaflet-container a {
color: #0078A8;
}
.leaflet-container a.leaflet-active {
outline: 2px solid orange;
}
.leaflet-zoom-box {
border: 2px dotted #38f;
background: rgba(255,255,255,0.5);
}
/* general typography */
.leaflet-container {
font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
}
/* general toolbar styles */
.leaflet-bar {
box-shadow: 0 1px 5px rgba(0,0,0,0.65);
border-radius: 4px;
}
.leaflet-bar a,
.leaflet-bar a:hover {
background-color: #fff;
border-bottom: 1px solid #ccc;
width: 26px;
height: 26px;
line-height: 26px;
display: block;
text-align: center;
text-decoration: none;
color: black;
}
.leaflet-bar a,
.leaflet-control-layers-toggle {
background-position: 50% 50%;
background-repeat: no-repeat;
display: block;
}
.leaflet-bar a:hover {
background-color: #f4f4f4;
}
.leaflet-bar a:first-child {
border-top-left-radius: 4px;
border-top-right-radius: 4px;
}
.leaflet-bar a:last-child {
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
border-bottom: none;
}
.leaflet-bar a.leaflet-disabled {
cursor: default;
background-color: #f4f4f4;
color: #bbb;
}
.leaflet-touch .leaflet-bar a {
width: 30px;
height: 30px;
line-height: 30px;
}
/* zoom control */
.leaflet-control-zoom-in,
.leaflet-control-zoom-out {
font: bold 18px 'Lucida Console', Monaco, monospace;
text-indent: 1px;
}
.leaflet-control-zoom-out {
font-size: 20px;
}
.leaflet-touch .leaflet-control-zoom-in {
font-size: 22px;
}
.leaflet-touch .leaflet-control-zoom-out {
font-size: 24px;
}
/* layers control */
.leaflet-control-layers {
box-shadow: 0 1px 5px rgba(0,0,0,0.4);
background: #fff;
border-radius: 5px;
}
.leaflet-control-layers-toggle {
background-image: url(images/layers.png);
width: 36px;
height: 36px;
}
.leaflet-retina .leaflet-control-layers-toggle {
background-image: url(images/layers-2x.png);
background-size: 26px 26px;
}
.leaflet-touch .leaflet-control-layers-toggle {
width: 44px;
height: 44px;
}
.leaflet-control-layers .leaflet-control-layers-list,
.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
display: none;
}
.leaflet-control-layers-expanded .leaflet-control-layers-list {
display: block;
position: relative;
}
.leaflet-control-layers-expanded {
padding: 6px 10px 6px 6px;
color: #333;
background: #fff;
}
.leaflet-control-layers-selector {
margin-top: 2px;
position: relative;
top: 1px;
}
.leaflet-control-layers label {
display: block;
}
.leaflet-control-layers-separator {
height: 0;
border-top: 1px solid #ddd;
margin: 5px -10px 5px -6px;
}
/* attribution and scale controls */
.leaflet-container .leaflet-control-attribution {
background: #fff;
background: rgba(255, 255, 255, 0.7);
margin: 0;
}
.leaflet-control-attribution,
.leaflet-control-scale-line {
padding: 0 5px;
color: #333;
}
.leaflet-control-attribution a {
text-decoration: none;
}
.leaflet-control-attribution a:hover {
text-decoration: underline;
}
.leaflet-container .leaflet-control-attribution,
.leaflet-container .leaflet-control-scale {
font-size: 11px;
}
.leaflet-left .leaflet-control-scale {
margin-left: 5px;
}
.leaflet-bottom .leaflet-control-scale {
margin-bottom: 5px;
}
.leaflet-control-scale-line {
border: 2px solid #777;
border-top: none;
line-height: 1.1;
padding: 2px 5px 1px;
font-size: 11px;
white-space: nowrap;
overflow: hidden;
-moz-box-sizing: content-box;
box-sizing: content-box;
background: #fff;
background: rgba(255, 255, 255, 0.5);
}
.leaflet-control-scale-line:not(:first-child) {
border-top: 2px solid #777;
border-bottom: none;
margin-top: -2px;
}
.leaflet-control-scale-line:not(:first-child):not(:last-child) {
border-bottom: 2px solid #777;
}
.leaflet-touch .leaflet-control-attribution,
.leaflet-touch .leaflet-control-layers,
.leaflet-touch .leaflet-bar {
box-shadow: none;
}
.leaflet-touch .leaflet-control-layers,
.leaflet-touch .leaflet-bar {
border: 2px solid rgba(0,0,0,0.2);
background-clip: padding-box;
}
/* popup */
.leaflet-popup {
position: absolute;
text-align: center;
}
.leaflet-popup-content-wrapper {
padding: 1px;
text-align: left;
border-radius: 12px;
}
.leaflet-popup-content {
margin: 13px 19px;
line-height: 1.4;
}
.leaflet-popup-content p {
margin: 18px 0;
}
.leaflet-popup-tip-container {
margin: 0 auto;
width: 40px;
height: 20px;
position: relative;
overflow: hidden;
}
.leaflet-popup-tip {
width: 17px;
height: 17px;
padding: 1px;
margin: -10px auto 0;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
}
.leaflet-popup-content-wrapper,
.leaflet-popup-tip {
background: white;
box-shadow: 0 3px 14px rgba(0,0,0,0.4);
}
.leaflet-container a.leaflet-popup-close-button {
position: absolute;
top: 0;
right: 0;
padding: 4px 4px 0 0;
text-align: center;
width: 18px;
height: 14px;
font: 16px/14px Tahoma, Verdana, sans-serif;
color: #c3c3c3;
text-decoration: none;
font-weight: bold;
background: transparent;
}
.leaflet-container a.leaflet-popup-close-button:hover {
color: #999;
}
.leaflet-popup-scrolled {
overflow: auto;
border-bottom: 1px solid #ddd;
border-top: 1px solid #ddd;
}
.leaflet-oldie .leaflet-popup-content-wrapper {
zoom: 1;
}
.leaflet-oldie .leaflet-popup-tip {
width: 24px;
margin: 0 auto;
-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
}
.leaflet-oldie .leaflet-popup-tip-container {
margin-top: -1px;
}
.leaflet-oldie .leaflet-control-zoom,
.leaflet-oldie .leaflet-control-layers,
.leaflet-oldie .leaflet-popup-content-wrapper,
.leaflet-oldie .leaflet-popup-tip {
border: 1px solid #999;
}
/* div icon */
.leaflet-div-icon {
background: #fff;
border: 1px solid #666;
}

9
vendor/leaflet/0.7.3/leaflet.js vendored Normal file

File diff suppressed because one or more lines are too long