progress indicators, bug fixes, after a while

This commit is contained in:
Kwesi Banson
2023-12-13 12:13:47 +00:00
parent ea6d83e5d9
commit bc97f69748
1283 changed files with 1010757 additions and 7379 deletions

1710
public/assets/vendors/Flot/docs/API.md vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,143 @@
## Writing plugins ##
All you need to do to make a new plugin is creating an init function
and a set of options (if needed), stuffing it into an object and
putting it in the $.plot.plugins array. For example:
```js
function myCoolPluginInit(plot) {
plot.coolstring = "Hello!";
};
$.plot.plugins.push({ init: myCoolPluginInit, options: { ... } });
// if $.plot is called, it will return a plot object with the
// attribute "coolstring"
```
Now, given that the plugin might run in many different places, it's
a good idea to avoid leaking names. The usual trick here is wrap the
above lines in an anonymous function which is called immediately, like
this: (function () { inner code ... })(). To make it even more robust
in case $ is not bound to jQuery but some other Javascript library, we
can write it as
```js
(function ($) {
// plugin definition
// ...
})(jQuery);
```
There's a complete example below, but you should also check out the
plugins bundled with Flot.
## Complete example ##
Here is a simple debug plugin which alerts each of the series in the
plot. It has a single option that control whether it is enabled and
how much info to output:
```js
(function ($) {
function init(plot) {
var debugLevel = 1;
function checkDebugEnabled(plot, options) {
if (options.debug) {
debugLevel = options.debug;
plot.hooks.processDatapoints.push(alertSeries);
}
}
function alertSeries(plot, series, datapoints) {
var msg = "series " + series.label;
if (debugLevel > 1) {
msg += " with " + series.data.length + " points";
alert(msg);
}
}
plot.hooks.processOptions.push(checkDebugEnabled);
}
var options = { debug: 0 };
$.plot.plugins.push({
init: init,
options: options,
name: "simpledebug",
version: "0.1"
});
})(jQuery);
```
We also define "name" and "version". It's not used by Flot, but might
be helpful for other plugins in resolving dependencies.
Put the above in a file named "jquery.flot.debug.js", include it in an
HTML page and then it can be used with:
```js
$.plot($("#placeholder"), [...], { debug: 2 });
```
This simple plugin illustrates a couple of points:
- It uses the anonymous function trick to avoid name pollution.
- It can be enabled/disabled through an option.
- Variables in the init function can be used to store plot-specific
state between the hooks.
The two last points are important because there may be multiple plots
on the same page, and you'd want to make sure they are not mixed up.
## Shutting down a plugin ##
Each plot object has a shutdown hook which is run when plot.shutdown()
is called. This usually mostly happens in case another plot is made on
top of an existing one.
The purpose of the hook is to give you a chance to unbind any event
handlers you've registered and remove any extra DOM things you've
inserted.
The problem with event handlers is that you can have registered a
handler which is run in some point in the future, e.g. with
setTimeout(). Meanwhile, the plot may have been shutdown and removed,
but because your event handler is still referencing it, it can't be
garbage collected yet, and worse, if your handler eventually runs, it
may overwrite stuff on a completely different plot.
## Some hints on the options ##
Plugins should always support appropriate options to enable/disable
them because the plugin user may have several plots on the same page
where only one should use the plugin. In most cases it's probably a
good idea if the plugin is turned off rather than on per default, just
like most of the powerful features in Flot.
If the plugin needs options that are specific to each series, like the
points or lines options in core Flot, you can put them in "series" in
the options object, e.g.
```js
var options = {
series: {
downsample: {
algorithm: null,
maxpoints: 1000
}
}
}
```
Then they will be copied by Flot into each series, providing default
values in case none are specified.
Think hard and long about naming the options. These names are going to
be public API, and code is going to depend on them if the plugin is
successful.

View File

