Compare commits

...

5 commits

Author SHA1 Message Date
Egbert de Pauw
00952b89af
Merge 9bd1631103 into 364c776ff1 2024-10-21 10:05:59 +13:00
Michael Keller
364c776ff1 Export: Update jquery to a Secure Version.
Update jquery to a version that fixes known security vulnerabilities.
Triggered by https://github.com/subsurface/subsurface/security/dependabot/7

Signed-off-by: Michael Keller <github@ike.ch>
2024-10-21 09:25:19 +13:00
Egbert de Pauw
9bd1631103
Merge branch 'subsurface:master' into qt6devel 2024-08-28 15:40:29 +02:00
Egbertdepauw
7201a40c5f Removed some testing code.
There was an unneeded line in the code, just for my own testing
purposes.

Signed-off-by: Egbertdepauw <egbert@despaankamer.nl>
2024-08-27 14:51:39 +02:00
Egbertdepauw
c5e5535f51 qt6: Make subsurface buildable with Qt6 on Macos
Building on macos with the Qt6 framework.

made changes to several files to make it possible to build subsurface
desktop with the Qt 6.5.x and higher framework.

Tested versions: 6.5.2, 6.6.3, 6.7.2

code builds and googlemaps works, made some adjustments to get panning
and zooming with mouse or trackpad working.

See issue #3577 "Build Fails, macOS" for build details.

Signed-off-by: Egbertdepauw <egbert@despaankamer.nl>
2024-08-27 13:51:37 +02:00
15 changed files with 1250 additions and 523 deletions

View file

@ -160,6 +160,6 @@ void exportHtmlInitLogic(const QString &filename, struct htmlExportSetting &hes)
file_copy_and_overwrite(searchPath + "jqplot.canvasAxisTickRenderer.min.js", exportFiles + "jqplot.canvasAxisTickRenderer.min.js"); file_copy_and_overwrite(searchPath + "jqplot.canvasAxisTickRenderer.min.js", exportFiles + "jqplot.canvasAxisTickRenderer.min.js");
file_copy_and_overwrite(searchPath + "jqplot.canvasTextRenderer.min.js", exportFiles + "jqplot.canvasTextRenderer.min.js"); file_copy_and_overwrite(searchPath + "jqplot.canvasTextRenderer.min.js", exportFiles + "jqplot.canvasTextRenderer.min.js");
file_copy_and_overwrite(searchPath + "jquery.min.js", exportFiles + "jquery.min.js"); file_copy_and_overwrite(searchPath + "jquery.min.js", exportFiles + "jquery.min.js");
file_copy_and_overwrite(searchPath + "jquery.jqplot.css", exportFiles + "jquery.jqplot.css"); file_copy_and_overwrite(searchPath + "jquery.jqplot.min.css", exportFiles + "jquery.jqplot.min.css");
file_copy_and_overwrite(searchPath + hes.themeFile, exportFiles + "theme.css"); file_copy_and_overwrite(searchPath + hes.themeFile, exportFiles + "theme.css");
} }

