Merge branch 'master' into develop

This commit is contained in:
Torkel Ödegaard 2015-11-09 11:25:22 +01:00
commit b25b31e4a0
25 changed files with 509 additions and 699 deletions

View File

@ -30,7 +30,7 @@ a standalone frontend only web application. Grafana 2.0 comes with a backend.
- Click and drag to zoom
- Multiple Y-axis, logarithmic scales
- Bars, Lines, Points
- Smart Y-axis formating
- Smart Y-axis formatting
- Series toggles & color selector
- Legend values, and formatting options
- Grid thresholds, axis labels

View File

@ -225,7 +225,7 @@ level = Info
[log.console]
level =
# Set formatting to "false" to disable color formatting of console logs
formatting = true
formatting = false
# For "file" mode only
[log.file]

View File

@ -2,7 +2,7 @@
# Grafana docker image
This container currently only contains the in development alpha of Grafana 2.0 (ie non production use). The
`#develop` tag is constantly updated as we make progress torwards a beta release.
`#develop` tag is constantly updated as we make progress towards a beta release.
## Running your Grafana image
@ -17,7 +17,7 @@ Try it out, default admin user is admin/admin.
## Configuring your Grafana container
All options defined in conf/grafana.ini can be overriden using environment variables, for example:
All options defined in conf/grafana.ini can be overridden using environment variables, for example:
```

View File

@ -54,6 +54,25 @@ Example content:
You need to specify a namespace, metric, at least one stat, and at least one dimension.
## Templated queries
CloudWatch Datasource Plugin provides the following functions in `Variables values query` field in Templating Editor to query `region`, `namespaces`, `metric names` and `dimension keys/values` on the CloudWatch.
Name | Description
------- | --------
`regions()` | Returns a list of regions AWS provides their service.
`namespaces()` | Returns a list of namespaces CloudWatch support.
`metrics(namespace)` | Returns a list of metrics in the namespace.
`dimension_keys(namespace)` | Returns a list of dimension keys in the namespace.
`dimension_values(region, namespace, metric)` | Returns a list of dimension values matching the specified `region`, `namespace` and `metric`.
For details about the metrics CloudWatch provides, please refer to the [CloudWatch documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/CW_Support_For_AWS.html).
If you want to filter dimension values by other dimension key/value pair, you can specify optional parameter like this.
```sql
dimension_values(region, namespace, metric, dim_key1=dim_val1,dim_key2=dim_val2,...)
```
![](/img/v2/cloudwatch_templating.png)
## Cost

View File

@ -30,18 +30,23 @@ Open a graph in edit mode by click the title.
![](/img/v2/opentsdb_query_editor.png)
### Auto complete suggestions
You should get auto complete suggestions for tags and tag values. If you do not you need to enable `tsd.core.meta.enable_realtime_ts` in
the OpenTSDB server settings.
As soon as you start typing metric names, tag names and tag values , you should see highlighted auto complete suggestions for them.
> Note: This is required for the OpenTSDB `lookup` api to work.
> Note: This is required for the OpenTSDB `suggest` api to work.
## Templating queries
Grafana's OpenTSDB data source now supports template variable values queries. This means you can create template variables that fetch the values from OpenTSDB (for example metric names, tag names, or tag values). The query editor is also enhanced to limiting tags by metric.
When using OpenTSDB with a template variable of `query` type you can use following syntax for lookup.
metrics() // returns metric names
metrics(prefix) // returns metric names with specific prefix (can be empty)
tag_names(cpu) // return tag names (i.e. keys) for a specific cpu metric
tag_values(cpu, hostname) // return tag values for metric cpu and tag key hostname
suggest_tagk(prefix) // return tag names (i.e. keys) for all metrics with specific prefix (can be empty)
suggest_tagv(prefix) // return tag values for all metrics with specific prefix (can be empty)
For details on opentsdb metric queries checkout the official [OpenTSDB documentation](http://opentsdb.net/docs/build/html/index.html)
If you do not see template variables being populated in `Preview of values` section, you need to enable `tsd.core.meta.enable_realtime_ts` in the OpenTSDB server settings. Also, to populate metadata of the existing time series data in OpenTSDB, you need to run `tsdb uid metasync` on the OpenTSDB server.
> Note: This is required for the OpenTSDB `lookup` api to work.
For details on opentsdb metric queries checkout the official [OpenTSDB documentation](http://opentsdb.net/docs/build/html/index.html)

View File

@ -0,0 +1,422 @@
----
page_title: Dashboard JSON
page_description: Dashboard JSON Reference
page_keywords: grafana, dashboard, json, documentation
---
# Dashboard JSON
## Overview
A dashboard in Grafana is represented by a JSON object, which stores metadata of its dashboard. Dashboard metadata includes dashboard properties, metadata from rows, panels, template variables, panel queries, etc.
To view the JSON of a dashboard, follow the steps mentioned below:
1. Go to a dashboard
2. Click on `Manage dashboard` menu on the top navigation bar
3. Select `View JSON` from the dropdown menu
## JSON fields
When a user creates a new dashboard, a new dashboard JSON object is initialized with the following fields:
> Note: In the following JSON, id is shown as null which is the default value assigned to it until a dashboard is saved. Once a dashboard is saved, an integer value is assigned to the `id` field.
```
{
"id": null,
"title": "New dashboard",
"originalTitle": "New dashboard",
"tags": [],
"style": "dark",
"timezone": "browser",
"editable": true,
"hideControls": false,
"sharedCrosshair": false,
"rows": [],
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {
"time_options": [],
"refresh_intervals": []
},
"templating": {
"list": []
},
"annotations": {
"list": []
},
"schemaVersion": 7,
"version": 0,
"links": []
}
```
Each field in the dashboard JSON is explained below with its usage:
| Name | Usage |
| ---- | ----- |
| **id** | unique dashboard id, an integer |
| **title** | current title of dashboard |
| **originalTitle** | title of dashboard when saved for the first time |
| **tags** | tags associated with dashboard, an array of strings |
| **style** | theme of dashboard, i.e. `dark` or `light` |
| **timezone** | timezone of dashboard, i.e. `utc` or `browser` |
| **editable** | whether a dashboard is editable or not |
| **hideControls** | whether row controls on the left in green are hidden or not |
| **sharedCrosshair** | TODO |
| **rows** | row metadata, see [rows section](/docs/sources/reference/dashboard.md/#rows) for details |
| **time** | time range for dashboard, i.e. last 6 hours, last 7 days, etc |
| **timepicker** | timepicker metadata, see [timepicker section](/docs/sources/reference/dashboard.md/#timepicker) for details |
| **templating** | templating metadata, see [templating section](/docs/sources/reference/dashboard.md/#templating) for details |
| **annotations** | annotations metadata, see [annotations section](/docs/sources/reference/dashboard.md/#annotations) for details |
| **schemaVersion** | TODO |
| **version** | TODO |
| **links** | TODO |
### rows
`rows` field consists of an array of JSON object representing each row in a dashboard, such as shown below:
```
"rows": [
{
"collapse": false,
"editable": true,
"height": "200px",
"panels": [],
"title": "New row"
},
{
"collapse": true,
"editable": true,
"height": "300px",
"panels": [],
"title": "New row"
}
]
```
Usage of the fields is explained below:
| Name | Usage |
| ---- | ----- |
| **collapse** | whether row is collapsed or not |
| **editable** | whether a row is editable or not |
| **height** | height of the row in pixels |
| **panels** | panels metadata, see [panels section](/docs/sources/reference/dashboard.md/#panels) for details |
| **title** | title of row |
#### panels
Panels are the building blocks a dashboard. It consists of datasource queries, type of graphs, aliases, etc. Panel JSON consists of an array of JSON objects, each representing a different panel in a row. Most of the fields are common for all panels but some fields depends on the panel type. Following is an example of panel JSON representing a `graph` panel type:
```
"panels": [
{
"aliasColors": {},
"bars": false,
"datasource": null,
"editable": true,
"error": false,
"fill": 0,
"grid": {
"leftLogBase": 1,
"leftMax": null,
"leftMin": null,
"rightLogBase": 1,
"rightMax": null,
"rightMin": null,
"threshold1": null,
"threshold1Color": "rgba(216, 200, 27, 0.27)",
"threshold2": null,
"threshold2Color": "rgba(234, 112, 112, 0.22)"
},
"id": 1,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 4,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "max",
"alias": "$tag_instance_id",
"currentTagKey": "",
"currentTagValue": "",
"downsampleAggregator": "avg",
"downsampleInterval": "",
"errors": {},
"metric": "memory.percent-used",
"refId": "A",
"shouldComputeRate": false,
"tags": {
"app": "$app",
"env": "stage",
"instance_id": "*"
}
}
],
"timeFrom": null,
"timeShift": null,
"title": "Memory Utilization",
"tooltip": {
"shared": true,
"value_type": "cumulative"
},
"type": "graph",
"x-axis": true,
"y-axis": true,
"y_formats": [
"percent",
"short"
]
},
{
"aliasColors": {},
"bars": false,
"datasource": null,
"editable": true,
"error": false,
"fill": 0,
"grid": {
"leftLogBase": 1,
"leftMax": null,
"leftMin": null,
"rightLogBase": 1,
"rightMax": null,
"rightMin": null,
"threshold1": null,
"threshold1Color": "rgba(216, 200, 27, 0.27)",
"threshold2": null,
"threshold2Color": "rgba(234, 112, 112, 0.22)"
},
"id": 2,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 4,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "avg",
"alias": "$tag_instance_id",
"currentTagKey": "",
"currentTagValue": "",
"downsampleAggregator": "avg",
"downsampleInterval": "",
"errors": {},
"metric": "memory.percent-cached",
"refId": "A",
"shouldComputeRate": false,
"tags": {
"app": "$app",
"env": "prod",
"instance_id": "*"
}
}
],
"timeFrom": null,
"timeShift": null,
"title": "Memory Cached",
"tooltip": {
"shared": true,
"value_type": "cumulative"
},
"type": "graph",
"x-axis": true,
"y-axis": true,
"y_formats": [
"short",
"short"
]
},
```
Usage of each field is explained below:
| Name | Usage |
| ---- | ----- |
| TODO | TODO |
### timepicker
Description: TODO
```
"timepicker": {
"collapse": false,
"enable": true,
"notice": false,
"now": true,
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
],
"status": "Stable",
"time_options": [
"5m",
"15m",
"1h",
"3h",
"6h",
"12h",
"24h",
"2d",
"3d",
"4d",
"7d",
"30d"
],
"type": "timepicker"
}
```
Usage of the fields is explained below:
| Name | Usage |
| ---- | ----- |
| **collapse** | whether timepicker is collapsed or not |
| **enable** | whether timepicker is enabled or not |
| **notice** | TODO |
| **now** | TODO |
| **refresh_intervals** | TODO |
| **status** | TODO |
| **time_options** | TODO |
| **type** | TODO |
### templating
`templating` fields contains array of template variables with their saved values along with some other metadata, for example:
```
"templating": {
"enable": true,
"list": [
{
"allFormat": "wildcard",
"current": {
"tags": [],
"text": "prod",
"value": "prod"
},
"datasource": null,
"includeAll": true,
"name": "env",
"options": [
{
"selected": false,
"text": "All",
"value": "*"
},
{
"selected": false,
"text": "stage",
"value": "stage"
},
{
"selected": false,
"text": "test",
"value": "test"
}
],
"query": "tag_values(cpu.utilization.average,env)",
"refresh": false,
"refresh_on_load": false,
"type": "query"
},
{
"allFormat": "wildcard",
"current": {
"text": "apache",
"value": "apache"
},
"datasource": null,
"includeAll": false,
"multi": false,
"multiFormat": "glob",
"name": "app",
"options": [
{
"selected": true,
"text": "tomcat",
"value": "tomcat"
},
{
"selected": false,
"text": "cassandra",
"value": "cassandra"
}
],
"query": "tag_values(cpu.utilization.average,app)",
"refresh_on_load": false,
"regex": "",
"type": "query"
}
]
}
```
Usage of the above mentioned fields in the templating section is explained below:
| Name | Usage |
| ---- | ----- |
| **enable** | whether templating is enabled or not |
| **list** | an array of objects representing, each representing one template variable |
| **allFormat** | format to use while fetching all values from datasource, eg: `wildcard`, `glob`, `regex`, `pipe`, etc. |
| **current** | shows current selected variable text/value on the dashboard |
| **datasource** | shows datasource for the variables |
| **includeAll** | whether all value option is available or not |
| **multi** | whether multiple values can be selected or not from variable value list |
| **multiFormat** | format to use while fetching timeseries from datasource |
| **name** | name of variable |
| **options** | array of variable text/value pairs available for selection on dashboard |
| **query** | datasource query used to fetch values for a variable |
| **refresh_on_load** | TODO |
| **regex** | TODO |
| **type** | type of variable, i.e. `custom`, `query` or `interval` |
### annotations
TODO

View File

@ -27,7 +27,7 @@ that is not really the case, or, at least, that it is a lot better than you expe
To begin with we are going to install the 3 main components that define our metric stack. Later in the guide we will
install StatsD, but that is optional.
- Carbon is the graphite ingestion deamon responsible for
- Carbon is the graphite ingestion daemon responsible for
receiving metrics and storing them.
- Graphite-api is light weight version of graphite-web with only the HTTP api and is
responsible for executing metric queries.
@ -90,7 +90,7 @@ pattern = .*
retentions = 10s:1d,1m:7d,10m:1y
```
This config specifies the resolution of metrics and the retention periods. For example for all metrics begining with the word `carbon` receive metrics every minute and store for 30 days, then
This config specifies the resolution of metrics and the retention periods. For example for all metrics beginning with the word `carbon` receive metrics every minute and store for 30 days, then
roll them up into 10 minute buckets and store those for 1 year, then roll those up into 1 hour buckets and store those for 5 years. For all other metrics
the default rule will be applied with other retention periods.
@ -206,7 +206,7 @@ Reload supervisor
supervisorctl reload
A carbon-cache deamon and graphite-api should now be running. Type `supervisorctl status` to verify that they are running. You can
A carbon-cache daemon and graphite-api should now be running. Type `supervisorctl status` to verify that they are running. You can
also open `http://your_server_ip:8888/metrics/find?query?*` in your browser. You should see a json snippet.
@ -243,12 +243,12 @@ Open http://your_server_ip:3000 in your browser and login with the default user
- Select `Add Panel` > `Graph` from the row menu
- An empty graph panel should appear with title `no title (click here)`. Click on this title and then `Edit`
- This will open the graph in edit mode and take you to the metrics tab.
- There is one query already added (asigned letter A) but it is empty.
- There is one query already added (assigned letter A) but it is empty.
- Click on `select metric` to pick the first graphite metric node. A new `select metric` link will appear until you reached a leaf node.
- Try picking the metric paths for `carbon.agents.<server name>.cpuUsage`, you should now see a line appear in the graph!
## Writing metrics to Graphite
Graphite has the simples metric write protocol imaginable. Something that has surely contributed to its wide adoption by metric
Graphite has the simplest metric write protocol imaginable. Something that has surely contributed to its wide adoption by metric
frameworks and numerous integrations.
prod.server1.requests.count 10 1398969187