@@ -0,0 +1,42 @@
## jquery.flot.absRelTime.js
This plugin is used to format the time axis in absolute time representation as
well as relative time representation.
It supports the following options:
```js
xaxis: {
timezone: null, // "browser" for local to the client or timezone for timezone-js
timeformat: null, // format string to use
twelveHourClock: false, // 12 or 24 time in time mode
monthNames: null // list of names of months
}
```
Depending upon the timeformat axis parameter value, the axis tick formatter will
choose between an absolute time representation if the value is '%A' or
relative time for timeformat '%r'.
If the format for an axis is 'time', inside processOptions hook the tickGenerator
and tickFormatter of the axis will be overrided with the custom ones used by time axes.
The formatted values look like in the example bellow:
|format|value(s)|formatted value(s)|
|------|----:|--------------:|
|Absolute time|0|12:00:00 AM 1/1/0001|
|Absolute time|300|12:05:00 AM 1/1/0001|
|Relative Time|0, 300, 600|00:00:00, 00:05:00, 00:10:00|
|Relative Time|300, 600, 900|00:00:00, 00:05:00, 00:10:00|
### Relative time axis
A relative time axis will show the time values with respect to the first data sample.
Basically, the first datapoint from the points array will be considered time 00:00:00:00.
If the difference between two datapoints is small, the milliseconds will apear.
Otherwise, the time representation will contain only the hour, minute and second.
### Absolute time axis
The absolute time representation contains, beside the hours, minutes and seconds
corresponding to the sample the date and year.
The value will be splitted on two rows, where the first row is the time and
the the second one the date in gregorian date format.

View File

@@ -0,0 +1,24 @@
## jquery.flot.browser.js
This plugin is used to make available some browser-related utility functions.
### Methods
- getPageXY(e)
Calculates the pageX and pageY using the screenX, screenY properties of the event
and the scrolling of the page. This is needed because the pageX and pageY
properties of the event are not correct while running tests in Edge.
- getPixelRatio(context)
This function returns the current pixel ratio defined by the product of desktop
zoom and page zoom.
Additional info: https://www.html5rocks.com/en/tutorials/canvas/hidpi/
- isSafari, isMobileSafari, isOpera, isFirefox, isIE, isEdge, isChrome, isBlink
This is a collection of functions, used to check if the code is running in a
particular browser or Javascript engine.

View File

@@ -0,0 +1,116 @@
## jquery.flot.canvaswrapper
This plugin contains the function for creating and manipulating both the canvas
layers and svg layers.
The Canvas object is a wrapper around an HTML5 canvas tag.
The constructor Canvas(cls, container) takes as parameters cls,
the list of classes to apply to the canvas adnd the containter,
element onto which to append the canvas. The canvas operations
don't work unless the canvas is attached to the DOM.
### jquery.canvaswrapper.js API functions
- resize(width, height)
Resizes the canvas to the given dimensions.
The width represents the new width of the canvas, meanwhile the height
is the new height of the canvas, both of them in pixels.
- clear()
Clears the entire canvas area, not including any overlaid HTML text
- render()
Finishes rendering the canvas, including managing the text overlay.
- getSVGLayer(classes)
Creates (if necessary) and returns the SVG overlay container.
The classes string represents the string of space-separated CSS classes
used to uniquely identify the text layer. It return the svg-layer div.
- getTextInfo(layer, text, font, angle, width)
Creates (if necessary) and returns a text info object.
The object looks like this:
```js
{
width //Width of the text's wrapper div.
height //Height of the text's wrapper div.
element //The HTML div containing the text.
positions //Array of positions at which this text is drawn.
}
```
The positions array contains objects that look like this:
```js
{
active //Flag indicating whether the text should be visible.
rendered //Flag indicating whether the text is currently visible.
element //The HTML div containing the text.
text //The actual text and is identical with element[0].textContent.
x //X coordinate at which to draw the text.
y //Y coordinate at which to draw the text.
}
```
Each position after the first receives a clone of the original element.
The idea is that that the width, height, and general 'identity' of the
text is constant no matter where it is placed; the placements are a
secondary property.
Canvas maintains a cache of recently-used text info objects; getTextInfo
either returns the cached element or creates a new entry.
The layer parameter is string of space-separated CSS classes uniquely
identifying the layer containing this text.
Text is the text string to retrieve info for.
Font is either a string of space-separated CSS classes or a font-spec object,
defining the text's font and style.
Angle is the angle at which to rotate the text, in degrees. Angle is currently unused,
it will be implemented in the future.
The last parameter is the Maximum width of the text before it wraps.
The method returns a text info object.
- addText (layer, x, y, text, font, angle, width, halign, valign, transforms)
Adds a text string to the canvas text overlay.
The text isn't drawn immediately; it is marked as rendering, which will
result in its addition to the canvas on the next render pass.
The layer is string of space-separated CSS classes uniquely
identifying the layer containing this text.
X and Y represents the X and Y coordinate at which to draw the text.
and text is the string to draw
- removeText (layer, x, y, text, font, angle)
The function removes one or more text strings from the canvas text overlay.
If no parameters are given, all text within the layer is removed.
Note that the text is not immediately removed; it is simply marked as
inactive, which will result in its removal on the next render pass.
This avoids the performance penalty for 'clear and redraw' behavior,
where we potentially get rid of all text on a layer, but will likely
add back most or all of it later, as when redrawing axes, for example.
The layer is a string of space-separated CSS classes uniquely
identifying the layer containing this text. The following parameter are
X and Y coordinate of the text.
Text is the string to remove, while the font is either a string of space-separated CSS
classes or a font-spec object, defining the text's font and style.
- clearCache()
Clears the cache used to speed up the text size measurements.
As an (unfortunate) side effect all text within the text Layer is removed.
Use this function before plot.setupGrid() and plot.draw() if the plot just
became visible or the styles changed.

