| @@ -0,0 +1,11 @@ | ||
| { | ||
| "js": [ | ||
| "../../bower_components/d3/d3.min.js", | ||
| "../../c3.min.js" | ||
| ], | ||
| "css": [ | ||
| "../../c3.css" | ||
| ], | ||
|
|
||
| "template": "<html><head><meta charset=\"utf-8\"><style>{0}</style></head><body><div id=\"chart\"></div></body></html>" | ||
| } |
| @@ -0,0 +1,140 @@ | ||
| /** | ||
| * PNG\JPEG exporter for C3.js, version 0.2 | ||
| * (c) 2014 Yuval Bar-On | ||
| * | ||
| * usage: path/to/phantomjs output options [WxH] | ||
| * | ||
| */ | ||
|
|
||
| // useful python-styled string formatting, "hello {0}! Javascript is {1}".format("world", "awesome"); | ||
| if (!String.prototype.format) { | ||
| String.prototype.format = function() { | ||
| var args = arguments; | ||
| return this.replace(/{(\d+)}/g, function(match, number) { | ||
| return typeof args[number] != 'undefined' | ||
| ? args[number] | ||
| : match | ||
| ; | ||
| }); | ||
| }; | ||
| } | ||
|
|
||
| // defaults | ||
| var page = require('webpage').create(), | ||
| fs = require('fs'), | ||
| system = require('system'), | ||
| config = JSON.parse( fs.read('config.json') ), | ||
| output, size; | ||
|
|
||
| if (system.args.length < 3 ) { | ||
| console.log('Usage: phantasm.js filename html [WxH]'); | ||
| phantom.exit(1); | ||
| } else { | ||
| out = system.args[1]; | ||
| opts = JSON.parse( system.args[2] ); | ||
|
|
||
| if (system.args[3]) { | ||
| var dimensions = system.args[3].split('x'), | ||
| width = dimensions[0], | ||
| height = dimensions[1]; | ||
|
|
||
| function checkNum(check) { | ||
| check = parseInt(check); | ||
| if (!isNaN(check)) | ||
| return check; | ||
| return false; | ||
| } | ||
|
|
||
| width = checkNum(width); | ||
| height = checkNum(height); | ||
|
|
||
| if (width && height) { | ||
| page.viewportSize = { | ||
| height: height, | ||
| width: width | ||
| } | ||
| } | ||
|
|
||
| // fit chart size to img size, if undefined | ||
| if (!opts.size) { | ||
| opts.size = { | ||
| "height": height, | ||
| "width": width | ||
| }; | ||
| } | ||
| } else { | ||
| // check if size is defined in chart, | ||
| // else apply defaults | ||
| page.viewportSize = { | ||
| height: (opts.size && opts.size.height) ? opts.size.height : 320, | ||
| width: (opts.size && opts.size.width ) ? opts.size.width : 710, | ||
| } | ||
| } | ||
| } | ||
|
|
||
| page.onResourceRequested = function(requestData, request) { | ||
| console.log('::loading resource ', requestData['url']); | ||
| }; | ||
|
|
||
| // helpful debug functions | ||
| page.onConsoleMessage = function(msg){ | ||
| console.log(msg); | ||
| }; | ||
|
|
||
| page.onError = function(msg, trace) { | ||
| var msgStack = ['ERROR: ' + msg]; | ||
|
|
||
| if (trace && trace.length) { | ||
| msgStack.push('TRACE:'); | ||
| trace.forEach(function(t) { | ||
| msgStack.push(' -> ' + t.file + ': ' + t.line + (t.function ? ' (in function "' + t.function +'")' : '')); | ||
| }); | ||
| } | ||
|
|
||
| console.error(msgStack.join('\n')); | ||
| }; | ||
|
|
||
| // render page | ||
| function injectVerify(script) { | ||
| var req = page.injectJs(script); | ||
| if (!req) { | ||
| console.log( '\nError!\n' + script + ' not found!\n' ); | ||
| phantom.exit(1); | ||
| } | ||
| } | ||
|
|
||
| page.onLoadFinished = function() { | ||
| console.log('::rendering'); | ||
|
|
||
| for (var j in config.js) { | ||
| injectVerify(config.js[j]); | ||
| } | ||
|
|
||
| page.evaluate(function(chartoptions) { | ||
| // phantomjs doesn't know how to handle .bind, so we override | ||
| Function.prototype.bind = Function.prototype.bind || function (thisp) { | ||
| var fn = this; | ||
| return function () { | ||
| return fn.apply(thisp, arguments); | ||
| }; | ||
| }; | ||
|
|
||
| // generate chart | ||
| c3.generate(chartoptions); | ||
|
|
||
| }, opts); | ||
|
|
||
| // setting transition to 0 has proven not to work thus far, but 300ms isn't much | ||
| // so this is acceptable for now | ||
| setTimeout(function() { | ||
| page.render(out); | ||
| phantom.exit(); | ||
| }, 300); | ||
| } | ||
|
|
||
| // apply css inline because that usually renders better | ||
| var css = ''; | ||
| for (var i in config.css) { | ||
| css += fs.read(config.css[i]); | ||
| } | ||
| page.content = config.template.format(css); |
| @@ -0,0 +1,380 @@ | ||
| var c3ext = {}; | ||
| c3ext.generate = function (options) { | ||
|
|
||
| if (options.zoom2 != null) { | ||
| zoom2_reducers = options.zoom2.reducers || {}; | ||
| zoom2_enabled = options.zoom2.enabled; | ||
| _zoom2_factor = options.zoom2.factor || 1; | ||
| _zoom2_maxItems = options.zoom2.maxItems; | ||
| } | ||
|
|
||
| if (!zoom2_enabled) { | ||
| return c3.generate(options); | ||
| } | ||
|
|
||
|
|
||
| var originalData = Q.copy(options.data); | ||
| var zoom2_reducers; | ||
| var zoom2_enabled; | ||
| var _zoom2_maxItems; | ||
|
|
||
| if (_zoom2_maxItems == null) { | ||
| var el = d3.select(options.bindto)[0][0]; | ||
| if (el != null) { | ||
| var availWidth = el.clientWidth; | ||
|
|
||
| var pointSize = 20; | ||
| _zoom2_maxItems = Math.ceil(availWidth / pointSize); | ||
| } | ||
| if (_zoom2_maxItems == null || _zoom2_maxItems < 10) { | ||
| _zoom2_maxItems = 10; | ||
| } | ||
| } | ||
|
|
||
| function onZoomChanged(e) { | ||
| refresh(); | ||
| } | ||
|
|
||
| var zoom2 = c3ext.ZoomBehavior({ changed: onZoomChanged, bindto: options.bindto }); | ||
|
|
||
| zoom2.enhance = function () { | ||
| _zoom2_maxItems *= 2; | ||
| var totalItems = zoom2.getZoom().totalItems; | ||
| if (_zoom2_maxItems > totalItems) | ||
| _zoom2_maxItems = totalItems; | ||
| refresh(); | ||
| } | ||
| zoom2.dehance = function () { | ||
| _zoom2_maxItems = Math.ceil(_zoom2_maxItems / 2) + 1; | ||
| refresh(); | ||
| } | ||
|
|
||
| zoom2.maxItems = function () { return _zoom2_maxItems; }; | ||
| function zoomAndReduceData(list, zoomRange, func, maxItems) { | ||
| //var maxItems = 10;//Math.ceil(10 * zoomFactor); | ||
| var list2 = list.slice(zoomRange[0], zoomRange[1]); | ||
| var chunkSize = 1; | ||
| var list3 = list2; | ||
| if (list3.length > maxItems) { | ||
| var chunkSize = Math.ceil(list2.length / maxItems); | ||
| list3 = list3.splitIntoChunksOf(chunkSize).map(func); | ||
| } | ||
| //console.log("x" + getCurrentZoomLevel() + ", maxItems=" + maxItems + " chunkSize=" + chunkSize + " totalBefore=" + list2.length + ", totalAfter=" + list3.length); | ||
| return list3; | ||
| } | ||
|
|
||
| function first(t) { return t[0]; } | ||
|
|
||
| var getDataForZoom = function (data) { | ||
| if (data.columns == null || data.columns.length == 0) | ||
| return; | ||
|
|
||
| var zoomInfo = zoom2.getZoom(); | ||
| if (zoomInfo.totalItems != data.columns[0].length - 1) { | ||
| zoom2.setOptions({ totalItems: data.columns[0].length - 1 }); | ||
| zoomInfo = zoom2.getZoom(); | ||
| } | ||
| data.columns = originalData.columns.map(function (column) { | ||
| var name = column[0]; | ||
| var reducer = zoom2_reducers[name] || first; //by default take the first | ||
|
|
||
| var values = column.slice(1); | ||
| var newValues = zoomAndReduceData(values, zoomInfo.currentZoom, reducer, _zoom2_maxItems); | ||
| return [name].concat(newValues); | ||
| }); | ||
| return data; | ||
| }; | ||
|
|
||
| getDataForZoom(options.data); | ||
| var chart = c3.generate(options); | ||
| var _chart_load_org = chart.load.bind(chart); | ||
| chart.zoom2 = zoom2; | ||
| chart.load = function (data) { | ||
| if (data.unload) { | ||
| unload(data.unload); | ||
| delete data.unload; | ||
| } | ||
| Q.copy(data, originalData); | ||
| refresh(); | ||
| } | ||
| chart.unload = function (names) { | ||
| unload(names); | ||
| refresh(); | ||
| } | ||
|
|
||
| function unload(names) { | ||
| originalData.columns.removeAll(function (t) { names.contains(t); }); | ||
| } | ||
|
|
||
|
|
||
| function refresh() { | ||
| var data = Q.copy(originalData) | ||
| getDataForZoom(data); | ||
| _chart_load_org(data); | ||
| }; | ||
|
|
||
|
|
||
| return chart; | ||
| } | ||
|
|
||
| c3ext.ZoomBehavior = function (options) { | ||
| var zoom = { __type: "ZoomBehavior" }; | ||
|
|
||
| var _zoom2_factor; | ||
| var _left; | ||
| var totalItems; | ||
| var currentZoom; | ||
| var bindto = options.bindto; | ||
| var _zoomChanged = options.changed || function () { }; | ||
| var element; | ||
| var mousewheelTimer; | ||
| var deltaY = 0; | ||
| var leftRatio = 0; | ||
|
|
||
|
|
||
| zoom.setOptions = function (options) { | ||
| if (options == null) | ||
| options = {}; | ||
| _zoom2_factor = options.factor || 1; | ||
| _left = 0; | ||
| totalItems = options.totalItems || 0; | ||
| currentZoom = [0, totalItems]; | ||
| _zoomChanged = options.changed || _zoomChanged; | ||
| } | ||
|
|
||
| zoom.setOptions(options); | ||
|
|
||
|
|
||
| function verifyZoom(newZoom) { | ||
| //newZoom.sort(); | ||
| if (newZoom[1] > totalItems) { | ||
| var diff = newZoom[1] - totalItems; | ||
| newZoom[0] -= diff; | ||
| newZoom[1] -= diff; | ||
| } | ||
| if (newZoom[0] < 0) { | ||
| var diff = newZoom[0] * -1; | ||
| newZoom[0] += diff; | ||
| newZoom[1] += diff; | ||
| } | ||
| if (newZoom[1] > totalItems) | ||
| newZoom[1] = totalItems; | ||
| if (newZoom[0] < 0) | ||
| newZoom[0] = 0; | ||
| } | ||
|
|
||
| function zoomAndPan(zoomFactor, left) { | ||
| var itemsToShow = Math.ceil(totalItems / zoomFactor); | ||
| var newZoom = [left, left + itemsToShow]; | ||
| verifyZoom(newZoom); | ||
| currentZoom = newZoom; | ||
| onZoomChanged(); | ||
| } | ||
|
|
||
| function onZoomChanged() { | ||
| if (_zoomChanged != null) | ||
| _zoomChanged(zoom.getZoom()); | ||
| } | ||
| function applyZoomAndPan() { | ||
| zoomAndPan(_zoom2_factor, _left); | ||
| } | ||
| function getItemsToShow() { | ||
| var itemsToShow = Math.ceil(totalItems / _zoom2_factor); | ||
| return itemsToShow; | ||
| } | ||
|
|
||
|
|
||
| zoom.getZoom = function () { | ||
| return { totalItems: totalItems, currentZoom: currentZoom.slice() }; | ||
| } | ||
|
|
||
| zoom.factor = function (factor, skipDraw) { | ||
| if (arguments.length == 0) | ||
| return _zoom2_factor; | ||
| _zoom2_factor = factor; | ||
| if (_zoom2_factor < 1) | ||
| _zoom2_factor = 1; | ||
| if (skipDraw) | ||
| return; | ||
| applyZoomAndPan(); | ||
| } | ||
| zoom.left = function (left, skipDraw) { | ||
| if (arguments.length == 0) | ||
| return _left; | ||
| _left = left; | ||
| if (_left < 0) | ||
| _left = 0; | ||
| var pageSize = getItemsToShow(); | ||
| //_left += pageSize; | ||
| if (_left + pageSize > totalItems) | ||
| _left = totalItems - pageSize; | ||
| console.log({ left: _left, pageSize: pageSize }); | ||
| if (skipDraw) | ||
| return; | ||
| applyZoomAndPan(); | ||
| } | ||
|
|
||
| zoom.zoomAndPanByRatio = function (zoomRatio, panRatio) { | ||
|
|
||
| var pageSize = getItemsToShow(); | ||
| var leftOffset = Math.round(pageSize * panRatio); | ||
| var mouseLeft = _left + leftOffset; | ||
| zoom.factor(zoom.factor() * zoomRatio, true); | ||
|
|
||
| var finalLeft = mouseLeft; | ||
| if (zoomRatio != 1) { | ||
| var pageSize2 = getItemsToShow(); | ||
| var leftOffset2 = Math.round(pageSize2 * panRatio); | ||
| finalLeft = mouseLeft - leftOffset2; | ||
| } | ||
| zoom.left(finalLeft, true); | ||
| applyZoomAndPan(); | ||
| } | ||
|
|
||
| zoom.zoomIn = function () { | ||
| zoom.zoomAndPanByRatio(2, 0); | ||
| } | ||
|
|
||
| zoom.zoomOut = function () { | ||
| zoom.zoomAndPanByRatio(0.5, 0); | ||
| } | ||
|
|
||
| zoom.panLeft = function () { | ||
| zoom.zoomAndPanByRatio(1, -1); | ||
| } | ||
| zoom.panRight = function () { | ||
| zoom.zoomAndPanByRatio(1, 1); | ||
| } | ||
|
|
||
| zoom.reset = function () { | ||
| _left = 0; | ||
| _zoom2_factor = 1; | ||
| applyZoomAndPan(); | ||
| } | ||
|
|
||
| function doZoom() { | ||
| if (deltaY != 0) { | ||
| var maxDelta = 10; | ||
| var multiply = (maxDelta + deltaY) / maxDelta; | ||
| //var factor = chart.zoom2.factor()*multiply; | ||
| //factor= Math.ceil(factor*100) / 100; | ||
| console.log({ deltaY: deltaY, multiply: multiply }); | ||
| zoom.zoomAndPanByRatio(multiply, leftRatio);//0.5);//leftRatio); | ||
| deltaY = 0; | ||
| } | ||
| } | ||
|
|
||
| function element_mousewheel(e) { | ||
| deltaY += e.deltaY; | ||
| leftRatio = (e.offsetX - 70) / (e.currentTarget.offsetWidth - 70); | ||
| //console.log({ "e.offsetX": e.offsetX, "e.currentTarget.offsetWidth": e.currentTarget.offsetWidth, leftRatio: leftRatio }); | ||
| mousewheelTimer.set(150); | ||
| e.preventDefault(); | ||
| } | ||
|
|
||
| if (bindto != null) { | ||
| element = $(options.bindto); | ||
| if (element.mousewheel) { | ||
| mousewheelTimer = new Timer(doZoom); | ||
| element.mousewheel(element_mousewheel); | ||
| } | ||
| } | ||
|
|
||
| return zoom; | ||
|
|
||
| } | ||
|
|
||
| if (typeof (Q) == "undefined") { | ||
| var Q = function () { | ||
| }; | ||
|
|
||
| Q.copy = function (src, target, options, depth) { | ||
| ///<summary>Copies an object into a target object, recursively cloning any object or array in the way, overwrite=true will overwrite a primitive field value even if exists</summary> | ||
| ///<param name="src" /> | ||
| ///<param name="target" /> | ||
| ///<param name="options" type="Object">{ overwrite:false }</param> | ||
| ///<returns type="Object">The copied object</returns> | ||
| if (depth == null) | ||
| depth = 0; | ||
| if (depth == 100) { | ||
| console.warn("Q.copy is in depth of 100 - possible circular reference") | ||
| } | ||
| options = options || { overwrite: false }; | ||
| if (src == target || src == null) | ||
| return target; | ||
| if (typeof (src) != "object") { | ||
| if (options.overwrite || target == null) | ||
| return src; | ||
| return target; | ||
| } | ||
| if (typeof (src.clone) == "function") { | ||
| if (options.overwrite || target == null) | ||
| return src.clone(); | ||
| return target; | ||
| } | ||
| if (target == null) { | ||
| if (src instanceof Array) | ||
| target = []; | ||
| else | ||
| target = {}; | ||
| } | ||
|
|
||
| if (src instanceof Array) { | ||
| for (var i = 0; i < src.length; i++) { | ||
| var item = src[i]; | ||
| var item2 = target[i]; | ||
| item2 = Q.copy(item, item2, options, depth + 1); | ||
| target[i] = item2; | ||
| } | ||
| target.splice(src.length, target.length - src.length); | ||
| return target; | ||
| } | ||
| for (var p in src) { | ||
| var value = src[p]; | ||
| var value2 = target[p]; | ||
| value2 = Q.copy(value, value2, options, depth + 1); | ||
| target[p] = value2; | ||
| } | ||
| return target; | ||
| } | ||
| } | ||
| if (typeof (Timer) == "undefined") { | ||
| var Timer = function (action, ms) { | ||
| this.action = action; | ||
| if (ms != null) | ||
| this.set(ms); | ||
| } | ||
|
|
||
| Timer.prototype.set = function (ms) { | ||
| if (ms == null) | ||
| ms = this._ms; | ||
| else | ||
| this._ms = ms; | ||
| this.clear(); | ||
| if (ms == null) | ||
| return; | ||
| this.timeout = window.setTimeout(this.onTick.bind(this), ms); | ||
| } | ||
|
|
||
| Timer.prototype.onTick = function () { | ||
| this.clear(); | ||
| this.action(); | ||
| } | ||
|
|
||
| Timer.prototype.clear = function (ms) { | ||
| if (this.timeout == null) | ||
| return; | ||
| window.clearTimeout(this.timeout); | ||
| this.timeout = null; | ||
| } | ||
| } | ||
| if (typeof(Array.prototype.splitIntoChunksOf)=="undefined") { | ||
| Array.prototype.splitIntoChunksOf = function (countInEachChunk) { | ||
| var chunks = Math.ceil(this.length / countInEachChunk); | ||
| var list = []; | ||
| for (var i = 0; i < this.length; i += countInEachChunk) { | ||
| list.push(this.slice(i, i + countInEachChunk)); | ||
| } | ||
| return list; | ||
| } | ||
| } |
| @@ -0,0 +1,37 @@ | ||
| { | ||
| "name": "d3", | ||
| "main": "d3.js", | ||
| "scripts": [ | ||
| "d3.js" | ||
| ], | ||
| "ignore": [ | ||
| ".DS_Store", | ||
| ".git", | ||
| ".gitignore", | ||
| ".npmignore", | ||
| ".spmignore", | ||
| ".travis.yml", | ||
| "Makefile", | ||
| "bin", | ||
| "component.json", | ||
| "composer.json", | ||
| "index.js", | ||
| "lib", | ||
| "node_modules", | ||
| "package.json", | ||
| "src", | ||
| "test" | ||
| ], | ||
| "homepage": "https://github.com/mbostock/d3", | ||
| "version": "3.5.6", | ||
| "_release": "3.5.6", | ||
| "_resolution": { | ||
| "type": "version", | ||
| "tag": "v3.5.6", | ||
| "commit": "0e88ef5aacbc565b7282790c829ea51dd86c978d" | ||
| }, | ||
| "_source": "git://github.com/mbostock/d3.git", | ||
| "_target": "~3.5.6", | ||
| "_originalSource": "d3", | ||
| "_direct": true | ||
| } |
| @@ -0,0 +1,5 @@ | ||
| bower.json -diff merge=ours | ||
| component.json -diff merge=ours | ||
| d3.js -diff merge=ours | ||
| d3.min.js -diff merge=ours | ||
| package.js -diff merge=ours |
| @@ -0,0 +1,27 @@ | ||
| # Contributing | ||
|
|
||
| **Important:** these GitHub issues are for *bug reports and feature requests only*. Please use [StackOverflow](http://stackoverflow.com/questions/tagged/d3.js) or the [d3-js Google group](https://groups.google.com/d/forum/d3-js) for general help. | ||
|
|
||
| If you’re looking for ways to contribute, please [peruse open issues](https://github.com/mbostock/d3/issues?milestone=&page=1&state=open). The icebox is a good place to find ideas that are not currently in development. If you already have an idea, please check past issues to see whether your idea or a similar one was previously discussed. | ||
|
|
||
| Before submitting a pull request, consider implementing a live example first, say using [bl.ocks.org](http://bl.ocks.org). Real-world use cases go a long way to demonstrating the usefulness of a proposed feature. The more complex a feature’s implementation, the more usefulness it should provide. Share your demo using the #d3js tag on Twitter or by sending it to the [d3-js Google group](https://groups.google.com/d/forum/d3-js). | ||
|
|
||
| If your proposed feature does not involve changing core functionality, consider submitting it instead as a [D3 plugin](https://github.com/d3/d3-plugins). New core features should be for general use, whereas plugins are suitable for more specialized use cases. When in doubt, it’s easier to start with a plugin before “graduating” to core. | ||
|
|
||
| To contribute new documentation or add examples to the gallery, just [edit the Wiki](https://github.com/mbostock/d3/wiki)! | ||
|
|
||
| ## How to Submit a Pull Request | ||
|
|
||
| 1. Click the “Fork” button to create your personal fork of the D3 repository. | ||
|
|
||
| 2. After cloning your fork of the D3 repository in the terminal, run `npm install` to install D3’s dependencies. | ||
|
|
||
| 3. Create a new branch for your new feature. For example: `git checkout -b my-awesome-feature`. A dedicated branch for your pull request means you can develop multiple features at the same time, and ensures that your pull request is stable even if you later decide to develop an unrelated feature. | ||
|
|
||
| 4. The `d3.js` and `d3.min.js` files are built from source files in the `src` directory. _Do not edit `d3.js` directly._ Instead, edit the source files, and then run `make` to build the generated files. | ||
|
|
||
| 5. Use `make test` to run tests and verify your changes. If you are adding a new feature, you should add new tests! If you are changing existing functionality, make sure the existing tests run, or update them as appropriate. | ||
|
|
||
| 6. Sign D3’s [Individual Contributor License Agreement](https://docs.google.com/forms/d/1CzjdBKtDuA8WeuFJinadx956xLQ4Xriv7-oDvXnZMaI/viewform). Unless you are submitting a trivial patch (such as fixing a typo), this form is needed to verify that you are able to contribute. | ||
|
|
||
| 7. Submit your pull request, and good luck! |
| @@ -0,0 +1,26 @@ | ||
| Copyright (c) 2010-2015, Michael Bostock | ||
| All rights reserved. | ||
|
|
||
| Redistribution and use in source and binary forms, with or without | ||
| modification, are permitted provided that the following conditions are met: | ||
|
|
||
| * Redistributions of source code must retain the above copyright notice, this | ||
| list of conditions and the following disclaimer. | ||
|
|
||
| * Redistributions in binary form must reproduce the above copyright notice, | ||
| this list of conditions and the following disclaimer in the documentation | ||
| and/or other materials provided with the distribution. | ||
|
|
||
| * The name Michael Bostock may not be used to endorse or promote products | ||
| derived from this software without specific prior written permission. | ||
|
|
||
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
| AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
| DISCLAIMED. IN NO EVENT SHALL MICHAEL BOSTOCK BE LIABLE FOR ANY DIRECT, | ||
| INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | ||
| OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
| NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, | ||
| EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| @@ -0,0 +1,9 @@ | ||
| # Data-Driven Documents | ||
|
|
||
| <a href="http://d3js.org"><img src="http://d3js.org/logo.svg" align="left" hspace="10" vspace="6"></a> | ||
|
|
||
| **D3.js** is a JavaScript library for manipulating documents based on data. **D3** helps you bring data to life using HTML, SVG, and CSS. **D3** emphasizes web standards and combines powerful visualization components with a data-driven approach to DOM manipulation, giving you the full capabilities of modern browsers without tying yourself to a proprietary framework. | ||
|
|
||
| Want to learn more? [See the wiki.](https://github.com/mbostock/d3/wiki) | ||
|
|
||
| For examples, [see the gallery](https://github.com/mbostock/d3/wiki/Gallery) and [mbostock’s bl.ocks](http://bl.ocks.org/mbostock). |
| @@ -0,0 +1,25 @@ | ||
| { | ||
| "name": "d3", | ||
| "main": "d3.js", | ||
| "scripts": [ | ||
| "d3.js" | ||
| ], | ||
| "ignore": [ | ||
| ".DS_Store", | ||
| ".git", | ||
| ".gitignore", | ||
| ".npmignore", | ||
| ".spmignore", | ||
| ".travis.yml", | ||
| "Makefile", | ||
| "bin", | ||
| "component.json", | ||
| "composer.json", | ||
| "index.js", | ||
| "lib", | ||
| "node_modules", | ||
| "package.json", | ||
| "src", | ||
| "test" | ||
| ] | ||
| } |
| @@ -0,0 +1,13 @@ | ||
| // Package metadata for Meteor.js. | ||
|
|
||
| Package.describe({ | ||
| name: "d3js:d3", // http://atmospherejs.com/d3js/d3 | ||
| summary: "D3 (official): A JavaScript visualization library for HTML and SVG.", | ||
| version: "3.5.6", | ||
| git: "https://github.com/mbostock/d3.git" | ||
| }); | ||
|
|
||
| Package.onUse(function(api) { | ||
| api.versionsFrom(["METEOR@1.0"]); | ||
| api.addFiles("d3.js", "client"); | ||
| }); |