View File

@ -67,8 +67,8 @@ func init() {
func handleGetRegions(req *cwRequest, c *middleware.Context) {
regions := []string{
"us-west-2", "us-west-1", "eu-west-1", "eu-central-1", "ap-southeast-1",
"ap-southeast-2", "ap-northeast-1", "sa-east-1",
"us-east-1", "us-west-2", "us-west-1", "eu-west-1", "eu-central-1", "ap-southeast-1",
"ap-southeast-2", "ap-northeast-1", "sa-east-1", "cn-north-1",
}
result := []interface{}{}

View File

@ -321,7 +321,7 @@ func DeleteUser(cmd *m.DeleteUserCommand) error {
return inTransaction(func(sess *xorm.Session) error {
deletes := []string{
"DELETE FROM star WHERE user_id = ?",
"DELETE FROM user WHERE id = ?",
"DELETE FROM " + dialect.Quote("user") + " WHERE id = ?",
}
for _, sql := range deletes {

View File

@ -10,6 +10,6 @@ datasource annotationQuery changed. now single options parameter with:
2.5 changed the `range` parameter in the `datasource.query` function's options parameter. This
parameter now holds a parsed range with `moment` dates `form` and `to`. To get
millisecond epoc from a `moment` you the function `valueOf`. The raw date range as represented
millisecond epoch from a `moment` you the function `valueOf`. The raw date range as represented
internally in grafana (which may be relative expressions like `now-5h`) is included in the
new property `rangeRaw` (on the options object).

View File

@ -80,8 +80,8 @@ function (angular, _, dateMath) {
return backendSrv.datasourceRequest(options);
};
OpenTSDBDatasource.prototype._performSuggestQuery = function(query) {
return this._get('/api/suggest', {type: 'metrics', q: query, max: 1000}).then(function(result) {
OpenTSDBDatasource.prototype._performSuggestQuery = function(query, type) {
return this._get('/api/suggest', {type: type, q: query, max: 1000}).then(function(result) {
return result.data;
});
};
@ -150,10 +150,12 @@ function (angular, _, dateMath) {
var metrics_regex = /metrics\((.*)\)/;
var tag_names_regex = /tag_names\((.*)\)/;
var tag_values_regex = /tag_values\((.*),\s?(.*)\)/;
var tag_names_suggest_regex = /suggest_tagk\((.*)\)/;
var tag_values_suggest_regex = /suggest_tagv\((.*)\)/;
var metrics_query = interpolated.match(metrics_regex);
if (metrics_query) {
return this._performSuggestQuery(metrics_query[1]).then(responseTransform);
return this._performSuggestQuery(metrics_query[1], 'metrics').then(responseTransform);
}
var tag_names_query = interpolated.match(tag_names_regex);
@ -166,6 +168,16 @@ function (angular, _, dateMath) {
return this._performMetricKeyValueLookup(tag_values_query[1], tag_values_query[2]).then(responseTransform);
}
var tag_names_suggest_query = interpolated.match(tag_names_suggest_regex);
if (tag_names_suggest_query) {
return this._performSuggestQuery(tag_names_suggest_query[1], 'tagk').then(responseTransform);
}
var tag_values_suggest_query = interpolated.match(tag_values_suggest_regex);
if (tag_values_suggest_query) {
return this._performSuggestQuery(tag_values_suggest_query[1], 'tagv').then(responseTransform);
}
return $q.when([]);
};

View File

@ -162,20 +162,20 @@
<editor-checkbox text="Counter" model="target.isCounter" change="targetBlur()"></editor-checkbox>
</li>
<li class="tight-form-item" ng-hide="!target.isCounter">
<li class="tight-form-item" ng-hide="!target.isCounter || !target.shouldComputeRate">
Counter Max:
</li>
<li ng-hide="!target.isCounter">
<li ng-hide="!target.isCounter || !target.shouldComputeRate">
<input type="text" class="tight-form-input input-small" ng-disabled="!target.shouldComputeRate"
ng-model="target.counterMax" spellcheck='false'
placeholder="max value" ng-model-onblur
ng-blur="targetBlur()"></input>
</li>
<li class="tight-form-item" ng-hide="!target.isCounter">
<li class="tight-form-item" ng-hide="!target.isCounter || !target.shouldComputeRate">
Reset Value:
</li>
<li ng-hide="!target.isCounter">
<li ng-hide="!target.isCounter || !target.shouldComputeRate">
<input type="text" class="tight-form-input input-small" ng-disabled="!target.shouldComputeRate"
ng-model="target.counterResetValue" spellcheck='false'
placeholder="reset value" ng-model-onblur

View File

@ -48,13 +48,13 @@ function (angular, _, kbn) {
};
$scope.suggestTagKeys = function(query, callback) {
$scope.datasource.metricFindQuery('tag_names(' + $scope.target.metric + ')')
$scope.datasource.metricFindQuery('suggest_tagk(' + query + ')')
.then($scope.getTextValues)
.then(callback);
};
$scope.suggestTagValues = function(query, callback) {
$scope.datasource.metricFindQuery('tag_values(' + $scope.target.metric + ',' + $scope.target.currentTagKey + ')')
$scope.datasource.metricFindQuery('suggest_tagv(' + query + ')')
.then($scope.getTextValues)
.then(callback);
};

View File

@ -28,9 +28,11 @@ define([
});
it('metrics() should generate api suggest query', function() {
ctx.ds.metricFindQuery('metrics()').then(function(data) { results = data; });
ctx.ds.metricFindQuery('metrics(pew)').then(function(data) { results = data; });
ctx.$rootScope.$apply();
expect(requestOptions.url).to.be('/api/suggest');
expect(requestOptions.params.type).to.be('metrics');
expect(requestOptions.params.q).to.be('pew');
});
it('tag_names(cpu) should generate looku query', function() {
@ -47,6 +49,22 @@ define([
expect(requestOptions.params.m).to.be('cpu{hostname=*}');
});
it('suggest_tagk() should generate api suggest query', function() {
ctx.ds.metricFindQuery('suggest_tagk(foo)').then(function(data) { results = data; });
ctx.$rootScope.$apply();
expect(requestOptions.url).to.be('/api/suggest');
expect(requestOptions.params.type).to.be('tagk');
expect(requestOptions.params.q).to.be('foo');
});
it('suggest_tagv() should generate api suggest query', function() {
ctx.ds.metricFindQuery('suggest_tagv(bar)').then(function(data) { results = data; });
ctx.$rootScope.$apply();
expect(requestOptions.url).to.be('/api/suggest');
expect(requestOptions.params.type).to.be('tagv');
expect(requestOptions.params.q).to.be('bar');
});
});
});
});

View File

@ -1,36 +0,0 @@
{
"name": "angular-native-dragdrop",
"version": "1.1.1",
"homepage": "http://angular-dragdrop.github.io/angular-dragdrop",
"authors": [
"ganarajpr"
],
"description": "Angular HTML5 Drag and Drop directive written in pure with no dependency on JQuery.",
"main": "draganddrop.js",
"keywords": [
"angular",
"drag",
"drop",
"html5"
],
"dependencies": {
"angular": "^1.3"
},
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
],
"_release": "1.1.1",
"_resolution": {
"type": "version",
"tag": "v1.1.1",
"commit": "4ff89cb0aa61070508e935729fb816fd46a58f60"
},
"_source": "git://github.com/angular-dragdrop/angular-dragdrop.git",
"_target": "~1.1.1",
"_originalSource": "angular-native-dragdrop"
}

View File

@ -1,15 +0,0 @@
/* jshint -W097 */
'use strict';
/* global require */
var jshint = require('gulp-jshint');
var stylish = require('jshint-stylish');
var gulp = require('gulp');
gulp.task('lint', function() {
return gulp.src('./draganddrop.js')
.pipe(jshint())
.pipe(jshint.reporter(stylish));
});
gulp.task('default', ['lint']);

View File

@ -1,10 +0,0 @@
The MIT License
Copyright (c) 2015 Ganaraj P R, [Nebithi](http://www.nebithi.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -1,27 +0,0 @@
{
"name": "angular-native-dragdrop",
"version": "1.1.1",
"homepage": "http://angular-dragdrop.github.io/angular-dragdrop",
"authors": [
"ganarajpr"
],
"description": "Angular HTML5 Drag and Drop directive written in pure with no dependency on JQuery.",
"main": "draganddrop.js",
"keywords": [
"angular",
"drag",
"drop",
"html5"
],
"dependencies": {
"angular": "^1.3"
},
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
]
}

View File

@ -1,29 +0,0 @@
body {
background-color: #f8f7f8;
}
.heading {
border-bottom: 1px solid #b7b7b7;
padding-bottom: 10px;
margin-bottom: 10px;
}
.topRow {
margin-bottom: 30px;
}
.on-drag-enter {
background-color : #677ba6;
}
.on-drag-enter-custom {
background-color : #d78cc7;
}
.on-drag-hover {
background-color : #3eb352;
}
.on-drag-hover-custom {
background-color : #d7a931;
}

View File

@ -1,129 +0,0 @@
<!DOCTYPE html>
<html ng-app="app">
<head>
<meta charset="utf-8" />
<title>Angular DragDrop (Demo)</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="css/styles.css" />
<script data-require="angular.js@1.4.x" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.js" data-semver="1.4.3"></script>
<script src="http://pc035860.github.io/angular-highlightjs/angular-highlightjs.min.js"></script>
<script src="js/app.js"></script>
<script src="../draganddrop.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
</head>
<body >
<div class="container">
<div class="row topRow">
<h4 class="heading">
Drag and drop between the two lists.
</h4>
</div>
<h3>Beasts</h3>
<p>Left column of beasts is not draggable and accepts both beasts and priests</p>
<hr>
<div class="row" ng-controller="MainCtrl">
<div class="col-xs-6">
<ul ui-on-drop="onDrop($event,$data,men)" drag-enter-class="on-drag-enter-custom"
drop-channel="beasts,priests"
drop-validate="dropValidateHandler($drop, $event, $data)">
<li ui-draggable="false" drag="man" drag-channel="beasts"
on-drop-success="dropSuccessHandler($event,$index,men)"
ng-repeat="man in men track by $index">
{{man}}
</li>
</ul>
</div>
<div class="col-xs-6">
<ul ui-on-drop="onDrop($event,$data,women)"
drop-channel="beasts"
drop-validate="dropValidateHandler($drop, $event, $data)">
<li ui-draggable="true" drag="woman" drag-channel="beasts"
on-drop-success="dropSuccessHandler($event,$index,women)"
ng-repeat="woman in women track by $index">
{{woman}}
</li>
</ul>
</div>
</div>
<hr>
<h3>Priests</h3>
<hr>
<div class="row" ng-controller="MainCtrl">
<div class="col-xs-6">
<ul ui-on-drop="onDrop($event,$data,men)"
drop-channel="priests"
drop-validate="dropValidateHandler($drop, $event, $data)">
<li ui-draggable="true" drag="man"
drag-channel="priests"
on-drop-success="dropSuccessHandler($event,$index,men)"
ng-repeat="man in men track by $index">
{{man}}
</li>
</ul>
</div>
<div class="col-xs-6">
<ul ui-on-drop="onDrop($event,$data,women)"
drop-channel="priests"
drop-validate="dropValidateHandler($drop, $event, $data)">
<li ui-draggable="true" drag="woman"
drag-channel="priests"
on-drop-success="dropSuccessHandler($event,$index,women)"
ng-repeat="woman in women track by $index">
{{woman}}
</li>
</ul>
</div>
</div>
<hr>
<h3>Terrorists</h3>
<p>Each terrorist list item accepts a new terrorist. Shows inserting into a particular
position in an array.</p>
<hr>
<div class="row" ng-controller="MainCtrl">
<div class="col-xs-6">
<ul>
<li ui-draggable="true" drag="man"
drag-channel="terrorists2"
drop-validate="dropValidateHandler($drop, $event, $data)"
drag-hover-class="on-drag-hover-custom"
on-drop-success="dropSuccessHandler($event,$index,men)"
ui-on-drop="onDrop($event,$data,men,$index)" drop-channel="terrorists1"
ng-repeat="man in men track by $index">
{{man}}
</li>
</ul>
</div>
<div class="col-xs-6">
<ul>
<li ui-draggable="true" drag="woman"
drag-channel="terrorists1"
drop-validate="dropValidateHandler($drop, $event, $data)"
drag-hover-class="on-drag-hover-custom"
ui-on-drop="onDrop($event,$data,women,$index)" drop-channel="terrorists2"
on-drop-success="dropSuccessHandler($event,$index,women)"
ng-repeat="woman in women track by $index">
{{woman}}
</li>
</ul>
</div>
</div>
</div>
</body>
</html>

View File

@ -1,46 +0,0 @@
angular.module('app', [
'hljs',
'ang-drag-drop'
]).controller('MainCtrl', function($scope) {
$scope.men = [
'John',
'Jack',
'Mark',
'Ernie',
'Mike (Locked)'
];
$scope.women = [
'Jane',
'Jill',
'Betty',
'Mary'
];
$scope.addText = '';
$scope.dropValidateHandler = function($drop, $event, $data) {
if ($data === 'Mike (Locked)') {
return false;
}
if ($drop.element[0] === $event.srcElement.parentNode) {
// Don't allow moving to same container
return false;
}
return true;
};
$scope.dropSuccessHandler = function($event, index, array) {
array.splice(index, 1);
};
$scope.onDrop = function($event, $data, array, index) {
if (index !== undefined) {
array.splice(index, 0, $data);
} else {
array.push($data);
}
};
});

View File

@ -1,32 +0,0 @@
.content {
margin : 50px auto;
font-size: 1.0em;
line-height: 1.5em;
}
.content a{
color: #677BA6;
cursor: pointer;
}
body {
background-color: #f8f7f8;
}
.jumbotron h1,
.jumbotron p{
font-family: 'Open Sans';
}
.heading{
border-bottom: 1px solid #b7b7b7;
padding-bottom: 10px;
margin-bottom: 10px;
}
.ribbon{
position: fixed;
top : 0;
right : 0;
z-index: 2000;
}

View File

@ -1,323 +0,0 @@
<!DOCTYPE html>
<html ng-app="app">
<head>
<title>Angular DragDrop</title>
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="css/styles.css"/>
<link rel="stylesheet" href="http://yandex.st/highlightjs/7.3/styles/github.min.css">
<script src="http://yandex.st/highlightjs/7.3/highlight.min.js"></script>
<script data-require="angular.js@1.3.x" src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"
data-semver="1.3.x"></script>
<script src="http://pc035860.github.io/angular-highlightjs/angular-highlightjs.min.js"></script>
</head>
<body>
<header class="navbar navbar-default navbar-fixed-top" role="banner">
<div class="container">
<div class="navbar-header">
<a href="#" class="navbar-brand">Angular DragDrop</a>
</div>
</div>
</header>
<a class="ribbon" href="https://github.com/angular-dragdrop/angular-dragdrop"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub"></a>
<div class="jumbotron">
<div class="container">
<h1>Angular Drag and Drop</h1>
<p>Angular-DragDrop is a <a href="http://www.angularjs.org">AngularJS</a> HTML5 Drag and Drop directive written in pure with no dependency on JQuery.</p>
<iframe src="http://ghbtns.com/github-btn.html?user=angular-dragdrop&repo=angular-dragdrop&type=watch&count=true"
allowtransparency="true" frameborder="0" scrolling="0" width="110" height="20"></iframe>
<iframe src="http://ghbtns.com/github-btn.html?user=angular-dragdrop&repo=angular-dragdrop&type=fork&count=true"
allowtransparency="true" frameborder="0" scrolling="0" width="110" height="20"></iframe>
</div>
</div>
<div class="container content">
<h2>Directives</h2>
<hr>
<h3 class="text-info"><em>ui-draggable</em></h3>
<p>
directive in module <em>ngDragDrop</em>
</p>
<p>The <code>ui-draggable</code> attribute tells Angular that the element is draggable. <code>ui-draggable</code>
takes an expression as the attribute value. The expression should evaluate to either <code>true</code> or <code>false</code>.
You can toggle the draggability of an element using this expression.
</p>
<h3 class="heading"><strong>Additional Attributes</strong></h3>
<h4 class="text-info"><em>drag</em></h4>
<p>The <code>drag</code> property is used to assign the data that needs to be passed along with the dragging
element.</p>
<hr>
<h4 class="text-info"><em>drag-handle-class</em></h4>
<p>The class used to mark child elements of draggable object to be used as drag handle. Default class name is
<code>drag-handle</code>.</p>
<div>
<strong>NOTE</strong>: If attribute is not present drag handle feature is not active.
</div>
<hr>
<h4 class="text-info"><em>on-drop-success</em></h4>
<p>The <code>on-drop-success</code> attribute takes a function. We can consider this to be an on-drop-success
handler function.
This can be useful if you need to do some post processing after the dragged element is dropped successfully on
the drop site.
<div>
<strong>NOTE</strong>: This callback function is only called when the drop succeeds.
</div>
You can request the <code>drag-end</code> event ( very similiar to requesting the click event in
<code>ng-click</code> )
by passing <code>$event</code> in the event handler.
</p>
<hr>
<h4 class="text-info"><em>on-drop-failure</em></h4>
<p>The <code>on-drop-failure</code> attribute takes a function. We can consider this to be an on-drop-failure
handler function.
This can be useful if you need to do some post processing after the dragged element is dropped unsuccessfully on
any drop site.
<div>
<strong>NOTE</strong>: This callback function is only called when the drop fails.
</div>
You can request the <code>drag-end</code> event ( very similiar to requesting the click event in
<code>ng-click</code> )
by passing <code>$event</code> in the event handler.
</p>
<hr>
<h3 class="heading"><strong>Usage</strong></h3>
<p>
<div hljs>
<ANY ui-draggable="{expression}"
drag="dragData"
drag-handle-class="my-drag-handle"
on-drop-success="onDropSuccessHandler($event)"
on-drop-failure="onDropFailureHandler($event)"
drag-channel="mydropchannel">...
</ANY>
</div>
</p>
<h3 class="heading"><strong>Details</strong></h3>
<p>
<table class="table table-bordered">
<thead>
<tr>
<td>Param</td>
<td>Type</td>
<td>Details</td>
</tr>
</thead>
<tbody>
<tr>
<td>ui-draggable</td>
<td><label class="text-muted">expression</label></td>
<td><a target="_blank" href="http://docs.angularjs.org/guide/expression">Expression</a> that should be
evaluated. The given expression should resolve to true or false.
</td>
</tr>
<tr>
<td>drag</td>
<td><label class="text-muted">variable</label></td>
<td>Takes any JSON convertable <code>$scope</code> variable.</td>
</tr>
<tr>
<td>drag-handle-class</td>
<td><label class="text-muted">string</label></td>
<td>Class name used to mark child elements of draggable object to be used as drag handle. <br/>If attribute
is not present drag handle feature is not used. <br/>If attribute is present but have no value
<code>drag-handle</code> used as default.</td>
</tr>
<tr>
<td>on-drop-success</td>
<td><label class="text-muted">function</label></td>
<td>Takes any <code>$scope</code> function. Can also pass <code>$event</code>.</td>
</tr>
<tr>
<td>on-drop-failure</td>
<td><label class="text-muted">function</label></td>
<td>Takes any <code>$scope</code> function. Can also pass <code>$event</code>.</td>
</tr>
<tr>
<td>drag-channel</td>
<td><label class="text-muted">string</label></td>
<td>Takes a string that can be used as the channel name for the dragging operation.
Default channel is <code>"defaultchannel"</code>
</td>
</tr>
</tbody>
</table>
</p>
<hr>
<h3 class="heading"><strong>Events</strong></h3>
<p>On start of dragging an Angular Event <code>ANGULAR_DRAG_START</code> is dispatched from the
<code>$rootScope</code>. The event also carries
carries the information about the channel in which the dragging has started.
</p>
<p>On end of dragging an Angular Event <code>ANGULAR_DRAG_END</code> is dispatched from the <code>$rootScope</code>.
The event also carries
carries the information about the channel in which the dragging has started.
</p>
<p>When hovering a draggable element on top of a drop area an Angular Event <code>ANGULAR_HOVER</code>
is dispatched from the <code>$rootScope</code>.
The event also carries the information about the channel in which the dragging has started.
</p>
<hr>
<h3 class="text-info"><em>ui-on-drop</em></h3>
<p>
directive in module <em>ngDragDrop</em>
</p>
<p>The <code>ui-on-drop</code> attribute tells Angular that the element is a drop site. <code>ui-on-drop</code>
takes a function as the attribute value. The function will be called when a valid dragged element is dropped in
that location.
A valid dragged element is one which has the same channel as the drop location.
<div>
<strong>NOTE</strong> : This callback function is only called when the drop succeeds.
</div>
The <code>ui-on-drop</code> callback can request additional parameters. The data that is dragged is available to the
callback as <code>$data</code> and its channel as <code>$channel</code>. Apart from this the drop event is exposed as <code>$event</code>.
</p>
<h3 class="heading"><strong>Additional Attributes</strong></h3>
<h4 class="text-info"><em>drop-channel</em></h4>
<p>The channel that the drop site accepts. The dragged element should have the same channel as this drop site for it
to be droppable at this location. It is possible to provide comma separated list of channels.
<div>
<strong>NOTE</strong>: Also special value of <code>drag-channel</code> attribute is available to accept
dragged element with any channel value — <code>*</code>
</div>
</p>
<hr>
<h4 class="text-info"><em>drop-validate</em></h4>
<p>Extra validation that makes sure that the drop site accepts the dragged element beyond having the same channel. If
not defined, no extra validation is made.
<div>
<strong>NOTE</strong>: This callback function is called only if the channel condition is met, when the element
starts being dragged
</div>
</p>
<hr>
<h4 class="text-info"><em>drag-enter-class</em></h4>
<p>The class that will be added to the the droppable element when a dragged element ( which is droppable )
enters the drop location. The default value for this is <code>on-drag-enter</code></p>
<h4 class="text-info"><em>drag-hover-class</em></h4>
<p>The class that will be added to the drop area element when hovering with an element.
The default value for this is <code>on-drag-hover</code></p>
<hr>
<h3 class="heading"><strong>Usage</strong></h3>
<p>
<div hljs>
<ANY ui-on-drop="onDrop($data,$channel,$event)" drop-channel="mydropchannel" drag-enter-class="dragEnter">...</ANY>
</div>
</p>
<h3 class="heading"><strong>Details</strong></h3>
<p>
<table class="table table-bordered">
<thead>
<tr>
<td>Param</td>
<td>Type</td>
<td>Details</td>
</tr>
</thead>
<tbody>
<tr>
<td>ui-on-drop</td>
<td><label class="text-muted">function</label></td>
<td>Takes any <code>$scope</code> function. Can also pass <code>$event</code>, <code>$data</code> and <code>$channel</code>.
</td>
</tr>
<tr>
<td>drop-channel</td>
<td><label class="text-muted">expression</label></td>
<td>The channel on which the drop has to listen for drag events. <br/>
Single value, comma separated list or special value <code>*</code> are possible</td>
</tr>
<tr>
<td>drop-validate</td>
<td><label class="text-muted">function</label></td>
<td>Takes any <code>$scope</code> function. Can also pass <code>$data</code> and <code>$channel</code>
</td>
</tr>
<tr>
<td>drag-enter-class</td>
<td><label class="text-muted">string</label></td>
<td>A class name that will be put on the droppable element when the dragged objects enters its boundaries.
<br/>Default class name is <code>on-drag-enter</code>.</td>
</tr>
<td>drag-hover-class</td>
<td><label class="text-muted">string</label></td>
<td>A class name that will be put on the drop area when an element is dragged onto it. <br/>Default class
name is <code>on-drag-hover</code>.</td>
</tr>
</tbody>
</table>
</p>
<hr>
<h3 class="heading"><strong>Demo</strong></h3>
<iframe style="width: 100%; height: 500px" src="http://embed.plnkr.co/5RLvCpDPoRcEk6u77dBM" frameborder="0" allowfullscreen="allowfullscreen"></iframe>
<iframe style="width: 100%; height: 500px" src="http://embed.plnkr.co/xRmz4TlCvlJKxybGrhQH" frameborder="0" allowfullscreen="allowfullscreen"></iframe>
</div>
<footer class="navbar navbar-default navbar-fixed-bottom"></footer>
<script type="text/javascript" src="../js/app.js"></script>
<script>
(function (i, s, o, g, r, a, m) {
i['GoogleAnalyticsObject'] = r;
i[r] = i[r] || function () {
(i[r].q = i[r].q || []).push(arguments)
}, i[r].l = 1 * new Date();
a = s.createElement(o),
m = s.getElementsByTagName(o)[0];
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m)
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
ga('create', 'UA-44888767-1', 'ganarajpr.github.io');
ga('send', 'pageview');
</script>
</body>
</html>

View File

@ -1,24 +0,0 @@
{
"name": "angular-native-dragdrop",
"version": "1.1.1",
"description": "Angular HTML5 Drag and Drop directive written in pure with no dependency on JQuery.",
"main": "draganddrop.js",
"scripts": {
"test": "gulp"
},
"repository": {
"type": "git",
"url": "https://github.com/angular-dragdrop/angular-dragdrop.git"
},
"author": "ganarajpr",
"license": "MIT",
"bugs": {
"url": "https://github.com/angular-dragdrop/angular-dragdrop/issues"
},
"homepage": "http://angular-dragdrop.github.io/angular-dragdrop",
"devDependencies": {
"gulp": "^3.8.11",
"gulp-jshint": "^1.9.2",
"jshint-stylish": "^1.0.1"
}
}

View File

@ -6,6 +6,11 @@ module.exports = function(config,grunt) {
var dest = './vendor/phantomjs/phantomjs';
var confDir = './node_modules/karma-phantomjs-launcher/node_modules/phantomjs/lib/'
if (!grunt.file.exists(confDir)) {
// npm 3 or npm 2 with dedupe
confDir = './node_modules/phantomjs/lib/';
}
if (!grunt.file.exists(dest)){
var m=grunt.file.read(confDir+"location.js")