View file

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
import QtQuick 2.5 import QtQuick
import QtLocation 5.3 import QtLocation
import QtPositioning 5.3 import QtPositioning
import org.subsurfacedivelog.mobile 1.0 import org.subsurfacedivelog.mobile 1.0
Item { Item {
@ -15,7 +15,7 @@ Item {
id: mapHelper id: mapHelper
map: map map: map
editMode: false editMode: false
onSelectedDivesChanged: rootItem.selectedDivesChanged(list) onSelectedDivesChanged: (list) => { rootItem.selectedDivesChanged(list) }
onEditModeChanged: editMessage.isVisible = editMode === true ? 1 : 0 onEditModeChanged: editMessage.isVisible = editMode === true ? 1 : 0
onCoordinatesChanged: {} onCoordinatesChanged: {}
Component.onCompleted: { Component.onCompleted: {
@ -29,7 +29,6 @@ Item {
id: map id: map
anchors.fill: parent anchors.fill: parent
zoomLevel: defaultZoomIn zoomLevel: defaultZoomIn
property var mapType property var mapType
readonly property var defaultCenter: QtPositioning.coordinate(0, 0) readonly property var defaultCenter: QtPositioning.coordinate(0, 0)
readonly property real defaultZoomIn: 12.0 readonly property real defaultZoomIn: 12.0
@ -41,12 +40,46 @@ Item {
property real newZoomOut: 1.0 property real newZoomOut: 1.0
property var clickCoord: QtPositioning.coordinate(0, 0) property var clickCoord: QtPositioning.coordinate(0, 0)
property bool isReady: false property bool isReady: false
Component.onCompleted: isReady = true Component.onCompleted: isReady = true
onZoomLevelChanged: { onZoomLevelChanged: {
if (isReady) if (isReady)
mapHelper.calculateSmallCircleRadius(map.center) mapHelper.calculateSmallCircleRadius(map.center)
} }
property geoCoordinate startCentroid
startCentroid: newCenter
PinchHandler {
id: pinch
target: null
onActiveChanged: if (active) {
map.startCentroid = map.toCoordinate(pinch.centroid.position, false)
}
onScaleChanged: (delta) => {
map.zoomLevel += Math.log2(delta)
map.alignCoordinateToPoint(map.startCentroid, pinch.centroid.position)
}
onRotationChanged: (delta) => {
map.bearing -= delta
map.alignCoordinateToPoint(map.startCentroid, pinch.centroid.position)
}
grabPermissions: PointerHandler.TakeOverForbidden
}
WheelHandler {
id: wheel
// workaround for QTBUG-87646 / QTBUG-112394 / QTBUG-112432:
// Magic Mouse pretends to be a trackpad but doesn't work with PinchHandler
// and we don't yet distinguish mice and trackpads on Wayland either
acceptedDevices: Qt.platform.pluginName === "cocoa" || Qt.platform.pluginName === "wayland"
? PointerDevice.Mouse | PointerDevice.TouchPad
: PointerDevice.Mouse
rotationScale: 1/120
property: "zoomLevel"
}
DragHandler {
id: drag
target: null
onTranslationChanged: (delta) => map.pan(-delta.x, -delta.y)
}
MapItemView { MapItemView {
id: mapItemView id: mapItemView
@ -67,7 +100,9 @@ Item {
} }
MouseArea { MouseArea {
drag.target: (mapHelper.editMode && model.isSelected) ? mapItem : undefined drag.target: (mapHelper.editMode && model.isSelected) ? mapItem : undefined
anchors.fill: parent anchors.fill: parent
hoverEnabled: true
onClicked: { onClicked: {
if (!mapHelper.editMode && model.divesite) if (!mapHelper.editMode && model.divesite)
mapHelper.selectedLocationChanged(model.divesite) mapHelper.selectedLocationChanged(model.divesite)
@ -122,8 +157,8 @@ Item {
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
onPressed: { map.stopZoomAnimations(); mouse.accepted = false } onPressed: (mouse) => { map.stopZoomAnimations(); mouse.accepted = false }
onWheel: { map.stopZoomAnimations(); wheel.accepted = false } onWheel: (wheel) => { map.stopZoomAnimations(); wheel.accepted = false }
onDoubleClicked: map.doubleClickHandler(map.toCoordinate(Qt.point(mouseX, mouseY))) onDoubleClicked: map.doubleClickHandler(map.toCoordinate(Qt.point(mouseX, mouseY)))
} }

View file

@ -4,20 +4,20 @@
#include <QDebug> #include <QDebug>
#include <QVector> #include <QVector>
#include "qmlmapwidgethelper.h"
#include "core/divefilter.h" #include "core/divefilter.h"
#include "core/divelist.h" #include "core/divelist.h"
#include "core/divelog.h" #include "core/divelog.h"
#include "core/divesite.h" #include "core/divesite.h"
#include "core/qthelper.h" #include "core/qthelper.h"
#include "core/range.h" #include "core/range.h"
#include "qt-models/maplocationmodel.h" #include "qmlmapwidgethelper.h"
#include "qt-models/divelocationmodel.h" #include "qt-models/divelocationmodel.h"
#include "qt-models/maplocationmodel.h"
#ifndef SUBSURFACE_MOBILE #ifndef SUBSURFACE_MOBILE
#include "desktop-widgets/mapwidget.h" #include "desktop-widgets/mapwidget.h"
#endif #endif
#define SMALL_CIRCLE_RADIUS_PX 26.0 #define SMALL_CIRCLE_RADIUS_PX 26.0
MapWidgetHelper::MapWidgetHelper(QObject *parent) : QObject(parent) MapWidgetHelper::MapWidgetHelper(QObject *parent) : QObject(parent)
{ {
@ -44,7 +44,7 @@ void MapWidgetHelper::centerOnDiveSite(struct dive_site *ds)
} else { } else {
// dive site with GPS // dive site with GPS
m_mapLocationModel->setSelected(ds); m_mapLocationModel->setSelected(ds);
QGeoCoordinate dsCoord (ds->location.lat.udeg * 0.000001, ds->location.lon.udeg * 0.000001); QGeoCoordinate dsCoord(ds->location.lat.udeg * 0.000001, ds->location.lon.udeg * 0.000001);
QMetaObject::invokeMethod(m_map, "centerOnCoordinate", Q_ARG(QVariant, QVariant::fromValue(dsCoord))); QMetaObject::invokeMethod(m_map, "centerOnCoordinate", Q_ARG(QVariant, QVariant::fromValue(dsCoord)));
} }
} }
@ -69,7 +69,7 @@ void MapWidgetHelper::centerOnSelectedDiveSite()
// find the most top-left and bottom-right dive sites on the map coordinate system. // find the most top-left and bottom-right dive sites on the map coordinate system.
qreal minLat = 0.0, minLon = 0.0, maxLat = 0.0, maxLon = 0.0; qreal minLat = 0.0, minLon = 0.0, maxLat = 0.0, maxLon = 0.0;
int count = 0; int count = 0;
for(struct dive_site *dss: selDS) { for (struct dive_site *dss : selDS) {
if (!has_location(&dss->location)) if (!has_location(&dss->location))
continue; continue;
qreal lat = dss->location.lat.udeg * 0.000001; qreal lat = dss->location.lat.udeg * 0.000001;
@ -92,7 +92,7 @@ void MapWidgetHelper::centerOnSelectedDiveSite()
// Pass coordinates to QML, either as a point or as a rectangle. // Pass coordinates to QML, either as a point or as a rectangle.
// If we didn't find any coordinates, do nothing. // If we didn't find any coordinates, do nothing.
if (count == 1) { if (count == 1) {
QGeoCoordinate dsCoord (selDS[0]->location.lat.udeg * 0.000001, selDS[0]->location.lon.udeg * 0.000001); QGeoCoordinate dsCoord(selDS[0]->location.lat.udeg * 0.000001, selDS[0]->location.lon.udeg * 0.000001);
QMetaObject::invokeMethod(m_map, "centerOnCoordinate", Q_ARG(QVariant, QVariant::fromValue(dsCoord))); QMetaObject::invokeMethod(m_map, "centerOnCoordinate", Q_ARG(QVariant, QVariant::fromValue(dsCoord)));
} else if (count > 1) { } else if (count > 1) {
QGeoCoordinate coordTopLeft(minLat, minLon); QGeoCoordinate coordTopLeft(minLat, minLon);
@ -134,7 +134,7 @@ void MapWidgetHelper::selectedLocationChanged(struct dive_site *ds_in)
return; return;
QGeoCoordinate locationCoord = location->coordinate; QGeoCoordinate locationCoord = location->coordinate;
for (auto [idx, dive]: enumerated_range(divelog.dives)) { for (auto [idx, dive] : enumerated_range(divelog.dives)) {
struct dive_site *ds = dive->dive_site; struct dive_site *ds = dive->dive_site;
if (!ds || !ds->has_gps_location()) if (!ds || !ds->has_gps_location())
continue; continue;
@ -151,9 +151,9 @@ void MapWidgetHelper::selectedLocationChanged(struct dive_site *ds_in)
} }
int last; // get latest dive chronologically int last; // get latest dive chronologically
if (!selectedDiveIds.isEmpty()) { if (!selectedDiveIds.isEmpty()) {
last = selectedDiveIds.last(); last = selectedDiveIds.last();
selectedDiveIds.clear(); selectedDiveIds.clear();
selectedDiveIds.append(last); selectedDiveIds.append(last);
} }
#endif #endif
emit selectedDivesChanged(selectedDiveIds); emit selectedDivesChanged(selectedDiveIds);
@ -162,7 +162,7 @@ void MapWidgetHelper::selectedLocationChanged(struct dive_site *ds_in)
void MapWidgetHelper::selectVisibleLocations() void MapWidgetHelper::selectVisibleLocations()
{ {
QList<int> selectedDiveIds; QList<int> selectedDiveIds;
for (auto [idx, dive]: enumerated_range(divelog.dives)) { for (auto [idx, dive] : enumerated_range(divelog.dives)) {
struct dive_site *ds = dive->dive_site; struct dive_site *ds = dive->dive_site;
if (!ds || ds->has_gps_location()) if (!ds || ds->has_gps_location())
continue; continue;
@ -171,7 +171,7 @@ void MapWidgetHelper::selectVisibleLocations()
QGeoCoordinate dsCoord(latitude, longitude); QGeoCoordinate dsCoord(latitude, longitude);
QPointF point; QPointF point;
QMetaObject::invokeMethod(m_map, "fromCoordinate", Q_RETURN_ARG(QPointF, point), QMetaObject::invokeMethod(m_map, "fromCoordinate", Q_RETURN_ARG(QPointF, point),
Q_ARG(QGeoCoordinate, dsCoord)); Q_ARG(QGeoCoordinate, dsCoord));
if (!qIsNaN(point.x())) if (!qIsNaN(point.x()))
#ifndef SUBSURFACE_MOBILE // indices on desktop #ifndef SUBSURFACE_MOBILE // indices on desktop
selectedDiveIds.append(idx); selectedDiveIds.append(idx);
@ -181,9 +181,9 @@ void MapWidgetHelper::selectVisibleLocations()
} }
int last; // get latest dive chronologically int last; // get latest dive chronologically
if (!selectedDiveIds.isEmpty()) { if (!selectedDiveIds.isEmpty()) {
last = selectedDiveIds.last(); last = selectedDiveIds.last();
selectedDiveIds.clear(); selectedDiveIds.clear();
selectedDiveIds.append(last); selectedDiveIds.append(last);
} }
#endif #endif
emit selectedDivesChanged(selectedDiveIds); emit selectedDivesChanged(selectedDiveIds);
@ -205,11 +205,11 @@ void MapWidgetHelper::calculateSmallCircleRadius(QGeoCoordinate coord)
{ {
QPointF point; QPointF point;
QMetaObject::invokeMethod(m_map, "fromCoordinate", Q_RETURN_ARG(QPointF, point), QMetaObject::invokeMethod(m_map, "fromCoordinate", Q_RETURN_ARG(QPointF, point),
Q_ARG(QGeoCoordinate, coord)); Q_ARG(QGeoCoordinate, coord));
QPointF point2(point.x() + SMALL_CIRCLE_RADIUS_PX, point.y()); QPointF point2(point.x() + SMALL_CIRCLE_RADIUS_PX, point.y());
QGeoCoordinate coord2; QGeoCoordinate coord2;
QMetaObject::invokeMethod(m_map, "toCoordinate", Q_RETURN_ARG(QGeoCoordinate, coord2), QMetaObject::invokeMethod(m_map, "toCoordinate", Q_RETURN_ARG(QGeoCoordinate, coord2),
Q_ARG(QPointF, point2)); Q_ARG(QPointF, point2));
m_smallCircleRadius = coord2.distanceTo(coord); m_smallCircleRadius = coord2.distanceTo(coord);
} }
@ -251,8 +251,8 @@ QString MapWidgetHelper::pluginObject()
{ {
QString lang = getUiLanguage().replace('_', '-'); QString lang = getUiLanguage().replace('_', '-');
QString cacheFolder = QString::fromStdString(system_default_directory() + "/googlemaps").replace("\\", "/"); QString cacheFolder = QString::fromStdString(system_default_directory() + "/googlemaps").replace("\\", "/");
return QStringLiteral("import QtQuick 2.0;" return QStringLiteral("import QtQuick;"
"import QtLocation 5.3;" "import QtLocation;"
"Plugin {" "Plugin {"
" id: mapPlugin;" " id: mapPlugin;"
" name: 'googlemaps';" " name: 'googlemaps';"
@ -263,5 +263,6 @@ QString MapWidgetHelper::pluginObject()
" console.warn('MapWidget.qml: cannot find a plugin named: ' + name);" " console.warn('MapWidget.qml: cannot find a plugin named: ' + name);"
" }" " }"
" }" " }"
"}").arg(lang, cacheFolder); "}")
.arg(lang, cacheFolder);
} }

View file

@ -169,8 +169,9 @@ for package in "${PACKAGES[@]}" ; do
git_checkout_library breeze-icons $CURRENT_BREEZE_ICONS https://github.com/kde/breeze-icons.git git_checkout_library breeze-icons $CURRENT_BREEZE_ICONS https://github.com/kde/breeze-icons.git
;; ;;
googlemaps) googlemaps)
git_checkout_library googlemaps master https://github.com/Subsurface/googlemaps.git #git_checkout_library googlemaps master https://github.com/Subsurface/googlemaps.git
;; git_checkout_library googlemaps master https://github.com/vladest/googlemaps.git
;;
hidapi) hidapi)
git_checkout_library hidapi master https://github.com/libusb/hidapi.git git_checkout_library hidapi master https://github.com/libusb/hidapi.git
;; ;;

View file

@ -27,7 +27,7 @@ function load_scripts()
fileref=document.createElement("link"); fileref=document.createElement("link");
fileref.setAttribute("rel", "stylesheet"); fileref.setAttribute("rel", "stylesheet");
fileref.setAttribute("type", "text/css"); fileref.setAttribute("type", "text/css");
fileref.setAttribute("href", location.pathname + "_files/jquery.jqplot.css"); fileref.setAttribute("href", location.pathname + "_files/jquery.jqplot.min.css");
document.getElementsByTagName("head")[0].appendChild(fileref); document.getElementsByTagName("head")[0].appendChild(fileref);
fileref=document.createElement('script'); fileref=document.createElement('script');

View file

@ -0,0 +1,253 @@
/**
* jqPlot
* Pure JavaScript plotting plugin using jQuery
*
* Version: 1.0.9
* Revision: d96a669
*
* Copyright (c) 2009-2016 Chris Leonello
* jqPlot is currently available for use in all personal or commercial projects
* under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
* version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
* choose the license that best suits your project and use it accordingly.
*
* Although not required, the author would appreciate an email letting him
* know of any substantial use of jqPlot. You can reach the author at:
* chris at jqplot dot com or see http://www.jqplot.com/info.php .
*
* If you are feeling kind and generous, consider supporting the project by
* making a donation at: http://www.jqplot.com/donate.php .
*
* sprintf functions contained in jqplot.sprintf.js by Ash Searle:
*
* version 2007.04.27
* author Ash Searle
* http://hexmen.com/blog/2007/03/printf-sprintf/
* http://hexmen.com/js/sprintf.js
* The author (Ash Searle) has placed this code in the public domain:
* "This code is unrestricted: you are free to use it however you like."
*
*/
(function($) {
/**
* Class: $.jqplot.CanvasAxisTickRenderer
* Renderer to draw axis ticks with a canvas element to support advanced
* featrues such as rotated text. This renderer uses a separate rendering engine
* to draw the text on the canvas. Two modes of rendering the text are available.
* If the browser has native font support for canvas fonts (currently Mozila 3.5
* and Safari 4), you can enable text rendering with the canvas fillText method.
* You do so by setting the "enableFontSupport" option to true.
*
* Browsers lacking native font support will have the text drawn on the canvas
* using the Hershey font metrics. Even if the "enableFontSupport" option is true
* non-supporting browsers will still render with the Hershey font.
*/
$.jqplot.CanvasAxisTickRenderer = function(options) {
// Group: Properties
// prop: mark
// tick mark on the axis. One of 'inside', 'outside', 'cross', '' or null.
this.mark = 'outside';
// prop: showMark
// whether or not to show the mark on the axis.
this.showMark = true;
// prop: showGridline
// whether or not to draw the gridline on the grid at this tick.
this.showGridline = true;
// prop: isMinorTick
// if this is a minor tick.
this.isMinorTick = false;
// prop: angle
// angle of text, measured clockwise from x axis.
this.angle = 0;
// prop: markSize
// Length of the tick marks in pixels. For 'cross' style, length
// will be stoked above and below axis, so total length will be twice this.
this.markSize = 4;
// prop: show
// whether or not to show the tick (mark and label).
this.show = true;
// prop: showLabel
// whether or not to show the label.
this.showLabel = true;
// prop: labelPosition
// 'auto', 'start', 'middle' or 'end'.
// Whether tick label should be positioned so the start, middle, or end
// of the tick mark.
this.labelPosition = 'auto';
this.label = '';
this.value = null;
this._styles = {};
// prop: formatter
// A class of a formatter for the tick text.
// The default $.jqplot.DefaultTickFormatter uses sprintf.
this.formatter = $.jqplot.DefaultTickFormatter;
// prop: formatString
// string passed to the formatter.
this.formatString = '';
// prop: prefix
// String to prepend to the tick label.
// Prefix is prepended to the formatted tick label.
this.prefix = '';
// prop: fontFamily
// css spec for the font-family css attribute.
this.fontFamily = '"Trebuchet MS", Arial, Helvetica, sans-serif';
// prop: fontSize
// CSS spec for font size.
this.fontSize = '10pt';
// prop: fontWeight
// CSS spec for fontWeight
this.fontWeight = 'normal';
// prop: fontStretch
// Multiplier to condense or expand font width.
// Applies only to browsers which don't support canvas native font rendering.
this.fontStretch = 1.0;
// prop: textColor
// css spec for the color attribute.
this.textColor = '#666666';
// prop: enableFontSupport
// true to turn on native canvas font support in Mozilla 3.5+ and Safari 4+.
// If true, tick label will be drawn with canvas tag native support for fonts.
// If false, tick label will be drawn with Hershey font metrics.
this.enableFontSupport = true;
// prop: pt2px
// Point to pixel scaling factor, used for computing height of bounding box
// around a label. The labels text renderer has a default setting of 1.4, which
// should be suitable for most fonts. Leave as null to use default. If tops of
// letters appear clipped, increase this. If bounding box seems too big, decrease.
// This is an issue only with the native font renderering capabilities of Mozilla
// 3.5 and Safari 4 since they do not provide a method to determine the font height.
this.pt2px = null;
this._elem;
this._ctx;
this._plotWidth;
this._plotHeight;
this._plotDimensions = {height:null, width:null};
$.extend(true, this, options);
var ropts = {fontSize:this.fontSize, fontWeight:this.fontWeight, fontStretch:this.fontStretch, fillStyle:this.textColor, angle:this.getAngleRad(), fontFamily:this.fontFamily};
if (this.pt2px) {
ropts.pt2px = this.pt2px;
}
if (this.enableFontSupport) {
if ($.jqplot.support_canvas_text()) {
this._textRenderer = new $.jqplot.CanvasFontRenderer(ropts);
}
else {
this._textRenderer = new $.jqplot.CanvasTextRenderer(ropts);
}
}
else {
this._textRenderer = new $.jqplot.CanvasTextRenderer(ropts);
}
};
$.jqplot.CanvasAxisTickRenderer.prototype.init = function(options) {
$.extend(true, this, options);
this._textRenderer.init({fontSize:this.fontSize, fontWeight:this.fontWeight, fontStretch:this.fontStretch, fillStyle:this.textColor, angle:this.getAngleRad(), fontFamily:this.fontFamily});
};
// return width along the x axis
// will check first to see if an element exists.
// if not, will return the computed text box width.
$.jqplot.CanvasAxisTickRenderer.prototype.getWidth = function(ctx) {
if (this._elem) {
return this._elem.outerWidth(true);
}
else {
var tr = this._textRenderer;
var l = tr.getWidth(ctx);
var h = tr.getHeight(ctx);
var w = Math.abs(Math.sin(tr.angle)*h) + Math.abs(Math.cos(tr.angle)*l);
return w;
}
};
// return height along the y axis.
$.jqplot.CanvasAxisTickRenderer.prototype.getHeight = function(ctx) {
if (this._elem) {
return this._elem.outerHeight(true);
}
else {
var tr = this._textRenderer;
var l = tr.getWidth(ctx);
var h = tr.getHeight(ctx);
var w = Math.abs(Math.cos(tr.angle)*h) + Math.abs(Math.sin(tr.angle)*l);
return w;
}
};
// return top.
$.jqplot.CanvasAxisTickRenderer.prototype.getTop = function(ctx) {
if (this._elem) {
return this._elem.position().top;
}
else {
return null;
}
};
$.jqplot.CanvasAxisTickRenderer.prototype.getAngleRad = function() {
var a = this.angle * Math.PI/180;
return a;
};
$.jqplot.CanvasAxisTickRenderer.prototype.setTick = function(value, axisName, isMinor) {
this.value = value;
if (isMinor) {
this.isMinorTick = true;
}
return this;
};
$.jqplot.CanvasAxisTickRenderer.prototype.draw = function(ctx, plot) {
if (!this.label) {
this.label = this.prefix + this.formatter(this.formatString, this.value);
}
// Memory Leaks patch
if (this._elem) {
if ($.jqplot.use_excanvas && window.G_vmlCanvasManager.uninitElement !== undefined) {
window.G_vmlCanvasManager.uninitElement(this._elem.get(0));
}
this._elem.emptyForce();
this._elem = null;
}
// create a canvas here, but can't draw on it untill it is appended
// to dom for IE compatability.
var elem = plot.canvasManager.getCanvas();
this._textRenderer.setText(this.label, ctx);
var w = this.getWidth(ctx);
var h = this.getHeight(ctx);
// canvases seem to need to have width and heigh attributes directly set.
elem.width = w;
elem.height = h;
elem.style.width = w;
elem.style.height = h;
elem.style.textAlign = 'left';
elem.style.position = 'absolute';
elem = plot.canvasManager.initCanvas(elem);
this._elem = $(elem);
this._elem.css(this._styles);
this._elem.addClass('jqplot-'+this.axis+'-tick');
elem = null;
return this._elem;
};
$.jqplot.CanvasAxisTickRenderer.prototype.pack = function() {
this._textRenderer.draw(this._elem.get(0).getContext("2d"), this.label);
};
})(jQuery);

View file

@ -1,57 +0,0 @@
/**
* jqPlot
* Pure JavaScript plotting plugin using jQuery
*
* Version: 1.0.0r1095
*
* Copyright (c) 2009-2011 Chris Leonello
* jqPlot is currently available for use in all personal or commercial projects
* under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
* version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
* choose the license that best suits your project and use it accordingly.
*
* Although not required, the author would appreciate an email letting him
* know of any substantial use of jqPlot. You can reach the author at:
* chris at jqplot dot com or see http://www.jqplot.com/info.php .
*
* If you are feeling kind and generous, consider supporting the project by
* making a donation at: http://www.jqplot.com/donate.php .
*
* sprintf functions contained in jqplot.sprintf.js by Ash Searle:
*
* version 2007.04.27
* author Ash Searle
* http://hexmen.com/blog/2007/03/printf-sprintf/
* http://hexmen.com/js/sprintf.js
* The author (Ash Searle) has placed this code in the public domain:
* "This code is unrestricted: you are free to use it however you like."
*
* included jsDate library by Chris Leonello:
*
* Copyright (c) 2010-2011 Chris Leonello
*
* jsDate is currently available for use in all personal or commercial projects
* under both the MIT and GPL version 2.0 licenses. This means that you can
* choose the license that best suits your project and use it accordingly.
*
* jsDate borrows many concepts and ideas from the Date Instance
* Methods by Ken Snyder along with some parts of Ken's actual code.
*
* Ken's origianl Date Instance Methods and copyright notice:
*
* Ken Snyder (ken d snyder at gmail dot com)
* 2008-09-10
* version 2.0.2 (http://kendsnyder.com/sandbox/date/)
* Creative Commons Attribution License 3.0 (http://creativecommons.org/licenses/by/3.0/)
*
* jqplotToImage function based on Larry Siden's export-jqplot-to-png.js.
* Larry has generously given permission to adapt his code for inclusion
* into jqPlot.
*
* Larry's original code can be found here:
*
* https://github.com/lsiden/export-jqplot-to-png
*
*
*/
(function(a){a.jqplot.CanvasAxisTickRenderer=function(b){this.mark="outside";this.showMark=true;this.showGridline=true;this.isMinorTick=false;this.angle=0;this.markSize=4;this.show=true;this.showLabel=true;this.labelPosition="auto";this.label="";this.value=null;this._styles={};this.formatter=a.jqplot.DefaultTickFormatter;this.formatString="";this.prefix="";this.fontFamily='"Trebuchet MS", Arial, Helvetica, sans-serif';this.fontSize="10pt";this.fontWeight="normal";this.fontStretch=1;this.textColor="#666666";this.enableFontSupport=true;this.pt2px=null;this._elem;this._ctx;this._plotWidth;this._plotHeight;this._plotDimensions={height:null,width:null};a.extend(true,this,b);var c={fontSize:this.fontSize,fontWeight:this.fontWeight,fontStretch:this.fontStretch,fillStyle:this.textColor,angle:this.getAngleRad(),fontFamily:this.fontFamily};if(this.pt2px){c.pt2px=this.pt2px}if(this.enableFontSupport){if(a.jqplot.support_canvas_text()){this._textRenderer=new a.jqplot.CanvasFontRenderer(c)}else{this._textRenderer=new a.jqplot.CanvasTextRenderer(c)}}else{this._textRenderer=new a.jqplot.CanvasTextRenderer(c)}};a.jqplot.CanvasAxisTickRenderer.prototype.init=function(b){a.extend(true,this,b);this._textRenderer.init({fontSize:this.fontSize,fontWeight:this.fontWeight,fontStretch:this.fontStretch,fillStyle:this.textColor,angle:this.getAngleRad(),fontFamily:this.fontFamily})};a.jqplot.CanvasAxisTickRenderer.prototype.getWidth=function(d){if(this._elem){return this._elem.outerWidth(true)}else{var f=this._textRenderer;var c=f.getWidth(d);var e=f.getHeight(d);var b=Math.abs(Math.sin(f.angle)*e)+Math.abs(Math.cos(f.angle)*c);return b}};a.jqplot.CanvasAxisTickRenderer.prototype.getHeight=function(d){if(this._elem){return this._elem.outerHeight(true)}else{var f=this._textRenderer;var c=f.getWidth(d);var e=f.getHeight(d);var b=Math.abs(Math.cos(f.angle)*e)+Math.abs(Math.sin(f.angle)*c);return b}};a.jqplot.CanvasAxisTickRenderer.prototype.getAngleRad=function(){var b=this.angle*Math.PI/180;return b};a.jqplot.CanvasAxisTickRenderer.prototype.setTick=function(b,d,c){this.value=b;if(c){this.isMinorTick=true}return this};a.jqplot.CanvasAxisTickRenderer.prototype.draw=function(c,f){if(!this.label){this.label=this.prefix+this.formatter(this.formatString,this.value)}if(this._elem){if(a.jqplot.use_excanvas&&window.G_vmlCanvasManager.uninitElement!==undefined){window.G_vmlCanvasManager.uninitElement(this._elem.get(0))}this._elem.emptyForce();this._elem=null}var e=f.canvasManager.getCanvas();this._textRenderer.setText(this.label,c);var b=this.getWidth(c);var d=this.getHeight(c);e.width=b;e.height=d;e.style.width=b;e.style.height=d;e.style.textAlign="left";e.style.position="absolute";e=f.canvasManager.initCanvas(e);this._elem=a(e);this._elem.css(this._styles);this._elem.addClass("jqplot-"+this.axis+"-tick");e=null;return this._elem};a.jqplot.CanvasAxisTickRenderer.prototype.pack=function(){this._textRenderer.draw(this._elem.get(0).getContext("2d"),this.label)}})(jQuery);

View file

@ -0,0 +1,449 @@
/**
* jqPlot
* Pure JavaScript plotting plugin using jQuery
*
* Version: 1.0.9
* Revision: d96a669
*
* Copyright (c) 2009-2016 Chris Leonello
* jqPlot is currently available for use in all personal or commercial projects
* under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
* version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
* choose the license that best suits your project and use it accordingly.
*
* Although not required, the author would appreciate an email letting him
* know of any substantial use of jqPlot. You can reach the author at:
* chris at jqplot dot com or see http://www.jqplot.com/info.php .
*
* If you are feeling kind and generous, consider supporting the project by
* making a donation at: http://www.jqplot.com/donate.php .
*
* sprintf functions contained in jqplot.sprintf.js by Ash Searle:
*
* version 2007.04.27
* author Ash Searle
* http://hexmen.com/blog/2007/03/printf-sprintf/
* http://hexmen.com/js/sprintf.js
* The author (Ash Searle) has placed this code in the public domain:
* "This code is unrestricted: you are free to use it however you like."
*
* included jsDate library by Chris Leonello:
*
* Copyright (c) 2010-2015 Chris Leonello
*
* jsDate is currently available for use in all personal or commercial projects
* under both the MIT and GPL version 2.0 licenses. This means that you can
* choose the license that best suits your project and use it accordingly.
*
* jsDate borrows many concepts and ideas from the Date Instance
* Methods by Ken Snyder along with some parts of Ken's actual code.
*
* Ken's original Date Instance Methods and copyright notice:
*
* Ken Snyder (ken d snyder at gmail dot com)
* 2008-09-10
* version 2.0.2 (http://kendsnyder.com/sandbox/date/)
* Creative Commons Attribution License 3.0 (http://creativecommons.org/licenses/by/3.0/)
*
* jqplotToImage function based on Larry Siden's export-jqplot-to-png.js.
* Larry has generously given permission to adapt his code for inclusion
* into jqPlot.
*
* Larry's original code can be found here:
*
* https://github.com/lsiden/export-jqplot-to-png
*
*
*/
(function($) {
// This code is a modified version of the canvastext.js code, copyright below:
//
// This code is released to the public domain by Jim Studt, 2007.
// He may keep some sort of up to date copy at http://www.federated.com/~jim/canvastext/
//
$.jqplot.CanvasTextRenderer = function(options){
this.fontStyle = 'normal'; // normal, italic, oblique [not implemented]
this.fontVariant = 'normal'; // normal, small caps [not implemented]
this.fontWeight = 'normal'; // normal, bold, bolder, lighter, 100 - 900
this.fontSize = '10px';
this.fontFamily = 'sans-serif';
this.fontStretch = 1.0;
this.fillStyle = '#666666';
this.angle = 0;
this.textAlign = 'start';
this.textBaseline = 'alphabetic';
this.text;
this.width;
this.height;
this.pt2px = 1.28;
$.extend(true, this, options);
this.normalizedFontSize = this.normalizeFontSize(this.fontSize);
this.setHeight();
};
$.jqplot.CanvasTextRenderer.prototype.init = function(options) {
$.extend(true, this, options);
this.normalizedFontSize = this.normalizeFontSize(this.fontSize);
this.setHeight();
};
// convert css spec into point size
// returns float
$.jqplot.CanvasTextRenderer.prototype.normalizeFontSize = function(sz) {
sz = String(sz);
var n = parseFloat(sz);
if (sz.indexOf('px') > -1) {
return n/this.pt2px;
}
else if (sz.indexOf('pt') > -1) {
return n;
}
else if (sz.indexOf('em') > -1) {
return n*12;
}
else if (sz.indexOf('%') > -1) {
return n*12/100;
}
// default to pixels;
else {
return n/this.pt2px;
}
};
$.jqplot.CanvasTextRenderer.prototype.fontWeight2Float = function(w) {
// w = normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900
// return values adjusted for Hershey font.
if (Number(w)) {
return w/400;
}
else {
switch (w) {
case 'normal':
return 1;
break;
case 'bold':
return 1.75;
break;
case 'bolder':
return 2.25;
break;
case 'lighter':
return 0.75;
break;
default:
return 1;
break;
}
}
};
$.jqplot.CanvasTextRenderer.prototype.getText = function() {
return this.text;
};
$.jqplot.CanvasTextRenderer.prototype.setText = function(t, ctx) {
this.text = t;
this.setWidth(ctx);
return this;
};
$.jqplot.CanvasTextRenderer.prototype.getWidth = function(ctx) {
return this.width;
};
$.jqplot.CanvasTextRenderer.prototype.setWidth = function(ctx, w) {
if (!w) {
this.width = this.measure(ctx, this.text);
}
else {
this.width = w;
}
return this;
};
// return height in pixels.
$.jqplot.CanvasTextRenderer.prototype.getHeight = function(ctx) {
return this.height;
};
// w - height in pt
// set heigh in px
$.jqplot.CanvasTextRenderer.prototype.setHeight = function(w) {
if (!w) {
//height = this.fontSize /0.75;
this.height = this.normalizedFontSize * this.pt2px;
}
else {
this.height = w;
}
return this;
};
$.jqplot.CanvasTextRenderer.prototype.letter = function (ch)
{
return this.letters[ch];
};
$.jqplot.CanvasTextRenderer.prototype.ascent = function()
{
return this.normalizedFontSize;
};
$.jqplot.CanvasTextRenderer.prototype.descent = function()
{
return 7.0*this.normalizedFontSize/25.0;
};
$.jqplot.CanvasTextRenderer.prototype.measure = function(ctx, str)
{
var total = 0;
var len = str.length;
for (var i = 0; i < len; i++) {
var c = this.letter(str.charAt(i));
if (c) {
total += c.width * this.normalizedFontSize / 25.0 * this.fontStretch;
}
}
return total;
};
$.jqplot.CanvasTextRenderer.prototype.draw = function(ctx,str)
{
var x = 0;
// leave room at bottom for descenders.
var y = this.height*0.72;
var total = 0;
var len = str.length;
var mag = this.normalizedFontSize / 25.0;
ctx.save();
var tx, ty;
// 1st quadrant
if ((-Math.PI/2 <= this.angle && this.angle <= 0) || (Math.PI*3/2 <= this.angle && this.angle <= Math.PI*2)) {
tx = 0;
ty = -Math.sin(this.angle) * this.width;
}
// 4th quadrant
else if ((0 < this.angle && this.angle <= Math.PI/2) || (-Math.PI*2 <= this.angle && this.angle <= -Math.PI*3/2)) {
tx = Math.sin(this.angle) * this.height;
ty = 0;
}
// 2nd quadrant
else if ((-Math.PI < this.angle && this.angle < -Math.PI/2) || (Math.PI <= this.angle && this.angle <= Math.PI*3/2)) {
tx = -Math.cos(this.angle) * this.width;
ty = -Math.sin(this.angle) * this.width - Math.cos(this.angle) * this.height;
}
// 3rd quadrant
else if ((-Math.PI*3/2 < this.angle && this.angle < Math.PI) || (Math.PI/2 < this.angle && this.angle < Math.PI)) {
tx = Math.sin(this.angle) * this.height - Math.cos(this.angle)*this.width;
ty = -Math.cos(this.angle) * this.height;
}
ctx.strokeStyle = this.fillStyle;
ctx.fillStyle = this.fillStyle;
ctx.translate(tx, ty);
ctx.rotate(this.angle);
ctx.lineCap = "round";
// multiplier was 2.0
var fact = (this.normalizedFontSize > 30) ? 2.0 : 2 + (30 - this.normalizedFontSize)/20;
ctx.lineWidth = fact * mag * this.fontWeight2Float(this.fontWeight);
for ( var i = 0; i < len; i++) {
var c = this.letter( str.charAt(i));
if ( !c) {
continue;
}
ctx.beginPath();
var penUp = 1;
var needStroke = 0;
for ( var j = 0; j < c.points.length; j++) {
var a = c.points[j];
if ( a[0] == -1 && a[1] == -1) {
penUp = 1;
continue;
}
if ( penUp) {
ctx.moveTo( x + a[0]*mag*this.fontStretch, y - a[1]*mag);
penUp = false;
} else {
ctx.lineTo( x + a[0]*mag*this.fontStretch, y - a[1]*mag);
}
}
ctx.stroke();
x += c.width*mag*this.fontStretch;
}
ctx.restore();
return total;
};
$.jqplot.CanvasTextRenderer.prototype.letters = {
' ': { width: 16, points: [] },
'!': { width: 10, points: [[5,21],[5,7],[-1,-1],[5,2],[4,1],[5,0],[6,1],[5,2]] },
'"': { width: 16, points: [[4,21],[4,14],[-1,-1],[12,21],[12,14]] },
'#': { width: 21, points: [[11,25],[4,-7],[-1,-1],[17,25],[10,-7],[-1,-1],[4,12],[18,12],[-1,-1],[3,6],[17,6]] },
'$': { width: 20, points: [[8,25],[8,-4],[-1,-1],[12,25],[12,-4],[-1,-1],[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]] },
'%': { width: 24, points: [[21,21],[3,0],[-1,-1],[8,21],[10,19],[10,17],[9,15],[7,14],[5,14],[3,16],[3,18],[4,20],[6,21],[8,21],[10,20],[13,19],[16,19],[19,20],[21,21],[-1,-1],[17,7],[15,6],[14,4],[14,2],[16,0],[18,0],[20,1],[21,3],[21,5],[19,7],[17,7]] },
'&': { width: 26, points: [[23,12],[23,13],[22,14],[21,14],[20,13],[19,11],[17,6],[15,3],[13,1],[11,0],[7,0],[5,1],[4,2],[3,4],[3,6],[4,8],[5,9],[12,13],[13,14],[14,16],[14,18],[13,20],[11,21],[9,20],[8,18],[8,16],[9,13],[11,10],[16,3],[18,1],[20,0],[22,0],[23,1],[23,2]] },
'\'': { width: 10, points: [[5,19],[4,20],[5,21],[6,20],[6,18],[5,16],[4,15]] },
'(': { width: 14, points: [[11,25],[9,23],[7,20],[5,16],[4,11],[4,7],[5,2],[7,-2],[9,-5],[11,-7]] },
')': { width: 14, points: [[3,25],[5,23],[7,20],[9,16],[10,11],[10,7],[9,2],[7,-2],[5,-5],[3,-7]] },
'*': { width: 16, points: [[8,21],[8,9],[-1,-1],[3,18],[13,12],[-1,-1],[13,18],[3,12]] },
'+': { width: 26, points: [[13,18],[13,0],[-1,-1],[4,9],[22,9]] },
',': { width: 10, points: [[6,1],[5,0],[4,1],[5,2],[6,1],[6,-1],[5,-3],[4,-4]] },
'-': { width: 18, points: [[6,9],[12,9]] },
'.': { width: 10, points: [[5,2],[4,1],[5,0],[6,1],[5,2]] },
'/': { width: 22, points: [[20,25],[2,-7]] },
'0': { width: 20, points: [[9,21],[6,20],[4,17],[3,12],[3,9],[4,4],[6,1],[9,0],[11,0],[14,1],[16,4],[17,9],[17,12],[16,17],[14,20],[11,21],[9,21]] },
'1': { width: 20, points: [[6,17],[8,18],[11,21],[11,0]] },
'2': { width: 20, points: [[4,16],[4,17],[5,19],[6,20],[8,21],[12,21],[14,20],[15,19],[16,17],[16,15],[15,13],[13,10],[3,0],[17,0]] },
'3': { width: 20, points: [[5,21],[16,21],[10,13],[13,13],[15,12],[16,11],[17,8],[17,6],[16,3],[14,1],[11,0],[8,0],[5,1],[4,2],[3,4]] },
'4': { width: 20, points: [[13,21],[3,7],[18,7],[-1,-1],[13,21],[13,0]] },
'5': { width: 20, points: [[15,21],[5,21],[4,12],[5,13],[8,14],[11,14],[14,13],[16,11],[17,8],[17,6],[16,3],[14,1],[11,0],[8,0],[5,1],[4,2],[3,4]] },
'6': { width: 20, points: [[16,18],[15,20],[12,21],[10,21],[7,20],[5,17],[4,12],[4,7],[5,3],[7,1],[10,0],[11,0],[14,1],[16,3],[17,6],[17,7],[16,10],[14,12],[11,13],[10,13],[7,12],[5,10],[4,7]] },
'7': { width: 20, points: [[17,21],[7,0],[-1,-1],[3,21],[17,21]] },
'8': { width: 20, points: [[8,21],[5,20],[4,18],[4,16],[5,14],[7,13],[11,12],[14,11],[16,9],[17,7],[17,4],[16,2],[15,1],[12,0],[8,0],[5,1],[4,2],[3,4],[3,7],[4,9],[6,11],[9,12],[13,13],[15,14],[16,16],[16,18],[15,20],[12,21],[8,21]] },
'9': { width: 20, points: [[16,14],[15,11],[13,9],[10,8],[9,8],[6,9],[4,11],[3,14],[3,15],[4,18],[6,20],[9,21],[10,21],[13,20],[15,18],[16,14],[16,9],[15,4],[13,1],[10,0],[8,0],[5,1],[4,3]] },
':': { width: 10, points: [[5,14],[4,13],[5,12],[6,13],[5,14],[-1,-1],[5,2],[4,1],[5,0],[6,1],[5,2]] },
';': { width: 10, points: [[5,14],[4,13],[5,12],[6,13],[5,14],[-1,-1],[6,1],[5,0],[4,1],[5,2],[6,1],[6,-1],[5,-3],[4,-4]] },
'<': { width: 24, points: [[20,18],[4,9],[20,0]] },
'=': { width: 26, points: [[4,12],[22,12],[-1,-1],[4,6],[22,6]] },
'>': { width: 24, points: [[4,18],[20,9],[4,0]] },
'?': { width: 18, points: [[3,16],[3,17],[4,19],[5,20],[7,21],[11,21],[13,20],[14,19],[15,17],[15,15],[14,13],[13,12],[9,10],[9,7],[-1,-1],[9,2],[8,1],[9,0],[10,1],[9,2]] },
'@': { width: 27, points: [[18,13],[17,15],[15,16],[12,16],[10,15],[9,14],[8,11],[8,8],[9,6],[11,5],[14,5],[16,6],[17,8],[-1,-1],[12,16],[10,14],[9,11],[9,8],[10,6],[11,5],[-1,-1],[18,16],[17,8],[17,6],[19,5],[21,5],[23,7],[24,10],[24,12],[23,15],[22,17],[20,19],[18,20],[15,21],[12,21],[9,20],[7,19],[5,17],[4,15],[3,12],[3,9],[4,6],[5,4],[7,2],[9,1],[12,0],[15,0],[18,1],[20,2],[21,3],[-1,-1],[19,16],[18,8],[18,6],[19,5]] },
'A': { width: 18, points: [[9,21],[1,0],[-1,-1],[9,21],[17,0],[-1,-1],[4,7],[14,7]] },
'B': { width: 21, points: [[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[-1,-1],[4,11],[13,11],[16,10],[17,9],[18,7],[18,4],[17,2],[16,1],[13,0],[4,0]] },
'C': { width: 21, points: [[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5]] },
'D': { width: 21, points: [[4,21],[4,0],[-1,-1],[4,21],[11,21],[14,20],[16,18],[17,16],[18,13],[18,8],[17,5],[16,3],[14,1],[11,0],[4,0]] },
'E': { width: 19, points: [[4,21],[4,0],[-1,-1],[4,21],[17,21],[-1,-1],[4,11],[12,11],[-1,-1],[4,0],[17,0]] },
'F': { width: 18, points: [[4,21],[4,0],[-1,-1],[4,21],[17,21],[-1,-1],[4,11],[12,11]] },
'G': { width: 21, points: [[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[18,8],[-1,-1],[13,8],[18,8]] },
'H': { width: 22, points: [[4,21],[4,0],[-1,-1],[18,21],[18,0],[-1,-1],[4,11],[18,11]] },
'I': { width: 8, points: [[4,21],[4,0]] },
'J': { width: 16, points: [[12,21],[12,5],[11,2],[10,1],[8,0],[6,0],[4,1],[3,2],[2,5],[2,7]] },
'K': { width: 21, points: [[4,21],[4,0],[-1,-1],[18,21],[4,7],[-1,-1],[9,12],[18,0]] },
'L': { width: 17, points: [[4,21],[4,0],[-1,-1],[4,0],[16,0]] },
'M': { width: 24, points: [[4,21],[4,0],[-1,-1],[4,21],[12,0],[-1,-1],[20,21],[12,0],[-1,-1],[20,21],[20,0]] },
'N': { width: 22, points: [[4,21],[4,0],[-1,-1],[4,21],[18,0],[-1,-1],[18,21],[18,0]] },
'O': { width: 22, points: [[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21]] },
'P': { width: 21, points: [[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,14],[17,12],[16,11],[13,10],[4,10]] },
'Q': { width: 22, points: [[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21],[-1,-1],[12,4],[18,-2]] },
'R': { width: 21, points: [[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[4,11],[-1,-1],[11,11],[18,0]] },
'S': { width: 20, points: [[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]] },
'T': { width: 16, points: [[8,21],[8,0],[-1,-1],[1,21],[15,21]] },
'U': { width: 22, points: [[4,21],[4,6],[5,3],[7,1],[10,0],[12,0],[15,1],[17,3],[18,6],[18,21]] },
'V': { width: 18, points: [[1,21],[9,0],[-1,-1],[17,21],[9,0]] },
'W': { width: 24, points: [[2,21],[7,0],[-1,-1],[12,21],[7,0],[-1,-1],[12,21],[17,0],[-1,-1],[22,21],[17,0]] },
'X': { width: 20, points: [[3,21],[17,0],[-1,-1],[17,21],[3,0]] },
'Y': { width: 18, points: [[1,21],[9,11],[9,0],[-1,-1],[17,21],[9,11]] },
'Z': { width: 20, points: [[17,21],[3,0],[-1,-1],[3,21],[17,21],[-1,-1],[3,0],[17,0]] },
'[': { width: 14, points: [[4,25],[4,-7],[-1,-1],[5,25],[5,-7],[-1,-1],[4,25],[11,25],[-1,-1],[4,-7],[11,-7]] },
'\\': { width: 14, points: [[0,21],[14,-3]] },
']': { width: 14, points: [[9,25],[9,-7],[-1,-1],[10,25],[10,-7],[-1,-1],[3,25],[10,25],[-1,-1],[3,-7],[10,-7]] },
'^': { width: 16, points: [[6,15],[8,18],[10,15],[-1,-1],[3,12],[8,17],[13,12],[-1,-1],[8,17],[8,0]] },
'_': { width: 16, points: [[0,-2],[16,-2]] },
'`': { width: 10, points: [[6,21],[5,20],[4,18],[4,16],[5,15],[6,16],[5,17]] },
'a': { width: 19, points: [[15,14],[15,0],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] },
'b': { width: 19, points: [[4,21],[4,0],[-1,-1],[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]] },
'c': { width: 18, points: [[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] },
'd': { width: 19, points: [[15,21],[15,0],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] },
'e': { width: 18, points: [[3,8],[15,8],[15,10],[14,12],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] },
'f': { width: 12, points: [[10,21],[8,21],[6,20],[5,17],[5,0],[-1,-1],[2,14],[9,14]] },
'g': { width: 19, points: [[15,14],[15,-2],[14,-5],[13,-6],[11,-7],[8,-7],[6,-6],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] },
'h': { width: 19, points: [[4,21],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]] },
'i': { width: 8, points: [[3,21],[4,20],[5,21],[4,22],[3,21],[-1,-1],[4,14],[4,0]] },
'j': { width: 10, points: [[5,21],[6,20],[7,21],[6,22],[5,21],[-1,-1],[6,14],[6,-3],[5,-6],[3,-7],[1,-7]] },
'k': { width: 17, points: [[4,21],[4,0],[-1,-1],[14,14],[4,4],[-1,-1],[8,8],[15,0]] },
'l': { width: 8, points: [[4,21],[4,0]] },
'm': { width: 30, points: [[4,14],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0],[-1,-1],[15,10],[18,13],[20,14],[23,14],[25,13],[26,10],[26,0]] },
'n': { width: 19, points: [[4,14],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]] },
'o': { width: 19, points: [[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3],[16,6],[16,8],[15,11],[13,13],[11,14],[8,14]] },
'p': { width: 19, points: [[4,14],[4,-7],[-1,-1],[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]] },
'q': { width: 19, points: [[15,14],[15,-7],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] },
'r': { width: 13, points: [[4,14],[4,0],[-1,-1],[4,8],[5,11],[7,13],[9,14],[12,14]] },
's': { width: 17, points: [[14,11],[13,13],[10,14],[7,14],[4,13],[3,11],[4,9],[6,8],[11,7],[13,6],[14,4],[14,3],[13,1],[10,0],[7,0],[4,1],[3,3]] },
't': { width: 12, points: [[5,21],[5,4],[6,1],[8,0],[10,0],[-1,-1],[2,14],[9,14]] },
'u': { width: 19, points: [[4,14],[4,4],[5,1],[7,0],[10,0],[12,1],[15,4],[-1,-1],[15,14],[15,0]] },
'v': { width: 16, points: [[2,14],[8,0],[-1,-1],[14,14],[8,0]] },
'w': { width: 22, points: [[3,14],[7,0],[-1,-1],[11,14],[7,0],[-1,-1],[11,14],[15,0],[-1,-1],[19,14],[15,0]] },
'x': { width: 17, points: [[3,14],[14,0],[-1,-1],[14,14],[3,0]] },
'y': { width: 16, points: [[2,14],[8,0],[-1,-1],[14,14],[8,0],[6,-4],[4,-6],[2,-7],[1,-7]] },
'z': { width: 17, points: [[14,14],[3,0],[-1,-1],[3,14],[14,14],[-1,-1],[3,0],[14,0]] },
'{': { width: 14, points: [[9,25],[7,24],[6,23],[5,21],[5,19],[6,17],[7,16],[8,14],[8,12],[6,10],[-1,-1],[7,24],[6,22],[6,20],[7,18],[8,17],[9,15],[9,13],[8,11],[4,9],[8,7],[9,5],[9,3],[8,1],[7,0],[6,-2],[6,-4],[7,-6],[-1,-1],[6,8],[8,6],[8,4],[7,2],[6,1],[5,-1],[5,-3],[6,-5],[7,-6],[9,-7]] },
'|': { width: 8, points: [[4,25],[4,-7]] },
'}': { width: 14, points: [[5,25],[7,24],[8,23],[9,21],[9,19],[8,17],[7,16],[6,14],[6,12],[8,10],[-1,-1],[7,24],[8,22],[8,20],[7,18],[6,17],[5,15],[5,13],[6,11],[10,9],[6,7],[5,5],[5,3],[6,1],[7,0],[8,-2],[8,-4],[7,-6],[-1,-1],[8,8],[6,6],[6,4],[7,2],[8,1],[9,-1],[9,-3],[8,-5],[7,-6],[5,-7]] },
'~': { width: 24, points: [[3,6],[3,8],[4,11],[6,12],[8,12],[10,11],[14,8],[16,7],[18,7],[20,8],[21,10],[-1,-1],[3,8],[4,10],[6,11],[8,11],[10,10],[14,7],[16,6],[18,6],[20,7],[21,10],[21,12]] }
};
$.jqplot.CanvasFontRenderer = function(options) {
options = options || {};
if (!options.pt2px) {
options.pt2px = 1.5;
}
$.jqplot.CanvasTextRenderer.call(this, options);
};
$.jqplot.CanvasFontRenderer.prototype = new $.jqplot.CanvasTextRenderer({});
$.jqplot.CanvasFontRenderer.prototype.constructor = $.jqplot.CanvasFontRenderer;
$.jqplot.CanvasFontRenderer.prototype.measure = function(ctx, str)
{
// var fstyle = this.fontStyle+' '+this.fontVariant+' '+this.fontWeight+' '+this.fontSize+' '+this.fontFamily;
var fstyle = this.fontSize+' '+this.fontFamily;
ctx.save();
ctx.font = fstyle;
var w = ctx.measureText(str).width;
ctx.restore();
return w;
};
$.jqplot.CanvasFontRenderer.prototype.draw = function(ctx, str)
{
var x = 0;
// leave room at bottom for descenders.
var y = this.height*0.72;
//var y = 12;
ctx.save();
var tx, ty;
// 1st quadrant
if ((-Math.PI/2 <= this.angle && this.angle <= 0) || (Math.PI*3/2 <= this.angle && this.angle <= Math.PI*2)) {
tx = 0;
ty = -Math.sin(this.angle) * this.width;
}
// 4th quadrant
else if ((0 < this.angle && this.angle <= Math.PI/2) || (-Math.PI*2 <= this.angle && this.angle <= -Math.PI*3/2)) {
tx = Math.sin(this.angle) * this.height;
ty = 0;
}
// 2nd quadrant
else if ((-Math.PI < this.angle && this.angle < -Math.PI/2) || (Math.PI <= this.angle && this.angle <= Math.PI*3/2)) {
tx = -Math.cos(this.angle) * this.width;
ty = -Math.sin(this.angle) * this.width - Math.cos(this.angle) * this.height;
}
// 3rd quadrant
else if ((-Math.PI*3/2 < this.angle && this.angle < Math.PI) || (Math.PI/2 < this.angle && this.angle < Math.PI)) {
tx = Math.sin(this.angle) * this.height - Math.cos(this.angle)*this.width;
ty = -Math.cos(this.angle) * this.height;
}
ctx.strokeStyle = this.fillStyle;
ctx.fillStyle = this.fillStyle;
// var fstyle = this.fontStyle+' '+this.fontVariant+' '+this.fontWeight+' '+this.fontSize+' '+this.fontFamily;
var fstyle = this.fontSize+' '+this.fontFamily;
ctx.font = fstyle;
ctx.translate(tx, ty);
ctx.rotate(this.angle);
ctx.fillText(str, x, y);
// ctx.strokeText(str, x, y);
ctx.restore();
};
})(jQuery);

File diff suppressed because one or more lines are too long

465
theme/jqplot.highlighter.js Normal file
View file

@ -0,0 +1,465 @@
/**
* jqPlot
* Pure JavaScript plotting plugin using jQuery
*
* Version: 1.0.9
* Revision: d96a669
*
* Copyright (c) 2009-2016 Chris Leonello
* jqPlot is currently available for use in all personal or commercial projects
* under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
* version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
* choose the license that best suits your project and use it accordingly.
*
* Although not required, the author would appreciate an email letting him
* know of any substantial use of jqPlot. You can reach the author at:
* chris at jqplot dot com or see http://www.jqplot.com/info.php .
*
* If you are feeling kind and generous, consider supporting the project by
* making a donation at: http://www.jqplot.com/donate.php .
*
* sprintf functions contained in jqplot.sprintf.js by Ash Searle:
*
* version 2007.04.27
* author Ash Searle
* http://hexmen.com/blog/2007/03/printf-sprintf/
* http://hexmen.com/js/sprintf.js
* The author (Ash Searle) has placed this code in the public domain:
* "This code is unrestricted: you are free to use it however you like."
*
*/
(function($) {
$.jqplot.eventListenerHooks.push(['jqplotMouseMove', handleMove]);
/**
* Class: $.jqplot.Highlighter
* Plugin which will highlight data points when they are moused over.
*
* To use this plugin, include the js
* file in your source:
*
* > <script type="text/javascript" src="plugins/jqplot.highlighter.js"></script>
*
* A tooltip providing information about the data point is enabled by default.
* To disable the tooltip, set "showTooltip" to false.
*
* You can control what data is displayed in the tooltip with various
* options. The "tooltipAxes" option controls whether the x, y or both
* data values are displayed.
*
* Some chart types (e.g. hi-low-close) have more than one y value per
* data point. To display the additional values in the tooltip, set the
* "yvalues" option to the desired number of y values present (3 for a hlc chart).
*
* By default, data values will be formatted with the same formatting
* specifiers as used to format the axis ticks. A custom format code
* can be supplied with the tooltipFormatString option. This will apply
* to all values in the tooltip.
*
* For more complete control, the "formatString" option can be set. This
* Allows conplete control over tooltip formatting. Values are passed to
* the format string in an order determined by the "tooltipAxes" and "yvalues"
* options. So, if you have a hi-low-close chart and you just want to display
* the hi-low-close values in the tooltip, you could set a formatString like:
*
* > highlighter: {
* > tooltipAxes: 'y',
* > yvalues: 3,
* > formatString:'<table class="jqplot-highlighter">
* > <tr><td>hi:</td><td>%s</td></tr>
* > <tr><td>low:</td><td>%s</td></tr>
* > <tr><td>close:</td><td>%s</td></tr></table>'
* > }
*
*/
$.jqplot.Highlighter = function(options) {
// Group: Properties
//
//prop: show
// true to show the highlight.
this.show = $.jqplot.config.enablePlugins;
// prop: markerRenderer
// Renderer used to draw the marker of the highlighted point.
// Renderer will assimilate attributes from the data point being highlighted,
// so no attributes need set on the renderer directly.
// Default is to turn off shadow drawing on the highlighted point.
this.markerRenderer = new $.jqplot.MarkerRenderer({shadow:false});
// prop: showMarker
// true to show the marker
this.showMarker = true;
// prop: lineWidthAdjust
// Pixels to add to the lineWidth of the highlight.
this.lineWidthAdjust = 2.5;
// prop: sizeAdjust
// Pixels to add to the overall size of the highlight.
this.sizeAdjust = 5;
// prop: showTooltip
// Show a tooltip with data point values.
this.showTooltip = true;
// prop: tooltipLocation
// Where to position tooltip, 'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw'
this.tooltipLocation = 'nw';
// prop: fadeTooltip
// true = fade in/out tooltip, flase = show/hide tooltip
this.fadeTooltip = true;
// prop: tooltipFadeSpeed
// 'slow', 'def', 'fast', or number of milliseconds.
this.tooltipFadeSpeed = "fast";
// prop: tooltipOffset
// Pixel offset of tooltip from the highlight.
this.tooltipOffset = 2;
// prop: tooltipAxes
// Which axes to display in tooltip, 'x', 'y' or 'both', 'xy' or 'yx'
// 'both' and 'xy' are equivalent, 'yx' reverses order of labels.
this.tooltipAxes = 'both';
// prop; tooltipSeparator
// String to use to separate x and y axes in tooltip.
this.tooltipSeparator = ', ';
// prop; tooltipContentEditor
// Function used to edit/augment/replace the formatted tooltip contents.
// Called as str = tooltipContentEditor(str, seriesIndex, pointIndex)
// where str is the generated tooltip html and seriesIndex and pointIndex identify
// the data point being highlighted. Should return the html for the tooltip contents.
this.tooltipContentEditor = null;
// prop: useAxesFormatters
// Use the x and y axes formatters to format the text in the tooltip.
this.useAxesFormatters = true;
// prop: tooltipFormatString
// sprintf format string for the tooltip.
// Uses Ash Searle's javascript sprintf implementation
// found here: http://hexmen.com/blog/2007/03/printf-sprintf/
// See http://perldoc.perl.org/functions/sprintf.html for reference.
// Additional "p" and "P" format specifiers added by Chris Leonello.
this.tooltipFormatString = '%.5P';
// prop: formatString
// alternative to tooltipFormatString
// will format the whole tooltip text, populating with x, y values as
// indicated by tooltipAxes option. So, you could have a tooltip like:
// 'Date: %s, number of cats: %d' to format the whole tooltip at one go.
// If useAxesFormatters is true, values will be formatted according to
// Axes formatters and you can populate your tooltip string with
// %s placeholders.
this.formatString = null;
// prop: yvalues
// Number of y values to expect in the data point array.
// Typically this is 1. Certain plots, like OHLC, will
// have more y values in each data point array.
this.yvalues = 1;
// prop: bringSeriesToFront
// This option requires jQuery 1.4+
// True to bring the series of the highlighted point to the front
// of other series.
this.bringSeriesToFront = false;
this._tooltipElem;
this.isHighlighting = false;
this.currentNeighbor = null;
$.extend(true, this, options);
};
var locations = ['nw', 'n', 'ne', 'e', 'se', 's', 'sw', 'w'];
var locationIndicies = {'nw':0, 'n':1, 'ne':2, 'e':3, 'se':4, 's':5, 'sw':6, 'w':7};
var oppositeLocations = ['se', 's', 'sw', 'w', 'nw', 'n', 'ne', 'e'];
// axis.renderer.tickrenderer.formatter
// called with scope of plot
$.jqplot.Highlighter.init = function (target, data, opts){
var options = opts || {};
// add a highlighter attribute to the plot
this.plugins.highlighter = new $.jqplot.Highlighter(options.highlighter);
};
// called within scope of series
$.jqplot.Highlighter.parseOptions = function (defaults, options) {
// Add a showHighlight option to the series
// and set it to true by default.
this.showHighlight = true;
};
// called within context of plot
// create a canvas which we can draw on.
// insert it before the eventCanvas, so eventCanvas will still capture events.
$.jqplot.Highlighter.postPlotDraw = function() {
// Memory Leaks patch
if (this.plugins.highlighter && this.plugins.highlighter.highlightCanvas) {
this.plugins.highlighter.highlightCanvas.resetCanvas();
this.plugins.highlighter.highlightCanvas = null;
}
if (this.plugins.highlighter && this.plugins.highlighter._tooltipElem) {
this.plugins.highlighter._tooltipElem.emptyForce();
this.plugins.highlighter._tooltipElem = null;
}
this.plugins.highlighter.highlightCanvas = new $.jqplot.GenericCanvas();
this.eventCanvas._elem.before(this.plugins.highlighter.highlightCanvas.createElement(this._gridPadding, 'jqplot-highlight-canvas', this._plotDimensions, this));
this.plugins.highlighter.highlightCanvas.setContext();
var elem = document.createElement('div');
this.plugins.highlighter._tooltipElem = $(elem);
elem = null;
this.plugins.highlighter._tooltipElem.addClass('jqplot-highlighter-tooltip');
this.plugins.highlighter._tooltipElem.css({position:'absolute', display:'none'});
this.eventCanvas._elem.before(this.plugins.highlighter._tooltipElem);
};
$.jqplot.preInitHooks.push($.jqplot.Highlighter.init);
$.jqplot.preParseSeriesOptionsHooks.push($.jqplot.Highlighter.parseOptions);
$.jqplot.postDrawHooks.push($.jqplot.Highlighter.postPlotDraw);
function draw(plot, neighbor) {
var hl = plot.plugins.highlighter;
var s = plot.series[neighbor.seriesIndex];
var smr = s.markerRenderer;
var mr = hl.markerRenderer;
mr.style = smr.style;
mr.lineWidth = smr.lineWidth + hl.lineWidthAdjust;
mr.size = smr.size + hl.sizeAdjust;
var rgba = $.jqplot.getColorComponents(smr.color);
var newrgb = [rgba[0], rgba[1], rgba[2]];
var alpha = (rgba[3] >= 0.6) ? rgba[3]*0.6 : rgba[3]*(2-rgba[3]);
mr.color = 'rgba('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+','+alpha+')';
mr.init();
mr.draw(s.gridData[neighbor.pointIndex][0], s.gridData[neighbor.pointIndex][1], hl.highlightCanvas._ctx);
}
function showTooltip(plot, series, neighbor) {
// neighbor looks like: {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}
// gridData should be x,y pixel coords on the grid.
// add the plot._gridPadding to that to get x,y in the target.
var hl = plot.plugins.highlighter;
var elem = hl._tooltipElem;
var serieshl = series.highlighter || {};
var opts = $.extend(true, {}, hl, serieshl);
if (opts.useAxesFormatters) {
var xf = series._xaxis._ticks[0].formatter;
var yf = series._yaxis._ticks[0].formatter;
var xfstr = series._xaxis._ticks[0].formatString;
var yfstr = series._yaxis._ticks[0].formatString;
var str;
var xstr = xf(xfstr, neighbor.data[0]);
var ystrs = [];
for (var i=1; i<opts.yvalues+1; i++) {
ystrs.push(yf(yfstr, neighbor.data[i]));
}
if (typeof opts.formatString === 'string') {
switch (opts.tooltipAxes) {
case 'both':
case 'xy':
ystrs.unshift(xstr);
ystrs.unshift(opts.formatString);
str = $.jqplot.sprintf.apply($.jqplot.sprintf, ystrs);
break;
case 'yx':
ystrs.push(xstr);
ystrs.unshift(opts.formatString);
str = $.jqplot.sprintf.apply($.jqplot.sprintf, ystrs);
break;
case 'x':
str = $.jqplot.sprintf.apply($.jqplot.sprintf, [opts.formatString, xstr]);
break;
case 'y':
ystrs.unshift(opts.formatString);
str = $.jqplot.sprintf.apply($.jqplot.sprintf, ystrs);
break;
default: // same as xy
ystrs.unshift(xstr);
ystrs.unshift(opts.formatString);
str = $.jqplot.sprintf.apply($.jqplot.sprintf, ystrs);
break;
}
}
else {
switch (opts.tooltipAxes) {
case 'both':
case 'xy':
str = xstr;
for (var i=0; i<ystrs.length; i++) {
str += opts.tooltipSeparator + ystrs[i];
}
break;
case 'yx':
str = '';
for (var i=0; i<ystrs.length; i++) {
str += ystrs[i] + opts.tooltipSeparator;
}
str += xstr;
break;
case 'x':
str = xstr;
break;
case 'y':
str = ystrs.join(opts.tooltipSeparator);
break;
default: // same as 'xy'
str = xstr;
for (var i=0; i<ystrs.length; i++) {
str += opts.tooltipSeparator + ystrs[i];
}
break;
}
}
}
else {
var str;
if (typeof opts.formatString === 'string') {
str = $.jqplot.sprintf.apply($.jqplot.sprintf, [opts.formatString].concat(neighbor.data));
}
else {
if (opts.tooltipAxes == 'both' || opts.tooltipAxes == 'xy') {
str = $.jqplot.sprintf(opts.tooltipFormatString, neighbor.data[0]) + opts.tooltipSeparator + $.jqplot.sprintf(opts.tooltipFormatString, neighbor.data[1]);
}
else if (opts.tooltipAxes == 'yx') {
str = $.jqplot.sprintf(opts.tooltipFormatString, neighbor.data[1]) + opts.tooltipSeparator + $.jqplot.sprintf(opts.tooltipFormatString, neighbor.data[0]);
}
else if (opts.tooltipAxes == 'x') {
str = $.jqplot.sprintf(opts.tooltipFormatString, neighbor.data[0]);
}
else if (opts.tooltipAxes == 'y') {
str = $.jqplot.sprintf(opts.tooltipFormatString, neighbor.data[1]);
}
}
}
if ($.isFunction(opts.tooltipContentEditor)) {
// args str, seriesIndex, pointIndex are essential so the hook can look up
// extra data for the point.
str = opts.tooltipContentEditor(str, neighbor.seriesIndex, neighbor.pointIndex, plot);
}
elem.html(str);
var gridpos = {x:neighbor.gridData[0], y:neighbor.gridData[1]};
var ms = 0;
var fact = 0.707;
if (series.markerRenderer.show == true) {
ms = (series.markerRenderer.size + opts.sizeAdjust)/2;
}
var loc = locations;
if (series.fillToZero && series.fill && neighbor.data[1] < 0) {
loc = oppositeLocations;
}
switch (loc[locationIndicies[opts.tooltipLocation]]) {
case 'nw':
var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset - fact * ms;
var y = gridpos.y + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true) - fact * ms;
break;
case 'n':
var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true)/2;
var y = gridpos.y + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true) - ms;
break;
case 'ne':
var x = gridpos.x + plot._gridPadding.left + opts.tooltipOffset + fact * ms;
var y = gridpos.y + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true) - fact * ms;
break;
case 'e':
var x = gridpos.x + plot._gridPadding.left + opts.tooltipOffset + ms;
var y = gridpos.y + plot._gridPadding.top - elem.outerHeight(true)/2;
break;
case 'se':
var x = gridpos.x + plot._gridPadding.left + opts.tooltipOffset + fact * ms;
var y = gridpos.y + plot._gridPadding.top + opts.tooltipOffset + fact * ms;
break;
case 's':
var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true)/2;
var y = gridpos.y + plot._gridPadding.top + opts.tooltipOffset + ms;
break;
case 'sw':
var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset - fact * ms;
var y = gridpos.y + plot._gridPadding.top + opts.tooltipOffset + fact * ms;
break;
case 'w':
var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset - ms;
var y = gridpos.y + plot._gridPadding.top - elem.outerHeight(true)/2;
break;
default: // same as 'nw'
var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset - fact * ms;
var y = gridpos.y + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true) - fact * ms;
break;
}
elem.css('left', x);
elem.css('top', y);
if (opts.fadeTooltip) {
// Fix for stacked up animations. Thnanks Trevor!
elem.stop(true,true).fadeIn(opts.tooltipFadeSpeed);
}
else {
elem.show();
}
elem = null;
}
function handleMove(ev, gridpos, datapos, neighbor, plot) {
var hl = plot.plugins.highlighter;
var c = plot.plugins.cursor;
if (hl.show) {
if (neighbor == null && hl.isHighlighting) {
var evt = jQuery.Event('jqplotHighlighterUnhighlight');
plot.target.trigger(evt);
var ctx = hl.highlightCanvas._ctx;
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
if (hl.fadeTooltip) {
hl._tooltipElem.fadeOut(hl.tooltipFadeSpeed);
}
else {
hl._tooltipElem.hide();
}
if (hl.bringSeriesToFront) {
plot.restorePreviousSeriesOrder();
}
hl.isHighlighting = false;
hl.currentNeighbor = null;
ctx = null;
}
else if (neighbor != null && plot.series[neighbor.seriesIndex].showHighlight && !hl.isHighlighting) {
var evt = jQuery.Event('jqplotHighlighterHighlight');
evt.which = ev.which;
evt.pageX = ev.pageX;
evt.pageY = ev.pageY;
var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data, plot];
plot.target.trigger(evt, ins);
hl.isHighlighting = true;
hl.currentNeighbor = neighbor;
if (hl.showMarker) {
draw(plot, neighbor);
}
if (plot.series[neighbor.seriesIndex].show && hl.showTooltip && (!c || !c._zoom.started)) {
showTooltip(plot, plot.series[neighbor.seriesIndex], neighbor);
}
if (hl.bringSeriesToFront) {
plot.moveSeriesToFront(neighbor.seriesIndex);
}
}
// check to see if we're highlighting the wrong point.
else if (neighbor != null && hl.isHighlighting && hl.currentNeighbor != neighbor) {
// highlighting the wrong point.
// if new series allows highlighting, highlight new point.
if (plot.series[neighbor.seriesIndex].showHighlight) {
var ctx = hl.highlightCanvas._ctx;
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
hl.isHighlighting = true;
hl.currentNeighbor = neighbor;
if (hl.showMarker) {
draw(plot, neighbor);
}
if (plot.series[neighbor.seriesIndex].show && hl.showTooltip && (!c || !c._zoom.started)) {
showTooltip(plot, plot.series[neighbor.seriesIndex], neighbor);
}
if (hl.bringSeriesToFront) {
plot.moveSeriesToFront(neighbor.seriesIndex);
}
}
}
}
}
})(jQuery);

File diff suppressed because one or more lines are too long

View file

@ -1,259 +0,0 @@
/*rules for the plot target div. These will be cascaded down to all plot elements according to css rules*/
.jqplot-target {
position: relative;
color: #666666;
font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
font-size: 1em;
/* height: 300px;
width: 400px;*/
}
/*rules applied to all axes*/
.jqplot-axis {
font-size: 0.75em;
}
.jqplot-xaxis {
margin-top: 10px;
}
.jqplot-x2axis {
margin-bottom: 10px;
}
.jqplot-yaxis {
margin-right: 10px;
}
.jqplot-y2axis, .jqplot-y3axis, .jqplot-y4axis, .jqplot-y5axis, .jqplot-y6axis, .jqplot-y7axis, .jqplot-y8axis, .jqplot-y9axis, .jqplot-yMidAxis {
margin-left: 10px;
margin-right: 10px;
}
/*rules applied to all axis tick divs*/
.jqplot-axis-tick, .jqplot-xaxis-tick, .jqplot-yaxis-tick, .jqplot-x2axis-tick, .jqplot-y2axis-tick, .jqplot-y3axis-tick, .jqplot-y4axis-tick, .jqplot-y5axis-tick, .jqplot-y6axis-tick, .jqplot-y7axis-tick, .jqplot-y8axis-tick, .jqplot-y9axis-tick, .jqplot-yMidAxis-tick {
position: absolute;
white-space: pre;
}
.jqplot-xaxis-tick {
top: 0px;
/* initial position untill tick is drawn in proper place */
left: 15px;
/* padding-top: 10px;*/
vertical-align: top;
}
.jqplot-x2axis-tick {
bottom: 0px;
/* initial position untill tick is drawn in proper place */
left: 15px;
/* padding-bottom: 10px;*/
vertical-align: bottom;
}
.jqplot-yaxis-tick {
right: 0px;
/* initial position untill tick is drawn in proper place */
top: 15px;
/* padding-right: 10px;*/
text-align: right;
}
.jqplot-yaxis-tick.jqplot-breakTick {
right: -20px;
margin-right: 0px;
padding:1px 5px 1px 5px;
/* background-color: white;*/
z-index: 2;
font-size: 1.5em;
}
.jqplot-y2axis-tick, .jqplot-y3axis-tick, .jqplot-y4axis-tick, .jqplot-y5axis-tick, .jqplot-y6axis-tick, .jqplot-y7axis-tick, .jqplot-y8axis-tick, .jqplot-y9axis-tick {
left: 0px;
/* initial position untill tick is drawn in proper place */
top: 15px;
/* padding-left: 10px;*/
/* padding-right: 15px;*/
text-align: left;
}
.jqplot-yMidAxis-tick {
text-align: center;
white-space: nowrap;
}
.jqplot-xaxis-label {
margin-top: 10px;
font-size: 11pt;
position: absolute;
}
.jqplot-x2axis-label {
margin-bottom: 10px;
font-size: 11pt;
position: absolute;
}
.jqplot-yaxis-label {
margin-right: 10px;
/* text-align: center;*/
font-size: 11pt;
position: absolute;
}
.jqplot-yMidAxis-label {
font-size: 11pt;
position: absolute;
}
.jqplot-y2axis-label, .jqplot-y3axis-label, .jqplot-y4axis-label, .jqplot-y5axis-label, .jqplot-y6axis-label, .jqplot-y7axis-label, .jqplot-y8axis-label, .jqplot-y9axis-label {
/* text-align: center;*/
font-size: 11pt;
margin-left: 10px;
position: absolute;
}
.jqplot-meterGauge-tick {
font-size: 0.75em;
color: #999999;
}
.jqplot-meterGauge-label {
font-size: 1em;
color: #999999;
}
table.jqplot-table-legend {
margin-top: 12px;
margin-bottom: 12px;
margin-left: 12px;
margin-right: 12px;
}
table.jqplot-table-legend, table.jqplot-cursor-legend {
background-color: rgba(255,255,255,0.6);
border: 1px solid #cccccc;
position: absolute;
font-size: 0.75em;
}
td.jqplot-table-legend {
vertical-align:middle;
}
/*
These rules could be used instead of assigning
element styles and relying on js object properties.
*/
/*
td.jqplot-table-legend-swatch {
padding-top: 0.5em;
text-align: center;
}
tr.jqplot-table-legend:first td.jqplot-table-legend-swatch {
padding-top: 0px;
}
*/
td.jqplot-seriesToggle:hover, td.jqplot-seriesToggle:active {
cursor: pointer;
}
.jqplot-table-legend .jqplot-series-hidden {
text-decoration: line-through;
}
div.jqplot-table-legend-swatch-outline {
border: 1px solid #cccccc;
padding:1px;
}
div.jqplot-table-legend-swatch {
width:0px;
height:0px;
border-top-width: 5px;
border-bottom-width: 5px;
border-left-width: 6px;
border-right-width: 6px;
border-top-style: solid;
border-bottom-style: solid;
border-left-style: solid;
border-right-style: solid;
}
.jqplot-title {
top: 0px;
left: 0px;
padding-bottom: 0.5em;
font-size: 1.2em;
}
table.jqplot-cursor-tooltip {
border: 1px solid #cccccc;
font-size: 0.75em;
}
.jqplot-cursor-tooltip {
border: 1px solid #cccccc;
font-size: 0.75em;
white-space: nowrap;
background: rgba(208,208,208,0.5);
padding: 1px;
}
.jqplot-highlighter-tooltip, .jqplot-canvasOverlay-tooltip {
border: 1px solid #cccccc;
font-size: 0.75em;
white-space: nowrap;
background: rgba(208,208,208,0.9);
padding: 1px;
}
.jqplot-point-label {
font-size: 0.75em;
z-index: 2;
}
td.jqplot-cursor-legend-swatch {
vertical-align: middle;
text-align: center;
}
div.jqplot-cursor-legend-swatch {
width: 1.2em;
height: 0.7em;
}
.jqplot-error {
/* Styles added to the plot target container when there is an error go here.*/
text-align: center;
}
.jqplot-error-message {
/* Styling of the custom error message div goes here.*/
position: relative;
top: 46%;
display: inline-block;
}
div.jqplot-bubble-label {
font-size: 0.8em;
/* background: rgba(90%, 90%, 90%, 0.15);*/
padding-left: 2px;
padding-right: 2px;
color: rgb(20%, 20%, 20%);
}
div.jqplot-bubble-label.jqplot-bubble-label-highlight {
background: rgba(90%, 90%, 90%, 0.7);
}
div.jqplot-noData-container {
text-align: center;
background-color: rgba(96%, 96%, 96%, 0.3);
}

1
theme/jquery.jqplot.min.css vendored Normal file
View file

@ -0,0 +1 @@
.jqplot-xaxis,.jqplot-xaxis-label{margin-top:10px}.jqplot-x2axis,.jqplot-x2axis-label{margin-bottom:10px}.jqplot-target{position:relative;color:#666;font-family:"Trebuchet MS",Arial,Helvetica,sans-serif;font-size:1em}.jqplot-axis{font-size:.75em}.jqplot-yaxis{margin-right:10px}.jqplot-y2axis,.jqplot-y3axis,.jqplot-y4axis,.jqplot-y5axis,.jqplot-y6axis,.jqplot-y7axis,.jqplot-y8axis,.jqplot-y9axis,.jqplot-yMidAxis{margin-left:10px;margin-right:10px}.jqplot-axis-tick,.jqplot-x2axis-tick,.jqplot-xaxis-tick,.jqplot-y2axis-tick,.jqplot-y3axis-tick,.jqplot-y4axis-tick,.jqplot-y5axis-tick,.jqplot-y6axis-tick,.jqplot-y7axis-tick,.jqplot-y8axis-tick,.jqplot-y9axis-tick,.jqplot-yMidAxis-tick,.jqplot-yaxis-tick{position:absolute;white-space:pre}.jqplot-xaxis-tick{top:0;left:15px;vertical-align:top}.jqplot-x2axis-tick{bottom:0;left:15px;vertical-align:bottom}.jqplot-yaxis-tick{right:0;top:15px;text-align:right}.jqplot-yaxis-tick.jqplot-breakTick{right:-20px;margin-right:0;padding:1px 5px;z-index:2;font-size:1.5em}.jqplot-x2axis-label,.jqplot-xaxis-label,.jqplot-yMidAxis-label,.jqplot-yaxis-label{font-size:11pt;position:absolute}.jqplot-y2axis-tick,.jqplot-y3axis-tick,.jqplot-y4axis-tick,.jqplot-y5axis-tick,.jqplot-y6axis-tick,.jqplot-y7axis-tick,.jqplot-y8axis-tick,.jqplot-y9axis-tick{left:0;top:15px;text-align:left}.jqplot-yMidAxis-tick{text-align:center;white-space:nowrap}.jqplot-yaxis-label{margin-right:10px}.jqplot-y2axis-label,.jqplot-y3axis-label,.jqplot-y4axis-label,.jqplot-y5axis-label,.jqplot-y6axis-label,.jqplot-y7axis-label,.jqplot-y8axis-label,.jqplot-y9axis-label{font-size:11pt;margin-left:10px;position:absolute}.jqplot-meterGauge-tick{font-size:.75em;color:#999}.jqplot-meterGauge-label{font-size:1em;color:#999}table.jqplot-table-legend{margin:12px}table.jqplot-cursor-legend,table.jqplot-table-legend{background-color:rgba(255,255,255,.6);border:1px solid #ccc;position:absolute;font-size:.75em}td.jqplot-table-legend{vertical-align:middle}td.jqplot-seriesToggle:active,td.jqplot-seriesToggle:hover{cursor:pointer}.jqplot-table-legend .jqplot-series-hidden{text-decoration:line-through}div.jqplot-table-legend-swatch-outline{border:1px solid #ccc;padding:1px}div.jqplot-table-legend-swatch{width:0;height:0;border-width:5px 6px;border-style:solid}.jqplot-title{top:0;left:0;padding-bottom:.5em;font-size:1.2em}table.jqplot-cursor-tooltip{border:1px solid #ccc;font-size:.75em}.jqplot-canvasOverlay-tooltip,.jqplot-cursor-tooltip,.jqplot-highlighter-tooltip{border:1px solid #ccc;font-size:.75em;white-space:nowrap;background:rgba(208,208,208,.5);padding:1px}.jqplot-point-label{font-size:.75em;z-index:2}td.jqplot-cursor-legend-swatch{vertical-align:middle;text-align:center}div.jqplot-cursor-legend-swatch{width:1.2em;height:.7em}.jqplot-error{text-align:center}.jqplot-error-message{position:relative;top:46%;display:inline-block}div.jqplot-bubble-label{font-size:.8em;padding-left:2px;padding-right:2px;color:rgb(20%,20%,20%)}div.jqplot-bubble-label.jqplot-bubble-label-highlight{background:rgba(90%,90%,90%,.7)}div.jqplot-noData-container{text-align:center;background-color:rgba(96%,96%,96%,.3)}

File diff suppressed because one or more lines are too long

9
theme/jquery.min.js vendored

File diff suppressed because one or more lines are too long