epochjs / epoch Goto Github PK
View Code? Open in Web Editor NEWA general purpose, real-time visualization library.
Home Page: http://epochjs.github.io/epoch
License: MIT License
A general purpose, real-time visualization library.
Home Page: http://epochjs.github.io/epoch
License: MIT License
Focused the purpose of this ticket a little more:
Originally:
Work through the styles as the exist/evolve and try to make them as easy to understand and override as possible. Other things that might be nice are general classifications for plots such as sparklines, etc. This will definitely have to evolve over time as we explore the usage space.
Currently we assume that a container for a plot will remain absolute and fixed. Modern CSS frameworks such as bootstrap provide adaptive styles that will resize element display widths as the browser window changes size. Look into handling these resize events intelligently and resizing plots when they occur.
It appears that there are a slew of devices that have/report non-integral pixel ratios [1]. We need to determine if Epoch's real-time charts will work appropriately in these contexts.
Full documentation.
The _prepareEntry
method of Epoch.Time.Heatmap
is responsible for transforming a sparse histogram into the correct number of buckets (buckets
option) given a range (bucketRange
option). The way we currently do this is pretty lazy and generally considered to be "jank" (technical term). This can have some very weird effects on the graphical output of the plot, here's an example:
This should be a plot of a normal distribution stretched over the range [0, 100) across 45 buckets. Clearly there are some weird numerical errors cropping up due to the so-called "jankness" of our bucketing routine.
Here's what needs to be done:
tests/real-time/heatmap.html
that reproduces the beahvior_prepareEntry
method that does not suffer from this problemTo make QueryCSS
more flexible we could follow the parent element tree up to the body node. Using each of the parent elements to construct the reference element would allow us to use more general selectors to apply styles to canvas plots.
The CSS style querying singelton (QueryCSS
) currently relies on jQuery's .load
method to place the reference element container into the page. While this technically works, it's weird in two ways:
<body>
Let's stop using the jQuery load method here and simply check for the containing element every time we make a query that requires it. Note that this performs fine since QueryCSS
is caching the results of css lookups.
Since we are moving most of the docs to the Github pages branch we need to rewrite the readme to make it more concise. Specifically it should cover the following:
Epoch needs better test coverage throughout its entire class hierarchy. For instance, we should at the very least cover the following bases:
Eventually it would be great to have both the basic and real-time charts fully unit tested, but the rendering tests suffice for these at the moment.
Use a spectrum from one color to another, or through multiple color stops, as opposed to using opacity to represent height in the heat map. Possible color combination [dark red, yellow].
For stacked plots it's reasonable to assume that the lowest value will be zero. This assumption breaks a bit with basic bar and line plots. It would be nice for us to allow the programmer to fix the x axis at the y-position 0 (as this is traditionally how it would be displayed.
The current heat map implementation (Epoch.Time.Heatmap
) uses opacity and a single CSS controlled color to determine the gradient used to denote "height" or "heat" in the map. In a recent experiment (#33) I was able to easily implement a coloring function that allowed the gradient to be computed over two user definable colors.
We should modify the current heat map implementation to allow for this. Specifically we want to do the following:
paintZeroValues
- If true then zero values are painted, otherwise they are omitted when rendering heat map columns (currently they are always omitted)._computeColor(value, max, color)
- This method should be responsible for returning a color given a value for the bucket and the computed maximum across the column. Currently this behavior is embedded in _paintEntry
and breaking it out makes the chart easier to extend..bucket0
- Currently we assume that we are going to compute the gradient from fully transparent to a CSS controlled color value. Allow developers to define the lower bound as any color they desire. The class .bucket0
(bucket naught) should default to rgba(0, 0, 0, 0.0)
.Note: this feature might not be a good option for multi-dimensional plots, as using solid colors across multiple layers will undoubtably make the chart much harder to read / interpret.
Related to #1. If you use the same labels and number of categories for the static pie chart then the transition will get a messed up quite a bit.
To reproduce create a bar chart and switch between the following data sets:
data1 = [
{ label: 'A', value: 10 },
{ label: 'B', value: 40 },
{ label: 'C', value: 50 }
]
data2 = [
{ label: 'A', value: 25 },
{ label: 'B', value: 60 },
{ label: 'C', value: 15 }
]
The slices should begin to overlap and look very strange.
Include Sass and Less mixins, etc. that make it easier for developers using those frameworks to override epoch styles. Related to #3.
kthx!
I think adding Retina support would be a nice touch. I dug up this gist that kind of addresses this - via the devicePixelRatio
method. According to QuirksMode, the browser support for this method is pretty good - http://www.quirksmode.org/blog/archives/2012/06/devicepixelrati.html
Rickshaw uses svg to get around this, but we all know how you feel about Rickshaw, @rsandor ๐
The basic bar chart should have an option for controlling bar padding. There are two types of paddings present:
0.08
)0.1
)The d3 documentation also mentions that there are two types of padding that can be applied via the ordinal scale's .rangeRoundBands
method: inner and outer. It would be nice if we could provide control over outer padding in both contexts as well (as we currently only support the basic padding parameter).
The Epoch.Util.domain
function is a bit weird as it does not preserve the order it encounters values. This is important for discrete charts such as Epoch.Chart.Bar
since it causes elements to appear in a string sorted order as opposed to the order the chart data was given.
Apparently making easy to use arc transformations wasn't high on the list for d3. Decrypt the online examples and apply them to the F.Chart.Pie
class.
Need to implement a multi-layer heatmap chart. Similar to the way we do it in the Fastly dashboard, but cleaner and better. Needs to piecewise rendering optimization to be performant. Might want to just roll the whole piecewise rendering system into the base plot class.
Add stroke styles and stroke rendering for real-time area charts.
Need a good and elegant way to handle legends and labels on charts.
Currently, overriding styles like fill and stroke colors require different CSS selectors depending on the type of chart. For instance, to change the styles of lines, areas, dots, and heat map buckets one uses the following selector pattern:
.layer-1 .line { stroke: blue; }
.layer-1 .area { fill: cyan; }
.layer-1 .dot { fill: orange; }
.layer-1 .bucket { fill: green; }
And to change bars and pie slices one uses two entirely different selector patterns:
.bar.layer-1 { fill: gray; }
.arc.layer-1 path { fill: black; }
While the current approach makes implementing the charts a little easier, it would be much better for application programmers if we had a consistent selector pattern. I am partial to this:
.layer-1 .line { stroke: blue }
The static bar chart Epoch.Chart.Bar
only supports grouped bar charts at the moment. We need to implement the stacked
and normal-stacked
types as well as transitions between the types.
It would be nice to have a way to easily create composite charts. Essentially it would give you a way to build multiple-charts together and give you a set of options that make it easy to determine placement and layering.
In the current heat map implementation, the color value used when rendering a bucket is buried deep within the _paintEntry
method. Pull this out into a new method named _computeColor
that makes it easier to extend the class.
Implement a simple stylized gauge chart for use with real-time data. Not sure if it needs the rendering optimization (via canvas), d3 should be more than enough for this type of chart.
Right now it is easy to get charts into a broken state if transitions are sent too quickly. We should look into building a transition queue for basic charts that ensure they are performed in the order sent.
All charts should have a method named option
that works as such:
chart.option()
- Returns a flat list of the chart's options (equivalent to chart.options
)chart.option(key)
- Returns the value of an individual option. Nested options can be accessed by using a .
in the key, like so: chart.option('tickFormats.top')
chart.option(key, value)
- Sets an option with the given key to the given value. Also triggers the event option:<key>
. This event will only fire if the option's value has actually changed.chart.option(object)
- Sets multiple options at the same time. Fires events for each of the options that are changed.Epoch should not rely on jQuery. Implement the jQuery features we use in pure CoffeeScript. For now let's assume we support IE > 8. See quirksmode for a decent breakdown on browser support for querying and manipulation:
For ease of implementation we chose to have set data formats for each of the types of plot. This can be a bit painful for simpler data (especially for time series data). Consider allowing each of the plots to accept multiple formats for the data.
I'd like to allow for more "flat" data to be used without having to explicitly specify the layer structure. For instance, instead of having to do this:
data = [
{ label: 'Layer 1', values: [ {time: 0, y: 0}, ... ] }
]
one could simply define the same single layer data set like so:
data = [ {time: 0, y: 0}, ... ]
Additionally it would be nice to allow for a series of basic numbers:
data = [ 0, 1, 2, 3, 20302 ]
For basic plots we could simply use the index as the x value. For real-time plots it's less nice since the time parameter expects a unix timestamp. Perhaps we could just count back from the current second in the browser?
Either way having simpler data formats should make it easier to get up and running with the library. And one can always use a more formal format as needed.
Sometimes in monitoring you want to have a range of acceptable behavior, and the realtime gauge graph is useful for that.
It would be great if you could specify that band and have different things happen if you went out of it. Either the entire gauge changes color, like green inside the band, red outside.
Or if you are going through different phases like say, RPM on a car, the first X percent is green, the next X percent is yellow, the final X is red as the gauge moves more to the right. And you could do that as a band/strip rather than as a full gauge color change.
Introduce a change log starting with the next release.
Many bar chart visualizations will often show negative bar values in one color (such as red) and positive bar values in another. The bar chart should apply a specific negative class to elements generated for y values less than zero. Or, at the very least, have an option that allows the programmer to enable this behavior.
Related to #21.
Need better rendering tests for each of the chart types. Specifically I'd like to do the following:
test/static.html
out into a single html page for each type of chart under the directory test/basic/*.html
test/time.html
out into a single html page for each type of chart under the directory test/realtime/*.html
test/index.html
where you can move back and forth between testsUse of $
is ambiguous, we should instead use jQuery
when interacting with the library.
On the project site we should provide basic CSS examples for how to override the styles in each of the chart sections.
On the project site the documentation for each of the individual charts' options tends to blend too much with the overall description. A couple of simple fixes could make these pages much easier to read:
The default black stroke on the real-time area chart doesn't match the basic area chart's defaults. Fix this by setting the stroke as transparent in the CSS.
By default the heat map implementation fully bypasses the rendering of buckets that have a zero sum in the dataset. We should provide a switch for this as an option to the chart named paintZeroValues
.
Per hendry on HackerNews:
Another time line graphing library without things like moving averages that I want. :/
This is a very valid point, we should have some way to easily add moving average lines, medians, etc. to plots.
The gauge chart seems to get "screwy" with it's frame rate if you change tabs and then change back. How to reproduce:
This came in via gingerlime
on hackernews:
... One obvious thing that felt like Epoch was missing was hover-over info. At least I couldn't spot it on the examples.
(Source)
Seems like this is a pretty basic low hanging fruit we could tackle in the near future. Leaving this as an open question for now to see if anyone has ideas or would like to discuss implementation strategies.
The bar chart should allow for two major orientations via an option named orientation
. This option should accept the following values:
horizontal
- Bars are arranged side-by-side horizontally (default/current, orientation)vertical
- Bars are arranged atop one another verticallyThis is only for the basic bar chart (Epoch.Chart.Bar
).
TODO:
test/basic/bar.html
If you omit the label
key when specifying a data layer Epoch incorrectly only renders the last specified layer. We should handle this more gracefully. To reproduce use the following data for a basic line chart:
var data = [
{ values: [{x: 1, y: 1}, {x: 2, y: 2}] },
{ values: [{x: 1, y: 2}, {x: 2, y: 3}] }
];
Related to #18.
Implement basic and real-time step line charts for Epoch. For a good overview, see: http://peltiertech.com/WordPress/line-chart-vs-step-chart/
While the library plots everything it receives, that doesn't seem a good idea for real time plots. The easiest way to visualize that is by using the well known method of switching tabs. If during that time lots of new updates are received, the plot never catches up with the data that's actually new. So, is there some simple way to discard irrelevant data for realtime plots?
I'm using history size of 100, and queue size of 50 (if those matters for the issue).
The current read me is a little overwhelming. Pull the information out into a Github Pages site for the project and simplify the actual README.md
.
Expected Site Layout
Note: some of this content does not exist or will need major reformatting.
The chart is not currently taking the pixel ratio into account. Fix this.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.