View File

@@ -0,0 +1,32 @@
## jquery.flot.composeImages.js
This plugin is used to expose a function used to overlap several canvases and
SVGs, for the purpose of creating a snaphot out of them.
### When composeImages is used:
When multiple canvases and SVGs have to be overlapped into a single image
and their offset on the page, must be preserved.
### Where can be used:
In creating a downloadable snapshot of the plots, axes, cursors etc of a graph.
### How it works:
The entry point is composeImages function. It expects an array of objects,
which should be either canvases or SVGs (or a mix). It does a prevalidation
of them, by verifying if they will be usable or not, later in the flow.
After selecting only usable sources, it passes them to getGenerateTempImg
function, which generates temporary images out of them. This function
expects that some of the passed sources (canvas or SVG) may still have
problems being converted to an image and makes sure the promises system,
used by composeImages function, moves forward. As an example, SVGs with
missing information from header or with unsupported content, may lead to
failure in generating the temporary image. Temporary images are required
mostly on extracting content from SVGs, but this is also where the x/y
offsets are extracted for each image which will be added. For SVGs in
particular, their CSS rules have to be applied.
After all temporary images are generated, they are overlapped using
getExecuteImgComposition function. This is where the destination canvas
is set to the proper dimensions. It is then output by composeImages.
This function returns a promise, which can be used to wait for the whole
composition process. It requires to be asynchronous, because this is how
temporary images load their data.

View File

@@ -0,0 +1,35 @@
## jquery.flot.drawSeries.js
This plugin is used by flot for drawing lines, plots, bars or area.
### Public methods
- drawSeriesLines(series, ctx, plotOffset, plotWidth, plotHeight, drawSymbol, getColorOrGradient)
This function is used for drawing lines or area fill. In case the series has line decimation function
attached, before starting to draw, as an optimization the points will first be decimated.
The series parameter contains the series to be drawn on ctx context. The plotOffset, plotWidth and
plotHeight are the corresponding parameters of flot used to determine the drawing surface.
The function getColorOrGradient is used to compute the fill style of lines and area.
- drawSeriesPoints(series, ctx, plotOffset, plotWidth, plotHeight, drawSymbol, getColorOrGradient)
This function is used for drawing points using a given symbol. In case the series has points decimation
function attached, before starting to draw, as an optimization the points will first be decimated.
The series parameter contains the series to be drawn on ctx context. The plotOffset, plotWidth and
plotHeight are the corresponding parameters of flot used to determine the drawing surface.
The function drawSymbol is used to compute and draw the symbol chosen for the points.
- drawSeriesBars(series, ctx, plotOffset, plotWidth, plotHeight, drawSymbol, getColorOrGradient)
This function is used for drawing series represented as bars. In case the series has decimation
function attached, before starting to draw, as an optimization the points will first be decimated.
The series parameter contains the series to be drawn on ctx context. The plotOffset, plotWidth and
plotHeight are the corresponding parameters of flot used to determine the drawing surface.
The function getColorOrGradient is used to compute the fill style of bars.

