You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openoffice.apache.org by ms...@apache.org on 2017/05/17 15:29:58 UTC
svn commit: r1795424 [28/29] - in /openoffice/ooo-site/trunk/content:
scripts/api.simile-widgets.org/ scripts/api.simile-widgets.org/ajax/
scripts/api.simile-widgets.org/ajax/2.2.1.fake/
scripts/api.simile-widgets.org/ajax/2.2.1/ scripts/api.simile-wid...
Added: openoffice/ooo-site/trunk/content/scripts/api.simile-widgets.org/timeplot/1.1/scripts/geometry.js
URL: http://svn.apache.org/viewvc/openoffice/ooo-site/trunk/content/scripts/api.simile-widgets.org/timeplot/1.1/scripts/geometry.js?rev=1795424&view=auto
==============================================================================
--- openoffice/ooo-site/trunk/content/scripts/api.simile-widgets.org/timeplot/1.1/scripts/geometry.js (added)
+++ openoffice/ooo-site/trunk/content/scripts/api.simile-widgets.org/timeplot/1.1/scripts/geometry.js Wed May 17 15:29:56 2017
@@ -0,0 +1,879 @@
+/**
+ * Geometries
+ *
+ * @fileOverview Geometries
+ * @name Geometries
+ */
+
+/**
+ * This is the constructor for the default value geometry.
+ * A value geometry is what regulates mapping of the plot values to the screen y coordinate.
+ * If two plots share the same value geometry, they will be drawn using the same scale.
+ * If "min" and "max" parameters are not set, the geometry will stretch itself automatically
+ * so that the entire plot will be drawn without overflowing. The stretching happens also
+ * when a geometry is shared between multiple plots, the one with the biggest range will
+ * win over the others.
+ *
+ * @constructor
+ */
+Timeplot.DefaultValueGeometry = function(params) {
+ if (!params) params = {};
+ this._id = ("id" in params) ? params.id : "g" + Math.round(Math.random() * 1000000);
+ this._axisColor = ("axisColor" in params) ? ((typeof params.axisColor == "string") ? new Timeplot.Color(params.axisColor) : params.axisColor) : new Timeplot.Color("#606060"),
+ this._gridColor = ("gridColor" in params) ? ((typeof params.gridColor == "string") ? new Timeplot.Color(params.gridColor) : params.gridColor) : null,
+ this._gridLineWidth = ("gridLineWidth" in params) ? params.gridLineWidth : 0.5;
+ this._axisLabelsPlacement = ("axisLabelsPlacement" in params) ? params.axisLabelsPlacement : "right";
+ this._gridSpacing = ("gridSpacing" in params) ? params.gridStep : 50;
+ this._gridType = ("gridType" in params) ? params.gridType : "short";
+ this._gridShortSize = ("gridShortSize" in params) ? params.gridShortSize : 10;
+ this._minValue = ("min" in params) ? params.min : null;
+ this._maxValue = ("max" in params) ? params.max : null;
+ this._linMap = {
+ direct: function(v) {
+ return v;
+ },
+ inverse: function(y) {
+ return y;
+ }
+ }
+ this._map = this._linMap;
+ this._labels = [];
+ this._grid = [];
+}
+
+Timeplot.DefaultValueGeometry.prototype = {
+
+ /**
+ * Since geometries can be reused across timeplots, we need to call this function
+ * before we can paint using this geometry.
+ */
+ setTimeplot: function(timeplot) {
+ this._timeplot = timeplot;
+ this._canvas = timeplot.getCanvas();
+ this.reset();
+ },
+
+ /**
+ * Called by all the plot layers this geometry is associated with
+ * to update the value range. Unless min/max values are specified
+ * in the parameters, the biggest value range will be used.
+ */
+ setRange: function(range) {
+ if ((this._minValue == null) || ((this._minValue != null) && (range.min < this._minValue))) {
+ this._minValue = range.min;
+ }
+ if ((this._maxValue == null) || ((this._maxValue != null) && (range.max * 1.05 > this._maxValue))) {
+ this._maxValue = range.max * 1.05; // get a little more head room to avoid hitting the ceiling
+ }
+
+ this._updateMappedValues();
+
+ if (!(this._minValue == 0 && this._maxValue == 0)) {
+ this._grid = this._calculateGrid();
+ }
+ },
+
+ /**
+ * Called after changing ranges or canvas size to reset the grid values
+ */
+ reset: function() {
+ this._clearLabels();
+ this._updateMappedValues();
+ this._grid = this._calculateGrid();
+ },
+
+ /**
+ * Map the given value to a y screen coordinate.
+ */
+ toScreen: function(value) {
+ if (this._canvas && this._maxValue) {
+ var v = value - this._minValue;
+ return this._canvas.height * (this._map.direct(v)) / this._mappedRange;
+ } else {
+ return -50;
+ }
+ },
+
+ /**
+ * Map the given y screen coordinate to a value
+ */
+ fromScreen: function(y) {
+ if (this._canvas) {
+ return this._map.inverse(this._mappedRange * y / this._canvas.height) + this._minValue;
+ } else {
+ return 0;
+ }
+ },
+
+ /**
+ * Each geometry is also a painter and paints the value grid and grid labels.
+ */
+ paint: function() {
+ if (this._timeplot) {
+ var ctx = this._canvas.getContext('2d');
+
+ ctx.lineJoin = 'miter';
+
+ // paint grid
+ if (this._gridColor) {
+ var gridGradient = ctx.createLinearGradient(0,0,0,this._canvas.height);
+ gridGradient.addColorStop(0, this._gridColor.toHexString());
+ gridGradient.addColorStop(0.3, this._gridColor.toHexString());
+ gridGradient.addColorStop(1, "rgba(255,255,255,0.5)");
+
+ ctx.lineWidth = this._gridLineWidth;
+ ctx.strokeStyle = gridGradient;
+
+ for (var i = 0; i < this._grid.length; i++) {
+ var tick = this._grid[i];
+ var y = Math.floor(tick.y) + 0.5;
+ if (typeof tick.label != "undefined") {
+ if (this._axisLabelsPlacement == "left") {
+ var div = this._timeplot.putText(this._id + "-" + i, tick.label,"timeplot-grid-label",{
+ left: 4,
+ bottom: y + 2,
+ color: this._gridColor.toHexString(),
+ visibility: "hidden"
+ });
+ this._labels.push(div);
+ } else if (this._axisLabelsPlacement == "right") {
+ var div = this._timeplot.putText(this._id + "-" + i, tick.label, "timeplot-grid-label",{
+ right: 4,
+ bottom: y + 2,
+ color: this._gridColor.toHexString(),
+ visibility: "hidden"
+ });
+ this._labels.push(div);
+ }
+ if (y + div.clientHeight < this._canvas.height + 10) {
+ div.style.visibility = "visible"; // avoid the labels that would overflow
+ }
+ }
+
+ // draw grid
+ ctx.beginPath();
+ if (this._gridType == "long" || tick.label == 0) {
+ ctx.moveTo(0, y);
+ ctx.lineTo(this._canvas.width, y);
+ } else if (this._gridType == "short") {
+ if (this._axisLabelsPlacement == "left") {
+ ctx.moveTo(0, y);
+ ctx.lineTo(this._gridShortSize, y);
+ } else if (this._axisLabelsPlacement == "right") {
+ ctx.moveTo(this._canvas.width, y);
+ ctx.lineTo(this._canvas.width - this._gridShortSize, y);
+ }
+ }
+ ctx.stroke();
+ }
+ }
+
+ // paint axis
+ var axisGradient = ctx.createLinearGradient(0,0,0,this._canvas.height);
+ axisGradient.addColorStop(0, this._axisColor.toString());
+ axisGradient.addColorStop(0.5, this._axisColor.toString());
+ axisGradient.addColorStop(1, "rgba(255,255,255,0.5)");
+
+ ctx.lineWidth = 1;
+ ctx.strokeStyle = axisGradient;
+
+ // left axis
+ ctx.beginPath();
+ ctx.moveTo(0,this._canvas.height);
+ ctx.lineTo(0,0);
+ ctx.stroke();
+
+ // right axis
+ ctx.beginPath();
+ ctx.moveTo(this._canvas.width,0);
+ ctx.lineTo(this._canvas.width,this._canvas.height);
+ ctx.stroke();
+ }
+ },
+
+ /**
+ * Removes all the labels that were added by this geometry
+ */
+ _clearLabels: function() {
+ for (var i = 0; i < this._labels.length; i++) {
+ var l = this._labels[i];
+ var parent = l.parentNode;
+ if (parent) parent.removeChild(l);
+ }
+ },
+
+ /*
+ * This function calculates the grid spacing that it will be used
+ * by this geometry to draw the grid in order to reduce clutter.
+ */
+ _calculateGrid: function() {
+ var grid = [];
+
+ if (!this._canvas || this._valueRange == 0) return grid;
+
+ var power = 0;
+ if (this._valueRange > 1) {
+ while (Math.pow(10,power) < this._valueRange) {
+ power++;
+ }
+ power--;
+ } else {
+ while (Math.pow(10,power) > this._valueRange) {
+ power--;
+ }
+ }
+
+ var unit = Math.pow(10,power);
+ var inc = unit;
+ while (true) {
+ var dy = this.toScreen(this._minValue + inc);
+
+ while (dy < this._gridSpacing) {
+ inc += unit;
+ dy = this.toScreen(this._minValue + inc);
+ }
+
+ if (dy > 2 * this._gridSpacing) { // grids are too spaced out
+ unit /= 10;
+ inc = unit;
+ } else {
+ break;
+ }
+ }
+
+ var v = 0;
+ var y = this.toScreen(v);
+ if (this._minValue >= 0) {
+ while (y < this._canvas.height) {
+ if (y > 0) {
+ grid.push({ y: y, label: v });
+ }
+ v += inc;
+ y = this.toScreen(v);
+ }
+ } else if (this._maxValue <= 0) {
+ while (y > 0) {
+ if (y < this._canvas.height) {
+ grid.push({ y: y, label: v });
+ }
+ v -= inc;
+ y = this.toScreen(v);
+ }
+ } else {
+ while (y < this._canvas.height) {
+ if (y > 0) {
+ grid.push({ y: y, label: v });
+ }
+ v += inc;
+ y = this.toScreen(v);
+ }
+ v = -inc;
+ y = this.toScreen(v);
+ while (y > 0) {
+ if (y < this._canvas.height) {
+ grid.push({ y: y, label: v });
+ }
+ v -= inc;
+ y = this.toScreen(v);
+ }
+ }
+
+ return grid;
+ },
+
+ /*
+ * Update the values that are used by the paint function so that
+ * we don't have to calculate them at every repaint.
+ */
+ _updateMappedValues: function() {
+ this._valueRange = Math.abs(this._maxValue - this._minValue);
+ this._mappedRange = this._map.direct(this._valueRange);
+ }
+
+}
+
+// --------------------------------------------------
+
+/**
+ * This is the constructor for a Logarithmic value geometry, which
+ * is useful when plots have values in different magnitudes but
+ * exhibit similar trends and such trends want to be shown on the same
+ * plot (here a cartesian geometry would make the small magnitudes
+ * disappear).
+ *
+ * NOTE: this class extends Timeplot.DefaultValueGeometry and inherits
+ * all of the methods of that class. So refer to that class.
+ *
+ * @constructor
+ */
+Timeplot.LogarithmicValueGeometry = function(params) {
+ Timeplot.DefaultValueGeometry.apply(this, arguments);
+ this._logMap = {
+ direct: function(v) {
+ return Math.log(v + 1) / Math.log(10);
+ },
+ inverse: function(y) {
+ return Math.exp(Math.log(10) * y) - 1;
+ }
+ }
+ this._mode = "log";
+ this._map = this._logMap;
+ this._calculateGrid = this._logarithmicCalculateGrid;
+};
+
+Timeplot.LogarithmicValueGeometry.prototype._linearCalculateGrid = Timeplot.DefaultValueGeometry.prototype._calculateGrid;
+
+Object.extend(Timeplot.LogarithmicValueGeometry.prototype,Timeplot.DefaultValueGeometry.prototype);
+
+/*
+ * This function calculates the grid spacing that it will be used
+ * by this geometry to draw the grid in order to reduce clutter.
+ */
+Timeplot.LogarithmicValueGeometry.prototype._logarithmicCalculateGrid = function() {
+ var grid = [];
+
+ if (!this._canvas || this._valueRange == 0) return grid;
+
+ var v = 1;
+ var y = this.toScreen(v);
+ while (y < this._canvas.height || isNaN(y)) {
+ if (y > 0) {
+ grid.push({ y: y, label: v });
+ }
+ v *= 10;
+ y = this.toScreen(v);
+ }
+
+ return grid;
+};
+
+/**
+ * Turn the logarithmic scaling off.
+ */
+Timeplot.LogarithmicValueGeometry.prototype.actLinear = function() {
+ this._mode = "lin";
+ this._map = this._linMap;
+ this._calculateGrid = this._linearCalculateGrid;
+ this.reset();
+}
+
+/**
+ * Turn the logarithmic scaling on.
+ */
+Timeplot.LogarithmicValueGeometry.prototype.actLogarithmic = function() {
+ this._mode = "log";
+ this._map = this._logMap;
+ this._calculateGrid = this._logarithmicCalculateGrid;
+ this.reset();
+}
+
+/**
+ * Toggle logarithmic scaling seeting it to on if off and viceversa.
+ */
+Timeplot.LogarithmicValueGeometry.prototype.toggle = function() {
+ if (this._mode == "log") {
+ this.actLinear();
+ } else {
+ this.actLogarithmic();
+ }
+}
+
+// -----------------------------------------------------
+
+/**
+ * This is the constructor for the default time geometry.
+ *
+ * @constructor
+ */
+Timeplot.DefaultTimeGeometry = function(params) {
+ if (!params) params = {};
+ this._id = ("id" in params) ? params.id : "g" + Math.round(Math.random() * 1000000);
+ this._locale = ("locale" in params) ? params.locale : "en";
+ this._timeZone = ("timeZone" in params) ? params.timeZone : SimileAjax.DateTime.getTimezone();
+ this._labeler = ("labeller" in params) ? params.labeller : null;
+ this._axisColor = ("axisColor" in params) ? ((params.axisColor == "string") ? new Timeplot.Color(params.axisColor) : params.axisColor) : new Timeplot.Color("#606060"),
+ this._gridColor = ("gridColor" in params) ? ((params.gridColor == "string") ? new Timeplot.Color(params.gridColor) : params.gridColor) : null,
+ this._gridLineWidth = ("gridLineWidth" in params) ? params.gridLineWidth : 0.5;
+ this._axisLabelsPlacement = ("axisLabelsPlacement" in params) ? params.axisLabelsPlacement : "bottom";
+ this._gridStep = ("gridStep" in params) ? params.gridStep : 100;
+ this._gridStepRange = ("gridStepRange" in params) ? params.gridStepRange : 20;
+ this._min = ("min" in params) ? params.min : null;
+ this._max = ("max" in params) ? params.max : null;
+ this._timeValuePosition =("timeValuePosition" in params) ? params.timeValuePosition : "bottom";
+ this._unit = ("unit" in params) ? params.unit : Timeline.NativeDateUnit;
+ this._linMap = {
+ direct: function(t) {
+ return t;
+ },
+ inverse: function(x) {
+ return x;
+ }
+ }
+ this._map = this._linMap;
+ if (!this._labeler)
+ this._labeler = this._unit.createLabeller(this._locale, this._timeZone);
+ var dateParser = this._unit.getParser("iso8601");
+ if (this._min && !this._min.getTime) {
+ this._min = dateParser(this._min);
+ }
+ if (this._max && !this._max.getTime) {
+ this._max = dateParser(this._max);
+ }
+ this._labels = [];
+ this._grid = [];
+}
+
+Timeplot.DefaultTimeGeometry.prototype = {
+
+ /**
+ * Since geometries can be reused across timeplots, we need to call this function
+ * before we can paint using this geometry.
+ */
+ setTimeplot: function(timeplot) {
+ this._timeplot = timeplot;
+ this._canvas = timeplot.getCanvas();
+ this.reset();
+ },
+
+ /**
+ * Called by all the plot layers this geometry is associated with
+ * to update the time range. Unless min/max values are specified
+ * in the parameters, the biggest range will be used.
+ */
+ setRange: function(range) {
+ if (this._min) {
+ this._earliestDate = this._min;
+ } else if (range.earliestDate && ((this._earliestDate == null) || ((this._earliestDate != null) && (range.earliestDate.getTime() < this._earliestDate.getTime())))) {
+ this._earliestDate = range.earliestDate;
+ }
+
+ if (this._max) {
+ this._latestDate = this._max;
+ } else if (range.latestDate && ((this._latestDate == null) || ((this._latestDate != null) && (range.latestDate.getTime() > this._latestDate.getTime())))) {
+ this._latestDate = range.latestDate;
+ }
+
+ if (!this._earliestDate && !this._latestDate) {
+ this._grid = [];
+ } else {
+ this.reset();
+ }
+ },
+
+ /**
+ * Called after changing ranges or canvas size to reset the grid values
+ */
+ reset: function() {
+ this._updateMappedValues();
+ if (this._canvas) this._grid = this._calculateGrid();
+ },
+
+ /**
+ * Map the given date to a x screen coordinate.
+ */
+ toScreen: function(time) {
+ if (this._canvas && this._latestDate) {
+ var t = time - this._earliestDate.getTime();
+ var fraction = (this._mappedPeriod > 0) ? this._map.direct(t) / this._mappedPeriod : 0;
+ return this._canvas.width * fraction;
+ } else {
+ return -50;
+ }
+ },
+
+ /**
+ * Map the given x screen coordinate to a date.
+ */
+ fromScreen: function(x) {
+ if (this._canvas) {
+ return this._map.inverse(this._mappedPeriod * x / this._canvas.width) + this._earliestDate.getTime();
+ } else {
+ return 0;
+ }
+ },
+
+ /**
+ * Get a period (in milliseconds) this time geometry spans.
+ */
+ getPeriod: function() {
+ return this._period;
+ },
+
+ /**
+ * Return the labeler that has been associated with this time geometry
+ */
+ getLabeler: function() {
+ return this._labeler;
+ },
+
+ /**
+ * Return the time unit associated with this time geometry
+ */
+ getUnit: function() {
+ return this._unit;
+ },
+
+ /**
+ * Each geometry is also a painter and paints the value grid and grid labels.
+ */
+ paint: function() {
+ if (this._canvas) {
+ var unit = this._unit;
+ var ctx = this._canvas.getContext('2d');
+
+ var gradient = ctx.createLinearGradient(0,0,0,this._canvas.height);
+
+ ctx.strokeStyle = gradient;
+ ctx.lineWidth = this._gridLineWidth;
+ ctx.lineJoin = 'miter';
+
+ // paint grid
+ if (this._gridColor) {
+ gradient.addColorStop(0, this._gridColor.toString());
+ gradient.addColorStop(1, "rgba(255,255,255,0.9)");
+
+ for (var i = 0; i < this._grid.length; i++) {
+ var tick = this._grid[i];
+ var x = Math.floor(tick.x) + 0.5;
+ if (this._axisLabelsPlacement == "top") {
+ var div = this._timeplot.putText(this._id + "-" + i, tick.label,"timeplot-grid-label",{
+ left: x + 4,
+ top: 2,
+ visibility: "hidden"
+ });
+ this._labels.push(div);
+ } else if (this._axisLabelsPlacement == "bottom") {
+ var div = this._timeplot.putText(this._id + "-" + i, tick.label, "timeplot-grid-label",{
+ left: x + 4,
+ bottom: 2,
+ visibility: "hidden"
+ });
+ this._labels.push(div);
+ }
+ if (x + div.clientWidth < this._canvas.width + 10) {
+ div.style.visibility = "visible"; // avoid the labels that would overflow
+ }
+
+ // draw separator
+ ctx.beginPath();
+ ctx.moveTo(x,0);
+ ctx.lineTo(x,this._canvas.height);
+ ctx.stroke();
+ }
+ }
+
+ // paint axis
+ gradient.addColorStop(0, this._axisColor.toString());
+ gradient.addColorStop(1, "rgba(255,255,255,0.5)");
+
+ ctx.lineWidth = 1;
+ gradient.addColorStop(0, this._axisColor.toString());
+
+ ctx.beginPath();
+ ctx.moveTo(0,0);
+ ctx.lineTo(this._canvas.width,0);
+ ctx.stroke();
+ }
+ },
+
+ /*
+ * This function calculates the grid spacing that it will be used
+ * by this geometry to draw the grid in order to reduce clutter.
+ */
+ _calculateGrid: function() {
+ var grid = [];
+
+ var time = SimileAjax.DateTime;
+ var u = this._unit;
+ var p = this._period;
+
+ if (p == 0) return grid;
+
+ // find the time units nearest to the time period
+ if (p > time.gregorianUnitLengths[time.MILLENNIUM]) {
+ unit = time.MILLENNIUM;
+ } else {
+ for (var unit = time.MILLENNIUM; unit > 0; unit--) {
+ if (time.gregorianUnitLengths[unit-1] <= p && p < time.gregorianUnitLengths[unit]) {
+ unit--;
+ break;
+ }
+ }
+ }
+
+ var t = u.cloneValue(this._earliestDate);
+
+ do {
+ time.roundDownToInterval(t, unit, this._timeZone, 1, 0);
+ var x = this.toScreen(u.toNumber(t));
+ switch (unit) {
+ case time.SECOND:
+ var l = t.toLocaleTimeString();
+ break;
+ case time.MINUTE:
+ var m = t.getMinutes();
+ var l = t.getHours() + ":" + ((m < 10) ? "0" : "") + m;
+ break;
+ case time.HOUR:
+ var l = t.getHours() + ":00";
+ break;
+ case time.DAY:
+ case time.WEEK:
+ case time.MONTH:
+ var l = t.toLocaleDateString();
+ break;
+ case time.YEAR:
+ case time.DECADE:
+ case time.CENTURY:
+ case time.MILLENNIUM:
+ var l = t.getUTCFullYear();
+ break;
+ }
+ if (x > 0) {
+ grid.push({ x: x, label: l });
+ }
+ time.incrementByInterval(t, unit, this._timeZone);
+ } while (t.getTime() < this._latestDate.getTime());
+
+ return grid;
+ },
+
+ /*
+ * Clear labels generated by this time geometry.
+ */
+ _clearLabels: function() {
+ for (var i = 0; i < this._labels.length; i++) {
+ var l = this._labels[i];
+ var parent = l.parentNode;
+ if (parent) parent.removeChild(l);
+ }
+ },
+
+ /*
+ * Update the values that are used by the paint function so that
+ * we don't have to calculate them at every repaint.
+ */
+ _updateMappedValues: function() {
+ if (this._latestDate && this._earliestDate) {
+ this._period = this._latestDate.getTime() - this._earliestDate.getTime();
+ this._mappedPeriod = this._map.direct(this._period);
+ } else {
+ this._period = 0;
+ this._mappedPeriod = 0;
+ }
+ }
+
+}
+
+// --------------------------------------------------------------
+
+/**
+ * This is the constructor for the magnifying time geometry.
+ * Users can interact with this geometry and 'magnify' certain areas of the
+ * plot to see the plot enlarged and resolve details that would otherwise
+ * get lost or cluttered with a linear time geometry.
+ *
+ * @constructor
+ */
+Timeplot.MagnifyingTimeGeometry = function(params) {
+ Timeplot.DefaultTimeGeometry.apply(this, arguments);
+
+ var g = this;
+ this._MagnifyingMap = {
+ direct: function(t) {
+ if (t < g._leftTimeMargin) {
+ var x = t * g._leftRate;
+ } else if ( g._leftTimeMargin < t && t < g._rightTimeMargin ) {
+ var x = t * g._expandedRate + g._expandedTimeTranslation;
+ } else {
+ var x = t * g._rightRate + g._rightTimeTranslation;
+ }
+ return x;
+ },
+ inverse: function(x) {
+ if (x < g._leftScreenMargin) {
+ var t = x / g._leftRate;
+ } else if ( g._leftScreenMargin < x && x < g._rightScreenMargin ) {
+ var t = x / g._expandedRate + g._expandedScreenTranslation;
+ } else {
+ var t = x / g._rightRate + g._rightScreenTranslation;
+ }
+ return t;
+ }
+ }
+
+ this._mode = "lin";
+ this._map = this._linMap;
+};
+
+Object.extend(Timeplot.MagnifyingTimeGeometry.prototype,Timeplot.DefaultTimeGeometry.prototype);
+
+/**
+ * Initialize this geometry associating it with the given timeplot and
+ * register the geometry event handlers to the timeplot so that it can
+ * interact with the user.
+ */
+Timeplot.MagnifyingTimeGeometry.prototype.initialize = function(timeplot) {
+ Timeplot.DefaultTimeGeometry.prototype.initialize.apply(this, arguments);
+
+ if (!this._lens) {
+ this._lens = this._timeplot.putDiv("lens","timeplot-lens");
+ }
+
+ var period = 1000 * 60 * 60 * 24 * 30; // a month in the magnifying lens
+
+ var geometry = this;
+
+ var magnifyWith = function(lens) {
+ var aperture = lens.clientWidth;
+ var loc = geometry._timeplot.locate(lens);
+ geometry.setMagnifyingParams(loc.x + aperture / 2, aperture, period);
+ geometry.actMagnifying();
+ geometry._timeplot.paint();
+ }
+
+ var canvasMouseDown = function(elmt, evt, target) {
+ geometry._canvas.startCoords = SimileAjax.DOM.getEventRelativeCoordinates(evt,elmt);
+ geometry._canvas.pressed = true;
+ }
+
+ var canvasMouseUp = function(elmt, evt, target) {
+ geometry._canvas.pressed = false;
+ var coords = SimileAjax.DOM.getEventRelativeCoordinates(evt,elmt);
+ if (Timeplot.Math.isClose(coords,geometry._canvas.startCoords,5)) {
+ geometry._lens.style.display = "none";
+ geometry.actLinear();
+ geometry._timeplot.paint();
+ } else {
+ geometry._lens.style.cursor = "move";
+ magnifyWith(geometry._lens);
+ }
+ }
+
+ var canvasMouseMove = function(elmt, evt, target) {
+ if (geometry._canvas.pressed) {
+ var coords = SimileAjax.DOM.getEventRelativeCoordinates(evt,elmt);
+ if (coords.x < 0) coords.x = 0;
+ if (coords.x > geometry._canvas.width) coords.x = geometry._canvas.width;
+ geometry._timeplot.placeDiv(geometry._lens, {
+ left: geometry._canvas.startCoords.x,
+ width: coords.x - geometry._canvas.startCoords.x,
+ bottom: 0,
+ height: geometry._canvas.height,
+ display: "block"
+ });
+ }
+ }
+
+ var lensMouseDown = function(elmt, evt, target) {
+ geometry._lens.startCoords = SimileAjax.DOM.getEventRelativeCoordinates(evt,elmt);;
+ geometry._lens.pressed = true;
+ }
+
+ var lensMouseUp = function(elmt, evt, target) {
+ geometry._lens.pressed = false;
+ }
+
+ var lensMouseMove = function(elmt, evt, target) {
+ if (geometry._lens.pressed) {
+ var coords = SimileAjax.DOM.getEventRelativeCoordinates(evt,elmt);
+ var lens = geometry._lens;
+ var left = lens.offsetLeft + coords.x - lens.startCoords.x;
+ if (left < geometry._timeplot._paddingX) left = geometry._timeplot._paddingX;
+ if (left + lens.clientWidth > geometry._canvas.width - geometry._timeplot._paddingX) left = geometry._canvas.width - lens.clientWidth + geometry._timeplot._paddingX;
+ lens.style.left = left;
+ magnifyWith(lens);
+ }
+ }
+
+ if (!this._canvas.instrumented) {
+ SimileAjax.DOM.registerEvent(this._canvas, "mousedown", canvasMouseDown);
+ SimileAjax.DOM.registerEvent(this._canvas, "mousemove", canvasMouseMove);
+ SimileAjax.DOM.registerEvent(this._canvas, "mouseup" , canvasMouseUp);
+ SimileAjax.DOM.registerEvent(this._canvas, "mouseup" , lensMouseUp);
+ this._canvas.instrumented = true;
+ }
+
+ if (!this._lens.instrumented) {
+ SimileAjax.DOM.registerEvent(this._lens, "mousedown", lensMouseDown);
+ SimileAjax.DOM.registerEvent(this._lens, "mousemove", lensMouseMove);
+ SimileAjax.DOM.registerEvent(this._lens, "mouseup" , lensMouseUp);
+ SimileAjax.DOM.registerEvent(this._lens, "mouseup" , canvasMouseUp);
+ this._lens.instrumented = true;
+ }
+}
+
+/**
+ * Set the Magnifying parameters. c is the location in pixels where the Magnifying
+ * center should be located in the timeplot, a is the aperture in pixel of
+ * the Magnifying and b is the time period in milliseconds that the Magnifying
+ * should span.
+ */
+Timeplot.MagnifyingTimeGeometry.prototype.setMagnifyingParams = function(c,a,b) {
+ a = a / 2;
+ b = b / 2;
+
+ var w = this._canvas.width;
+ var d = this._period;
+
+ if (c < 0) c = 0;
+ if (c > w) c = w;
+
+ if (c - a < 0) a = c;
+ if (c + a > w) a = w - c;
+
+ var ct = this.fromScreen(c) - this._earliestDate.getTime();
+ if (ct - b < 0) b = ct;
+ if (ct + b > d) b = d - ct;
+
+ this._centerX = c;
+ this._centerTime = ct;
+ this._aperture = a;
+ this._aperturePeriod = b;
+
+ this._leftScreenMargin = this._centerX - this._aperture;
+ this._rightScreenMargin = this._centerX + this._aperture;
+ this._leftTimeMargin = this._centerTime - this._aperturePeriod;
+ this._rightTimeMargin = this._centerTime + this._aperturePeriod;
+
+ this._leftRate = (c - a) / (ct - b);
+ this._expandedRate = a / b;
+ this._rightRate = (w - c - a) / (d - ct - b);
+
+ this._expandedTimeTranslation = this._centerX - this._centerTime * this._expandedRate;
+ this._expandedScreenTranslation = this._centerTime - this._centerX / this._expandedRate;
+ this._rightTimeTranslation = (c + a) - (ct + b) * this._rightRate;
+ this._rightScreenTranslation = (ct + b) - (c + a) / this._rightRate;
+
+ this._updateMappedValues();
+}
+
+/*
+ * Turn magnification off.
+ */
+Timeplot.MagnifyingTimeGeometry.prototype.actLinear = function() {
+ this._mode = "lin";
+ this._map = this._linMap;
+ this.reset();
+}
+
+/*
+ * Turn magnification on.
+ */
+Timeplot.MagnifyingTimeGeometry.prototype.actMagnifying = function() {
+ this._mode = "Magnifying";
+ this._map = this._MagnifyingMap;
+ this.reset();
+}
+
+/*
+ * Toggle magnification.
+ */
+Timeplot.MagnifyingTimeGeometry.prototype.toggle = function() {
+ if (this._mode == "Magnifying") {
+ this.actLinear();
+ } else {
+ this.actMagnifying();
+ }
+}
+
Added: openoffice/ooo-site/trunk/content/scripts/api.simile-widgets.org/timeplot/1.1/scripts/math.js
URL: http://svn.apache.org/viewvc/openoffice/ooo-site/trunk/content/scripts/api.simile-widgets.org/timeplot/1.1/scripts/math.js?rev=1795424&view=auto
==============================================================================
--- openoffice/ooo-site/trunk/content/scripts/api.simile-widgets.org/timeplot/1.1/scripts/math.js (added)
+++ openoffice/ooo-site/trunk/content/scripts/api.simile-widgets.org/timeplot/1.1/scripts/math.js Wed May 17 15:29:56 2017
@@ -0,0 +1,193 @@
+/**
+ * Math Utility functions
+ *
+ * @fileOverview Math Utility functions
+ * @name Math
+ */
+
+Timeplot.Math = {
+
+ /**
+ * Evaluates the range (min and max values) of the given array
+ */
+ range: function(f) {
+ var F = f.length;
+ var min = Number.MAX_VALUE;
+ var max = Number.MIN_VALUE;
+
+ for (var t = 0; t < F; t++) {
+ var value = f[t];
+ if (value < min) {
+ min = value;
+ }
+ if (value > max) {
+ max = value;
+ }
+ }
+
+ return {
+ min: min,
+ max: max
+ }
+ },
+
+ /**
+ * Evaluates the windows average of a given array based on the
+ * given window size
+ */
+ movingAverage: function(f, size) {
+ var F = f.length;
+ var g = new Array(F);
+ for (var n = 0; n < F; n++) {
+ var value = 0;
+ for (var m = n - size; m < n + size; m++) {
+ if (m < 0) {
+ var v = f[0];
+ } else if (m >= F) {
+ var v = g[n-1];
+ } else {
+ var v = f[m];
+ }
+ value += v;
+ }
+ g[n] = value / (2 * size);
+ }
+ return g;
+ },
+
+ /**
+ * Returns an array with the integral of the given array
+ */
+ integral: function(f) {
+ var F = f.length;
+
+ var g = new Array(F);
+ var sum = 0;
+
+ for (var t = 0; t < F; t++) {
+ sum += f[t];
+ g[t] = sum;
+ }
+
+ return g;
+ },
+
+ /**
+ * Normalizes an array so that its complete integral is 1.
+ * This is useful to obtain arrays that preserve the overall
+ * integral of a convolution.
+ */
+ normalize: function(f) {
+ var F = f.length;
+ var sum = 0.0;
+
+ for (var t = 0; t < F; t++) {
+ sum += f[t];
+ }
+
+ for (var t = 0; t < F; t++) {
+ f[t] /= sum;
+ }
+
+ return f;
+ },
+
+ /**
+ * Calculates the convolution between two arrays
+ */
+ convolution: function(f,g) {
+ var F = f.length;
+ var G = g.length;
+
+ var c = new Array(F);
+
+ for (var m = 0; m < F; m++) {
+ var r = 0;
+ var end = (m + G < F) ? m + G : F;
+ for (var n = m; n < end; n++) {
+ var a = f[n - G];
+ var b = g[n - m];
+ r += a * b;
+ }
+ c[m] = r;
+ }
+
+ return c;
+ },
+
+ // ------ Array generators -------------------------------------------------
+ // Functions that generate arrays based on mathematical functions
+ // Normally these are used to produce operators by convolving them with the input array
+ // The returned arrays have the property of having
+
+ /**
+ * Generate the heavyside step function of given size
+ */
+ heavyside: function(size) {
+ var f = new Array(size);
+ var value = 1 / size;
+ for (var t = 0; t < size; t++) {
+ f[t] = value;
+ }
+ return f;
+ },
+
+ /**
+ * Generate the gaussian function so that at the given 'size' it has value 'threshold'
+ * and make sure its integral is one.
+ */
+ gaussian: function(size, threshold) {
+ with (Math) {
+ var radius = size / 2;
+ var variance = radius * radius / log(threshold);
+ var g = new Array(size);
+ for (var t = 0; t < size; t++) {
+ var l = t - radius;
+ g[t] = exp(-variance * l * l);
+ }
+ }
+
+ return this.normalize(g);
+ },
+
+ // ---- Utility Methods --------------------------------------------------
+
+ /**
+ * Return x with n significant figures
+ */
+ round: function(x,n) {
+ with (Math) {
+ if (abs(x) > 1) {
+ var l = floor(log(x)/log(10));
+ var d = round(exp((l-n+1)*log(10)));
+ var y = round(round(x / d) * d);
+ return y;
+ } else {
+ log("FIXME(SM): still to implement for 0 < abs(x) < 1");
+ return x;
+ }
+ }
+ },
+
+ /**
+ * Return the hyperbolic tangent of x
+ */
+ tanh: function(x) {
+ if (x > 5) {
+ return 1;
+ } else if (x < 5) {
+ return -1;
+ } else {
+ var expx2 = Math.exp(2 * x);
+ return (expx2 - 1) / (expx2 + 1);
+ }
+ },
+
+ /**
+ * Returns true if |a.x - b.x| < value && | a.y - b.y | < value
+ */
+ isClose: function(a,b,value) {
+ return (a && b && Math.abs(a.x - b.x) < value && Math.abs(a.y - b.y) < value);
+ }
+
+}
\ No newline at end of file
Added: openoffice/ooo-site/trunk/content/scripts/api.simile-widgets.org/timeplot/1.1/scripts/plot.js
URL: http://svn.apache.org/viewvc/openoffice/ooo-site/trunk/content/scripts/api.simile-widgets.org/timeplot/1.1/scripts/plot.js?rev=1795424&view=auto
==============================================================================
--- openoffice/ooo-site/trunk/content/scripts/api.simile-widgets.org/timeplot/1.1/scripts/plot.js (added)
+++ openoffice/ooo-site/trunk/content/scripts/api.simile-widgets.org/timeplot/1.1/scripts/plot.js Wed May 17 15:29:56 2017
@@ -0,0 +1,400 @@
+/**
+ * Plot Layer
+ *
+ * @fileOverview Plot Layer
+ * @name Plot
+ */
+
+/**
+ * A plot layer is the main building block for timeplots and it's the object
+ * that is responsible for painting the plot itself. Each plot needs to have
+ * a time geometry, either a DataSource (for time series
+ * plots) or an EventSource (for event plots) and a value geometry in case
+ * of time series plots. Such parameters are passed along
+ * in the 'plotInfo' map.
+ *
+ * @constructor
+ */
+Timeplot.Plot = function(timeplot, plotInfo) {
+ this._timeplot = timeplot;
+ this._canvas = timeplot.getCanvas();
+ this._plotInfo = plotInfo;
+ this._id = plotInfo.id;
+ this._timeGeometry = plotInfo.timeGeometry;
+ this._valueGeometry = plotInfo.valueGeometry;
+ this._theme = new Timeline.getDefaultTheme();
+ this._dataSource = plotInfo.dataSource;
+ this._eventSource = plotInfo.eventSource;
+ this._bubble = null;
+};
+
+Timeplot.Plot.prototype = {
+
+ /**
+ * Initialize the plot layer
+ */
+ initialize: function() {
+ if (this._dataSource && this._dataSource.getValue) {
+ this._timeFlag = this._timeplot.putDiv("timeflag","timeplot-timeflag");
+ this._valueFlag = this._timeplot.putDiv(this._id + "valueflag","timeplot-valueflag");
+ this._valueFlagLineLeft = this._timeplot.putDiv(this._id + "valueflagLineLeft","timeplot-valueflag-line");
+ this._valueFlagLineRight = this._timeplot.putDiv(this._id + "valueflagLineRight","timeplot-valueflag-line");
+ if (!this._valueFlagLineLeft.firstChild) {
+ this._valueFlagLineLeft.appendChild(SimileAjax.Graphics.createTranslucentImage(Timeplot.urlPrefix + "images/line_left.png"));
+ this._valueFlagLineRight.appendChild(SimileAjax.Graphics.createTranslucentImage(Timeplot.urlPrefix + "images/line_right.png"));
+ }
+ this._valueFlagPole = this._timeplot.putDiv(this._id + "valuepole","timeplot-valueflag-pole");
+
+ var opacity = this._plotInfo.valuesOpacity;
+
+ SimileAjax.Graphics.setOpacity(this._timeFlag, opacity);
+ SimileAjax.Graphics.setOpacity(this._valueFlag, opacity);
+ SimileAjax.Graphics.setOpacity(this._valueFlagLineLeft, opacity);
+ SimileAjax.Graphics.setOpacity(this._valueFlagLineRight, opacity);
+ SimileAjax.Graphics.setOpacity(this._valueFlagPole, opacity);
+
+ var plot = this;
+
+ var mouseOverHandler = function(elmt, evt, target) {
+ if (plot._plotInfo.showValues) {
+ plot._valueFlag.style.display = "block";
+ mouseMoveHandler(elmt, evt, target);
+ }
+ }
+
+ var day = 24 * 60 * 60 * 1000;
+ var month = 30 * day;
+
+ var mouseMoveHandler = function(elmt, evt, target) {
+ if (typeof SimileAjax != "undefined" && plot._plotInfo.showValues) {
+ var c = plot._canvas;
+ var x = Math.round(SimileAjax.DOM.getEventRelativeCoordinates(evt,plot._canvas).x);
+ if (x > c.width) x = c.width;
+ if (isNaN(x) || x < 0) x = 0;
+ var t = plot._timeGeometry.fromScreen(x);
+ if (t == 0) { // something is wrong
+ plot._valueFlag.style.display = "none";
+ return;
+ }
+
+ var validTime = plot._dataSource.getClosestValidTime(t);
+ x = plot._timeGeometry.toScreen(validTime);
+ var v = plot._dataSource.getValue(validTime);
+ if (plot._plotInfo.roundValues) v = Math.round(v);
+ plot._valueFlag.innerHTML = new String(v);
+ var d = new Date(validTime);
+ var p = plot._timeGeometry.getPeriod();
+ if (p < day) {
+ plot._timeFlag.innerHTML = d.toLocaleTimeString();
+ } else if (p > month) {
+ plot._timeFlag.innerHTML = d.toLocaleDateString();
+ } else {
+ plot._timeFlag.innerHTML = d.toLocaleString();
+ }
+
+ var tw = plot._timeFlag.clientWidth;
+ var th = plot._timeFlag.clientHeight;
+ var tdw = Math.round(tw / 2);
+ var vw = plot._valueFlag.clientWidth;
+ var vh = plot._valueFlag.clientHeight;
+ var y = plot._valueGeometry.toScreen(v);
+
+ if (x + tdw > c.width) {
+ var tx = c.width - tdw;
+ } else if (x - tdw < 0) {
+ var tx = tdw;
+ } else {
+ var tx = x;
+ }
+
+ if (plot._timeGeometry._timeValuePosition == "top") {
+ plot._timeplot.placeDiv(plot._valueFlagPole, {
+ left: x,
+ top: th - 5,
+ height: c.height - y - th + 6,
+ display: "block"
+ });
+ plot._timeplot.placeDiv(plot._timeFlag,{
+ left: tx - tdw,
+ top: -6,
+ display: "block"
+ });
+ } else {
+ plot._timeplot.placeDiv(plot._valueFlagPole, {
+ left: x,
+ bottom: th - 5,
+ height: y - th + 6,
+ display: "block"
+ });
+ plot._timeplot.placeDiv(plot._timeFlag,{
+ left: tx - tdw,
+ bottom: -6,
+ display: "block"
+ });
+ }
+
+ if (x + vw + 14 > c.width && y + vh + 4 > c.height) {
+ plot._valueFlagLineLeft.style.display = "none";
+ plot._timeplot.placeDiv(plot._valueFlagLineRight,{
+ left: x - 14,
+ bottom: y - 14,
+ display: "block"
+ });
+ plot._timeplot.placeDiv(plot._valueFlag,{
+ left: x - vw - 13,
+ bottom: y - vh - 13,
+ display: "block"
+ });
+ } else if (x + vw + 14 > c.width && y + vh + 4 < c.height) {
+ plot._valueFlagLineRight.style.display = "none";
+ plot._timeplot.placeDiv(plot._valueFlagLineLeft,{
+ left: x - 14,
+ bottom: y,
+ display: "block"
+ });
+ plot._timeplot.placeDiv(plot._valueFlag,{
+ left: x - vw - 13,
+ bottom: y + 13,
+ display: "block"
+ });
+ } else if (x + vw + 14 < c.width && y + vh + 4 > c.height) {
+ plot._valueFlagLineRight.style.display = "none";
+ plot._timeplot.placeDiv(plot._valueFlagLineLeft,{
+ left: x,
+ bottom: y - 13,
+ display: "block"
+ });
+ plot._timeplot.placeDiv(plot._valueFlag,{
+ left: x + 13,
+ bottom: y - 13,
+ display: "block"
+ });
+ } else {
+ plot._valueFlagLineLeft.style.display = "none";
+ plot._timeplot.placeDiv(plot._valueFlagLineRight,{
+ left: x,
+ bottom: y,
+ display: "block"
+ });
+ plot._timeplot.placeDiv(plot._valueFlag,{
+ left: x + 13,
+ bottom: y + 13,
+ display: "block"
+ });
+ }
+ }
+ }
+
+ var timeplotElement = this._timeplot.getElement();
+ SimileAjax.DOM.registerEvent(timeplotElement, "mouseover", mouseOverHandler);
+ SimileAjax.DOM.registerEvent(timeplotElement, "mousemove", mouseMoveHandler);
+ }
+ },
+
+ /**
+ * Dispose the plot layer and all the data sources and listeners associated to it
+ */
+ dispose: function() {
+ if (this._dataSource) {
+ this._dataSource.removeListener(this._paintingListener);
+ this._paintingListener = null;
+ this._dataSource.dispose();
+ this._dataSource = null;
+ }
+ },
+
+ /**
+ * Hide the values
+ */
+ hideValues: function() {
+ if (this._valueFlag) this._valueFlag.style.display = "none";
+ if (this._timeFlag) this._timeFlag.style.display = "none";
+ if (this._valueFlagLineLeft) this._valueFlagLineLeft.style.display = "none";
+ if (this._valueFlagLineRight) this._valueFlagLineRight.style.display = "none";
+ if (this._valueFlagPole) this._valueFlagPole.style.display = "none";
+ },
+
+ /**
+ * Return the data source of this plot layer (it could be either a DataSource or an EventSource)
+ */
+ getDataSource: function() {
+ return (this._dataSource) ? this._dataSource : this._eventSource;
+ },
+
+ /**
+ * Return the time geometry associated with this plot layer
+ */
+ getTimeGeometry: function() {
+ return this._timeGeometry;
+ },
+
+ /**
+ * Return the value geometry associated with this plot layer
+ */
+ getValueGeometry: function() {
+ return this._valueGeometry;
+ },
+
+ /**
+ * Paint this plot layer
+ */
+ paint: function() {
+ var ctx = this._canvas.getContext('2d');
+
+ ctx.lineWidth = this._plotInfo.lineWidth;
+ ctx.lineJoin = 'miter';
+
+ if (this._dataSource) {
+ if (this._plotInfo.fillColor) {
+ if (this._plotInfo.fillGradient) {
+ var gradient = ctx.createLinearGradient(0,this._canvas.height,0,0);
+ gradient.addColorStop(0,this._plotInfo.fillColor.toString());
+ gradient.addColorStop(0.5,this._plotInfo.fillColor.toString());
+ gradient.addColorStop(1, 'rgba(255,255,255,0)');
+
+ ctx.fillStyle = gradient;
+ } else {
+ ctx.fillStyle = this._plotInfo.fillColor.toString();
+ }
+
+ ctx.beginPath();
+ ctx.moveTo(0,0);
+ this._plot(function(x,y) {
+ ctx.lineTo(x,y);
+ });
+ if (this._plotInfo.fillFrom == Number.NEGATIVE_INFINITY) {
+ ctx.lineTo(this._canvas.width, 0);
+ } else if (this._plotInfo.fillFrom == Number.POSITIVE_INFINITY) {
+ ctx.lineTo(this._canvas.width, this._canvas.height);
+ ctx.lineTo(0, this._canvas.height);
+ } else {
+ ctx.lineTo(this._canvas.width, this._valueGeometry.toScreen(this._plotInfo.fillFrom));
+ ctx.lineTo(0, this._valueGeometry.toScreen(this._plotInfo.fillFrom));
+ }
+ ctx.fill();
+ }
+
+ if (this._plotInfo.lineColor) {
+ ctx.strokeStyle = this._plotInfo.lineColor.toString();
+ ctx.beginPath();
+ var first = true;
+ this._plot(function(x,y) {
+ if (first) {
+ first = false;
+ ctx.moveTo(x,y);
+ }
+ ctx.lineTo(x,y);
+ });
+ ctx.stroke();
+ }
+
+ if (this._plotInfo.dotColor) {
+ ctx.fillStyle = this._plotInfo.dotColor.toString();
+ var r = this._plotInfo.dotRadius;
+ this._plot(function(x,y) {
+ ctx.beginPath();
+ ctx.arc(x,y,r,0,2*Math.PI,true);
+ ctx.fill();
+ });
+ }
+ }
+
+ if (this._eventSource) {
+ var gradient = ctx.createLinearGradient(0,0,0,this._canvas.height);
+ gradient.addColorStop(1, 'rgba(255,255,255,0)');
+
+ ctx.strokeStyle = gradient;
+ ctx.fillStyle = gradient;
+ ctx.lineWidth = this._plotInfo.eventLineWidth;
+ ctx.lineJoin = 'miter';
+
+ var i = this._eventSource.getAllEventIterator();
+ while (i.hasNext()) {
+ var event = i.next();
+ var color = event.getColor();
+ color = (color) ? new Timeplot.Color(color) : this._plotInfo.lineColor;
+ var eventStart = event.getStart().getTime();
+ var eventEnd = event.getEnd().getTime();
+ if (eventStart == eventEnd) {
+ var c = color.toString();
+ gradient.addColorStop(0, c);
+ var start = this._timeGeometry.toScreen(eventStart);
+ start = Math.floor(start) + 0.5; // center it between two pixels (makes the rendering nicer)
+ var end = start;
+ ctx.beginPath();
+ ctx.moveTo(start,0);
+ ctx.lineTo(start,this._canvas.height);
+ ctx.stroke();
+ var x = start - 4;
+ var w = 7;
+ } else {
+ var c = color.toString(0.5);
+ gradient.addColorStop(0, c);
+ var start = this._timeGeometry.toScreen(eventStart);
+ start = Math.floor(start) + 0.5; // center it between two pixels (makes the rendering nicer)
+ var end = this._timeGeometry.toScreen(eventEnd);
+ end = Math.floor(end) + 0.5; // center it between two pixels (makes the rendering nicer)
+ ctx.fillRect(start,0,end - start, this._canvas.height);
+ var x = start;
+ var w = end - start - 1;
+ }
+
+ var div = this._timeplot.putDiv(event.getID(),"timeplot-event-box",{
+ left: Math.round(x),
+ width: Math.round(w),
+ top: 0,
+ height: this._canvas.height - 1
+ });
+
+ var plot = this;
+ var clickHandler = function(event) {
+ return function(elmt, evt, target) {
+ var doc = plot._timeplot.getDocument();
+ plot._closeBubble();
+ var coords = SimileAjax.DOM.getEventPageCoordinates(evt);
+ var elmtCoords = SimileAjax.DOM.getPageCoordinates(elmt);
+ plot._bubble = SimileAjax.Graphics.createBubbleForPoint(coords.x, elmtCoords.top + plot._canvas.height, plot._plotInfo.bubbleWidth, plot._plotInfo.bubbleHeight, "bottom");
+ event.fillInfoBubble(plot._bubble.content, plot._theme, plot._timeGeometry.getLabeler());
+ }
+ };
+ var mouseOverHandler = function(elmt, evt, target) {
+ elmt.oldClass = elmt.className;
+ elmt.className = elmt.className + " timeplot-event-box-highlight";
+ };
+ var mouseOutHandler = function(elmt, evt, target) {
+ elmt.className = elmt.oldClass;
+ elmt.oldClass = null;
+ }
+
+ if (!div.instrumented) {
+ SimileAjax.DOM.registerEvent(div, "click" , clickHandler(event));
+ SimileAjax.DOM.registerEvent(div, "mouseover", mouseOverHandler);
+ SimileAjax.DOM.registerEvent(div, "mouseout" , mouseOutHandler);
+ div.instrumented = true;
+ }
+ }
+ }
+ },
+
+ _plot: function(f) {
+ var data = this._dataSource.getData();
+ if (data) {
+ var times = data.times;
+ var values = data.values;
+ var T = times.length;
+ for (var t = 0; t < T; t++) {
+ var x = this._timeGeometry.toScreen(times[t]);
+ var y = this._valueGeometry.toScreen(values[t]);
+ f(x, y);
+ }
+ }
+ },
+
+ _closeBubble: function() {
+ if (this._bubble != null) {
+ this._bubble.close();
+ this._bubble = null;
+ }
+ }
+
+}
\ No newline at end of file
Added: openoffice/ooo-site/trunk/content/scripts/api.simile-widgets.org/timeplot/1.1/scripts/processor.js
URL: http://svn.apache.org/viewvc/openoffice/ooo-site/trunk/content/scripts/api.simile-widgets.org/timeplot/1.1/scripts/processor.js?rev=1795424&view=auto
==============================================================================
--- openoffice/ooo-site/trunk/content/scripts/api.simile-widgets.org/timeplot/1.1/scripts/processor.js (added)
+++ openoffice/ooo-site/trunk/content/scripts/api.simile-widgets.org/timeplot/1.1/scripts/processor.js Wed May 17 15:29:56 2017
@@ -0,0 +1,122 @@
+/**
+ * Processing Data Source
+ *
+ * @fileOverview Processing Data Source and Operators
+ * @name Processor
+ */
+
+/* -----------------------------------------------------------------------------
+ * Operators
+ *
+ * These are functions that can be used directly as Timeplot.Processor operators
+ * ----------------------------------------------------------------------------- */
+
+Timeplot.Operator = {
+
+ /**
+ * This is the operator used when you want to draw the cumulative sum
+ * of a time series and not, for example, their daily values.
+ */
+ sum: function(data, params) {
+ return Timeplot.Math.integral(data.values);
+ },
+
+ /**
+ * This is the operator that is used to 'smooth' a given time series
+ * by taking the average value of a moving window centered around
+ * each value. The size of the moving window is influenced by the 'size'
+ * parameters in the params map.
+ */
+ average: function(data, params) {
+ var size = ("size" in params) ? params.size : 30;
+ var result = Timeplot.Math.movingAverage(data.values, size);
+ return result;
+ }
+}
+
+/*==================================================
+ * Processing Data Source
+ *==================================================*/
+
+/**
+ * A Processor is a special DataSource that can apply an Operator
+ * to the DataSource values and thus return a different one.
+ *
+ * @constructor
+ */
+Timeplot.Processor = function(dataSource, operator, params) {
+ this._dataSource = dataSource;
+ this._operator = operator;
+ this._params = params;
+
+ this._data = {
+ times: new Array(),
+ values: new Array()
+ };
+
+ this._range = {
+ earliestDate: null,
+ latestDate: null,
+ min: 0,
+ max: 0
+ };
+
+ var processor = this;
+ this._processingListener = {
+ onAddMany: function() { processor._process(); },
+ onClear: function() { processor._clear(); }
+ }
+ this.addListener(this._processingListener);
+};
+
+Timeplot.Processor.prototype = {
+
+ _clear: function() {
+ this.removeListener(this._processingListener);
+ this._dataSource._clear();
+ },
+
+ _process: function() {
+ // this method requires the dataSource._process() method to be
+ // called first as to setup the data and range used below
+ // this should be guaranteed by the order of the listener registration
+
+ var data = this._dataSource.getData();
+ var range = this._dataSource.getRange();
+
+ var newValues = this._operator(data, this._params);
+ var newValueRange = Timeplot.Math.range(newValues);
+
+ this._data = {
+ times: data.times,
+ values: newValues
+ };
+
+ this._range = {
+ earliestDate: range.earliestDate,
+ latestDate: range.latestDate,
+ min: newValueRange.min,
+ max: newValueRange.max
+ };
+ },
+
+ getRange: function() {
+ return this._range;
+ },
+
+ getData: function() {
+ return this._data;
+ },
+
+ getValue: Timeplot.DataSource.prototype.getValue,
+
+ getClosestValidTime: Timeplot.DataSource.prototype.getClosestValidTime,
+
+ addListener: function(listener) {
+ this._dataSource.addListener(listener);
+ },
+
+ removeListener: function(listener) {
+ this._dataSource.removeListener(listener);
+ }
+}
Added: openoffice/ooo-site/trunk/content/scripts/api.simile-widgets.org/timeplot/1.1/scripts/sources.js
URL: http://svn.apache.org/viewvc/openoffice/ooo-site/trunk/content/scripts/api.simile-widgets.org/timeplot/1.1/scripts/sources.js?rev=1795424&view=auto
==============================================================================
--- openoffice/ooo-site/trunk/content/scripts/api.simile-widgets.org/timeplot/1.1/scripts/sources.js (added)
+++ openoffice/ooo-site/trunk/content/scripts/api.simile-widgets.org/timeplot/1.1/scripts/sources.js Wed May 17 15:29:56 2017
@@ -0,0 +1,371 @@
+/**
+ * Sources
+ *
+ * @fileOverview Sources
+ * @name Sources
+ */
+
+/**
+ * Timeplot.DefaultEventSource is an extension of Timeline.DefaultEventSource
+ * and therefore reuses the exact same event loading subsystem that
+ * Timeline uses.
+ *
+ * @constructor
+ */
+Timeplot.DefaultEventSource = function(eventIndex) {
+ Timeline.DefaultEventSource.apply(this, arguments);
+};
+
+Object.extend(Timeplot.DefaultEventSource.prototype, Timeline.DefaultEventSource.prototype);
+
+/**
+ * Function used by Timeplot to load time series data from a text file.
+ */
+Timeplot.DefaultEventSource.prototype.loadText = function(text, separator, url, filter, format) {
+
+ if (text == null) {
+ return;
+ }
+
+ this._events.maxValues = new Array();
+ var base = this._getBaseURL(url);
+
+ if (!format) format = 'iso8601';
+ var parseDateTimeFunction = this._events.getUnit().getParser(format);
+
+ var data = this._parseText(text, separator);
+
+ var added = false;
+
+ if (filter) {
+ data = filter(data);
+ }
+
+ if (data) {
+ for (var i = 0; i < data.length; i++){
+ var row = data[i];
+ if (row.length > 1) {
+ var dateStr = SimileAjax.jQuery.trim(row[0]);
+ var date = parseDateTimeFunction(dateStr);
+ if (date) {
+ var evt = new Timeplot.DefaultEventSource.NumericEvent(date,row.slice(1));
+ this._events.add(evt);
+ added = true;
+ }
+ }
+ }
+ }
+
+ if (added) {
+ this._fire("onAddMany", []);
+ }
+}
+
+/*
+ * Parse the data file.
+ *
+ * Adapted from http://www.kawa.net/works/js/jkl/js/jkl-parsexml.js by Yusuke Kawasaki
+ */
+Timeplot.DefaultEventSource.prototype._parseText = function (text, separator) {
+ text = text.replace( /\r\n?/g, "\n" ); // normalize newlines
+ var pos = 0;
+ var len = text.length;
+ var table = [];
+ while (pos < len) {
+ var line = [];
+ if (text.charAt(pos) != '#') { // if it's not a comment, process
+ while (pos < len) {
+ if (text.charAt(pos) == '"') { // "..." quoted column
+ var nextquote = text.indexOf('"', pos+1 );
+ while (nextquote<len && nextquote > -1) {
+ if (text.charAt(nextquote+1) != '"') {
+ break; // end of column
+ }
+ nextquote = text.indexOf('"', nextquote + 2);
+ }
+ if ( nextquote < 0 ) {
+ // unclosed quote
+ } else if (text.charAt(nextquote + 1) == separator) { // end of column
+ var quoted = text.substr(pos + 1, nextquote-pos - 1);
+ quoted = quoted.replace(/""/g,'"');
+ line[line.length] = quoted;
+ pos = nextquote + 2;
+ continue;
+ } else if (text.charAt(nextquote + 1) == "\n" || // end of line
+ len == nextquote + 1 ) { // end of file
+ var quoted = text.substr(pos + 1, nextquote-pos - 1);
+ quoted = quoted.replace(/""/g,'"');
+ line[line.length] = quoted;
+ pos = nextquote + 2;
+ break;
+ } else {
+ // invalid column
+ }
+ }
+ var nextseparator = text.indexOf(separator, pos);
+ var nextnline = text.indexOf("\n", pos);
+ if (nextnline < 0) nextnline = len;
+ if (nextseparator > -1 && nextseparator < nextnline) {
+ line[line.length] = text.substr(pos, nextseparator-pos);
+ pos = nextseparator + 1;
+ } else { // end of line
+ line[line.length] = text.substr(pos, nextnline-pos);
+ pos = nextnline + 1;
+ break;
+ }
+ }
+ } else { // if it's a comment, ignore
+ var nextnline = text.indexOf("\n", pos);
+ pos = (nextnline > -1) ? nextnline + 1 : cur;
+ }
+ if (line.length > 0) {
+ table[table.length] = line; // push line
+ }
+ }
+ if (table.length < 0) return; // null data
+ return table;
+}
+
+/**
+ * Return the range of the loaded data
+ */
+Timeplot.DefaultEventSource.prototype.getRange = function() {
+ var earliestDate = this.getEarliestDate();
+ var latestDate = this.getLatestDate();
+ return {
+ earliestDate: (earliestDate) ? earliestDate : null,
+ latestDate: (latestDate) ? latestDate : null,
+ min: 0,
+ max: 0
+ };
+}
+
+// -----------------------------------------------------------------------
+
+/**
+ * A NumericEvent is an Event that also contains an array of values,
+ * one for each columns in the loaded data file.
+ *
+ * @constructor
+ */
+Timeplot.DefaultEventSource.NumericEvent = function(time, values) {
+ this._id = "e" + Math.round(Math.random() * 1000000);
+ this._time = time;
+ this._values = values;
+};
+
+Timeplot.DefaultEventSource.NumericEvent.prototype = {
+ getID: function() { return this._id; },
+ getTime: function() { return this._time; },
+ getValues: function() { return this._values; },
+
+ // these are required by the EventSource
+ getStart: function() { return this._time; },
+ getEnd: function() { return this._time; }
+};
+
+// -----------------------------------------------------------------------
+
+/**
+ * A DataSource represent an abstract class that represents a monodimensional time series.
+ *
+ * @constructor
+ */
+Timeplot.DataSource = function(eventSource) {
+ this._eventSource = eventSource;
+ var source = this;
+ this._processingListener = {
+ onAddMany: function() { source._process(); },
+ onClear: function() { source._clear(); }
+ }
+ this.addListener(this._processingListener);
+ this._listeners = [];
+ this._data = null;
+ this._range = null;
+};
+
+Timeplot.DataSource.prototype = {
+
+ _clear: function() {
+ this._data = null;
+ this._range = null;
+ },
+
+ _process: function() {
+ this._data = {
+ times: new Array(),
+ values: new Array()
+ };
+ this._range = {
+ earliestDate: null,
+ latestDate: null,
+ min: 0,
+ max: 0
+ };
+ },
+
+ /**
+ * Return the range of this data source
+ */
+ getRange: function() {
+ return this._range;
+ },
+
+ /**
+ * Return the actual data that this data source represents.
+ * NOTE: _data = { times: [], values: [] }
+ */
+ getData: function() {
+ return this._data;
+ },
+
+ /**
+ * Return the value associated with the given time in this time series
+ */
+ getValue: function(t) {
+ if (this._data) {
+ for (var i = 0; i < this._data.times.length; i++) {
+ var l = this._data.times[i];
+ if (l >= t) {
+ return this._data.values[i];
+ }
+ }
+ }
+ return 0;
+ },
+
+ /**
+ * Return the time of the data point closest to the given time.
+ */
+ getClosestValidTime: function(t) {
+ if (this._data) {
+ for (var i = 0; i < this._data.times.length; i++) {
+ var currentTime = this._data.times[i];
+ if (currentTime >= t) {
+ if (i <= 0) {
+ return currentTime;
+ } else {
+ var lastTime = this._data.times[i - 1];
+ // t must be between currentTime and lastTime.
+ // Find the closest one.
+ if (t - lastTime < currentTime - t) {
+ return lastTime;
+ } else {
+ return currentTime;
+ }
+ }
+ }
+ }
+ }
+ return 0;
+ },
+
+ /**
+ * Add a listener to the underlying event source
+ */
+ addListener: function(listener) {
+ this._eventSource.addListener(listener);
+ },
+
+ /**
+ * Remove a listener from the underlying event source
+ */
+ removeListener: function(listener) {
+ this._eventSource.removeListener(listener);
+ },
+
+ /**
+ * Replace a listener from the underlying event source
+ */
+ replaceListener: function(oldListener, newListener) {
+ this.removeListener(oldListener);
+ this.addListener(newListener);
+ }
+
+}
+
+// -----------------------------------------------------------------------
+
+/**
+ * Implementation of a DataSource that extracts the time series out of a
+ * single column from the events
+ *
+ * @constructor
+ */
+Timeplot.ColumnSource = function(eventSource, column) {
+ Timeplot.DataSource.apply(this, arguments);
+ this._column = column - 1;
+};
+
+Object.extend(Timeplot.ColumnSource.prototype,Timeplot.DataSource.prototype);
+
+Timeplot.ColumnSource.prototype.dispose = function() {
+ this.removeListener(this._processingListener);
+ this._clear();
+}
+
+Timeplot.ColumnSource.prototype._process = function() {
+ var count = this._eventSource.getCount();
+ var times = new Array(count);
+ var values = new Array(count);
+ var min = Number.MAX_VALUE;
+ var max = Number.MIN_VALUE;
+ var i = 0;
+
+ var iterator = this._eventSource.getAllEventIterator();
+ while (iterator.hasNext()) {
+ var event = iterator.next();
+ var time = event.getTime();
+ times[i] = time;
+ var value = this._getValue(event);
+ if (!isNaN(value)) {
+ if (value < min) {
+ min = value;
+ }
+ if (value > max) {
+ max = value;
+ }
+ values[i] = value;
+ }
+ i++;
+ }
+
+ this._data = {
+ times: times,
+ values: values
+ };
+
+ if (max == Number.MIN_VALUE) max = 1;
+
+ this._range = {
+ earliestDate: this._eventSource.getEarliestDate(),
+ latestDate: this._eventSource.getLatestDate(),
+ min: min,
+ max: max
+ };
+}
+
+Timeplot.ColumnSource.prototype._getValue = function(event) {
+ return parseFloat(event.getValues()[this._column]);
+}
+
+// ---------------------------------------------------------------
+
+/**
+ * Data Source that generates the time series out of the difference
+ * between the first and the second column
+ *
+ * @constructor
+ */
+Timeplot.ColumnDiffSource = function(eventSource, column1, column2) {
+ Timeplot.ColumnSource.apply(this, arguments);
+ this._column2 = column2 - 1;
+};
+
+Object.extend(Timeplot.ColumnDiffSource.prototype,Timeplot.ColumnSource.prototype);
+
+Timeplot.ColumnDiffSource.prototype._getValue = function(event) {
+ var a = parseFloat(event.getValues()[this._column]);
+ var b = parseFloat(event.getValues()[this._column2]);
+ return a - b;
+}