View File

@@ -0,0 +1,21 @@
## jquery.flot.hover.js
This plugin is used for mouse hover and tap on a point of plot series.
It supports the following options:
```js
grid: {
hoverable: false, //to trigger plothover event on mouse hover or tap on a point
clickable: false //to trigger plotclick event on mouse hover
}
```
It listens to native mouse move event or click, as well as artificial generated
tap and touchevent.
When the mouse is over a point or a tap on a point is performed, that point or
the correscponding bar will be highlighted and a "plothover" event will be generated.
Custom "touchevent" is triggered when any touch interaction is made. Hover plugin
handles this events by unhighlighting all of the previously highlighted points and generates
"plothovercleanup" event to notify any part that is handling plothover (for exemple to cleanup
the tooltip from webcharts).

View File

@@ -0,0 +1,57 @@
# Interaction
Flot offers support for both mouse and touch interactions by using [navigate](navigate.md), [touch](../jquery.flot.touch.js)
and [touchNavigate](../jquery.flot.touchNavigate.js) plugins.
## navigate plugin
This plugin is adding ```zoom```, ```pan```, ```smartPan```, ```recenter``` and ```activate``` capabilities to flot.
It is listening for the following events:
* ```click```
* ```dblclick```
* ```dragstart```
* ```drag```
* ```dragend```
* ```mousewheel```
For pan, ```dragstart```, ```drag``` and ```dragend``` events are used which are triggered by the deprecated version 1.6 of ```jquery.event.drag.js```.
To perform a zoom operation, the mouse wheel can be used which is done by using ```mousewheel``` event generated by ```jquery.mousewheel.js``` version 3.0.6. These files are included inside lib folder and should be replaced by the npm latest releases of those packages.
The touch interactions are using only a part of the functionalities:
* ```zoom```
* ```pan```
* ```recenter```
* ```activate```
Any of the functions can be used by the mouse, touch or any other event handler.
## touch plugin
This plugin is responsible only for transforming the low level ```touchstart```, ```touchmove``` and ```touchend``` events into higher level events like:
* ```panstart```
* ```pandrag```
* ```panend```
* ```pinchstart```
* ```pinchdrag```
* ```pinchend```
* ```doubletap```
* ```longtap```
* ```tap```
This plugin is using the ```bindEvents``` hook of flot to add the event listenters for the low level events and, after interpreting them, will dispach the higher level events to the same event holder.
It's up to the other plugins to listen for these events and take any actions if necessary. Also they have the possibility to stop the propagation to prevent other plugins for handling the same event.
For example, the pan events are normally handled by the ```touchNavigate``` plugin, but in some cases the user might want to interact with other elements like cursors or markes which are on top of the plot.
In this case panning is not appropriate so other event handler specific to those elements should intercept these events first and stop their propagation before they get to the ```touchNavigate``` plugin.
Having a single place where the low level events are interpreted removes the burden of implementing the same logic in multiple places.
Some of the things this plugin is doing in order to extract the gestures or the user intentions:
* doesn't emit some pan or pinch events unless the user moved its finger(s) a minimum distance
* doesn't emit the double tap event unless both taps are near and fast enough
* deals with accidental multiple touches when panning
## touchNavigate plugin
Similar to the ```touch``` plugin, the ```touchNavigate``` is using the same ```bindEvents``` hook to add its own listeners to the event holder of the flot, but it will listen for the high level events only emitted by the ```touch``` plugin.
When a pan or pinch is started the plugin will determine what exactly is being "touched": the entire plot or just one of the axes.
After determining the element that the user wants to interact with then this plugin will call one of the ```zoom```, ```pan``` or ```recenter``` of the ```navigate``` plugin.

View File

@@ -0,0 +1,27 @@
## jquery.flot.logaxis
This plugin is used to create logarithmic axis. This includes tick generation,
formatters and transformers to and from logarithmic representation.
### Methods and hooks
- logTickGenerator(plot, axis, noTicks)
Generates logarithmic ticks, depending on axis range.
In case the number of ticks that can be generated is less than the expected noTicks/4,
a linear tick generation is used.
- logTickFormatter(value, axis, precision)
This is the corresponding tickFormatter of the logaxis.
For a number greater that 10^6 or smaller than 10^(-3), this will be drawn
with e representation
- setDataminRange(plot, axis)
It is used for clamping the starting point of a logarithmic axis.
This will set the axis datamin range to 0.1 or to the first datapoint greater then 0.
The function is usefull since the logarithmic representation can not show
values less than or equal to 0.

View File

@@ -0,0 +1,110 @@
## jquery.flot.navigate.js
This flot plugin is used for adding the ability to pan and zoom the plot.
A higher level overview is available at [interactions](interactions.md) documentation.
The default behaviour is scrollwheel up/down to zoom in, drag
to pan. The plugin defines plot.zoom({ center }), plot.zoomOut() and
plot.pan( offset ) so you easily can add custom controls. It also fires
"plotpan" and "plotzoom" events, useful for synchronizing plots.
The plugin supports these options:
```js
zoom: {
interactive: false,
active: false,
amount: 1.5, // 2 = 200% (zoom in), 0.5 = 50% (zoom out)
enableTouch: false
}
pan: {
interactive: false,
active: false,
cursor: "move", // CSS mouse cursor value used when dragging, e.g. "pointer"
frameRate: 60,
mode: "smart", // enable smart pan mode
enableTouch: false,
touchMode: ""
}
recenter: {
interactive: true,
enableTouch: true
}
propagateSupportedGesture: false,
xaxis: {
axisZoom: true, //zoom axis when mouse over it is allowed
plotZoom: true, //zoom axis is allowed for plot zoom
axisPan: true, //pan axis when mouse over it is allowed
plotPan: true //pan axis is allowed for plot pan
}
yaxis: {
axisZoom: true, //zoom axis when mouse over it is allowed
plotZoom: true, //zoom axis is allowed for plot zoom
axisPan: true, //pan axis when mouse over it is allowed
plotPan: true //pan axis is allowed for plot pan
}
```
**interactive** enables the built-in drag/click behaviour. If you enable
interactive for pan, then you'll have a basic plot that supports moving
around; the same for zoom and recenter.
**active** is true after a touch tap on plot. This enables plot navigation.
Once activated, zoom and pan cannot be deactivated. When the plot becomes active,
"plotactivated" event is triggered.
**amount** specifies the default amount to zoom in (so 1.5 = 150%) relative to
the current viewport.
**cursor** is a standard CSS mouse cursor string used for visual feedback to the
user when dragging.
**frameRate** specifies the maximum number of times per second the plot will
update itself while the user is panning around on it (set to null to disable
intermediate pans, the plot will then not update until the mouse button is
released).
**mode** a string specifies the pan mode for mouse interaction. Accepted values:
'manual': no pan hint or direction snapping;
'smart': The graph shows pan hint bar and the pan movement will snap
to one direction when the drag direction is close to it;
'smartLock'. The graph shows pan hint bar and the pan movement will always
snap to a direction that the drag diorection started with.
Default: 'smart'.
**enableTouch** enables the touch support, for pan (to drag), pinch (to zoom and move),
or double tap (to recenter).
**touchMode** a string specifies the pan mode of touch pan.
The accepted values is the sams as **mode** option. Default: 'manual'
**propagateSupportedGesture** set true to allow the propagation of origin touch events
(e.g. 'touchstart') that is already handled for pan or pinch. Default: false.
Example API usage:
```js
plot = $.plot(...);
// zoom default amount in on the pixel ( 10, 20 )
plot.zoom({ center: { left: 10, top: 20 } });
// zoom out again
plot.zoomOut({ center: { left: 10, top: 20 } });
// zoom 200% in on the pixel (10, 20)
plot.zoom({ amount: 2, center: { left: 10, top: 20 } });
// pan 100 pixels to the left and 20 down
plot.pan({ left: -100, top: 20 })
```
Here, "center" specifies where the center of the zooming should happen. Note
that this is defined in pixel space, not the space of the data points (you can
use the p2c helpers on the axes in Flot to help you convert between these).
**amount** is the amount to zoom the viewport relative to the current range, so
1 is 100% (i.e. no change), 1.5 is 150% (zoom in), 0.7 is 70% (zoom out). You
can set the default in the options.