Browse Source

fixed clean up of icons, titles, fixed some style issues, typos

v3_develop
Alex de Mulder 10 years ago
parent
commit
7c23ffa3c1
6 changed files with 504 additions and 280 deletions
  1. +42
    -0
      dist/vis.css
  2. +405
    -254
      dist/vis.js
  3. +1
    -1
      dist/vis.min.css
  4. +7
    -7
      examples/graph2d/16_bothAxis_titles.html
  5. +34
    -18
      lib/timeline/component/DataAxis.js
  6. +15
    -0
      lib/timeline/component/LineGraph.js

+ 42
- 0
dist/vis.css View File

@ -415,6 +415,48 @@
width: auto; width: auto;
} }
.vis.timeline .dataaxis .yAxis.title{
position: absolute;
color: #4d4d4d;
white-space: nowrap;
bottom: 20px;
text-align: center;
}
.vis.timeline .dataaxis .yAxis.title.measure{
padding: 0px 0px 0px 0px;
margin: 0px 0px 0px 0px;
visibility: hidden;
width: auto;
}
.vis.timeline .dataaxis .yAxis.title.left {
bottom: 0px;
-webkit-transform-origin: left top;
-moz-transform-origin: left top;
-ms-transform-origin: left top;
-o-transform-origin: left top;
transform-origin: left bottom;
-webkit-transform: rotate(-90deg);
-moz-transform: rotate(-90deg);
-ms-transform: rotate(-90deg);
-o-transform: rotate(-90deg);
transform: rotate(-90deg);
}
.vis.timeline .dataaxis .yAxis.title.right {
bottom: 0px;
-webkit-transform-origin: right bottom;
-moz-transform-origin: right bottom;
-ms-transform-origin: right bottom;
-o-transform-origin: right bottom;
transform-origin: right bottom;
-webkit-transform: rotate(90deg);
-moz-transform: rotate(90deg);
-ms-transform: rotate(90deg);
-o-transform: rotate(90deg);
transform: rotate(90deg);
}
.vis.timeline .legend { .vis.timeline .legend {
background-color: rgba(247, 252, 255, 0.65); background-color: rgba(247, 252, 255, 0.65);

+ 405
- 254
dist/vis.js View File

@ -104,7 +104,7 @@ return /******/ (function(modules) { // webpackBootstrap
exports.Graph2d = __webpack_require__(42); exports.Graph2d = __webpack_require__(42);
exports.timeline = { exports.timeline = {
DateUtil: __webpack_require__(24), DateUtil: __webpack_require__(24),
DataStep: __webpack_require__(44),
DataStep: __webpack_require__(47),
Range: __webpack_require__(21), Range: __webpack_require__(21),
stack: __webpack_require__(33), stack: __webpack_require__(33),
TimeStep: __webpack_require__(27), TimeStep: __webpack_require__(27),
@ -121,12 +121,12 @@ return /******/ (function(modules) { // webpackBootstrap
Component: __webpack_require__(23), Component: __webpack_require__(23),
CurrentTime: __webpack_require__(28), CurrentTime: __webpack_require__(28),
CustomTime: __webpack_require__(30), CustomTime: __webpack_require__(30),
DataAxis: __webpack_require__(45),
GraphGroup: __webpack_require__(46),
DataAxis: __webpack_require__(44),
GraphGroup: __webpack_require__(45),
Group: __webpack_require__(32), Group: __webpack_require__(32),
BackgroundGroup: __webpack_require__(36), BackgroundGroup: __webpack_require__(36),
ItemSet: __webpack_require__(31), ItemSet: __webpack_require__(31),
Legend: __webpack_require__(47),
Legend: __webpack_require__(46),
LineGraph: __webpack_require__(43), LineGraph: __webpack_require__(43),
TimeAxis: __webpack_require__(26) TimeAxis: __webpack_require__(26)
} }
@ -4556,7 +4556,6 @@ return /******/ (function(modules) { // webpackBootstrap
point.setAttributeNS(null, "cx", x); point.setAttributeNS(null, "cx", x);
point.setAttributeNS(null, "cy", y); point.setAttributeNS(null, "cy", y);
point.setAttributeNS(null, "r", 0.5 * group.options.drawPoints.size); point.setAttributeNS(null, "r", 0.5 * group.options.drawPoints.size);
point.setAttributeNS(null, "class", group.className + " point");
} }
else { else {
point = exports.getSVGElement('rect',JSONcontainer,svgContainer); point = exports.getSVGElement('rect',JSONcontainer,svgContainer);
@ -4564,8 +4563,12 @@ return /******/ (function(modules) { // webpackBootstrap
point.setAttributeNS(null, "y", y - 0.5*group.options.drawPoints.size); point.setAttributeNS(null, "y", y - 0.5*group.options.drawPoints.size);
point.setAttributeNS(null, "width", group.options.drawPoints.size); point.setAttributeNS(null, "width", group.options.drawPoints.size);
point.setAttributeNS(null, "height", group.options.drawPoints.size); point.setAttributeNS(null, "height", group.options.drawPoints.size);
point.setAttributeNS(null, "class", group.className + " point");
} }
if(group.options.drawPoints.styles !== undefined) {
point.setAttributeNS(null, "style", group.group.options.drawPoints.styles);
}
point.setAttributeNS(null, "class", group.className + " point");
return point; return point;
}; };
@ -20033,9 +20036,9 @@ return /******/ (function(modules) { // webpackBootstrap
var DataSet = __webpack_require__(7); var DataSet = __webpack_require__(7);
var DataView = __webpack_require__(9); var DataView = __webpack_require__(9);
var Component = __webpack_require__(23); var Component = __webpack_require__(23);
var DataAxis = __webpack_require__(45);
var GraphGroup = __webpack_require__(46);
var Legend = __webpack_require__(47);
var DataAxis = __webpack_require__(44);
var GraphGroup = __webpack_require__(45);
var Legend = __webpack_require__(46);
var UNGROUPED = '__ungrouped__'; // reserved group id for ungrouped items var UNGROUPED = '__ungrouped__'; // reserved group id for ungrouped items
@ -20086,6 +20089,21 @@ return /******/ (function(modules) { // webpackBootstrap
left: {min:undefined, max:undefined}, left: {min:undefined, max:undefined},
right: {min:undefined, max:undefined} right: {min:undefined, max:undefined}
} }
//,
//format: {
// left: {decimals: 2},
// right: {decimals: 2}
//},
//title: {
// left: {
// text: 'left',
// style: 'color:black;'
// },
// right: {
// text: 'right',
// style: 'color:black;'
// }
//}
}, },
legend: { legend: {
enabled: false, enabled: false,
@ -20104,7 +20122,6 @@ return /******/ (function(modules) { // webpackBootstrap
} }
}; };
// options is shared by this ItemSet and all its items // options is shared by this ItemSet and all its items
this.options = util.extend({}, this.defaultOptions); this.options = util.extend({}, this.defaultOptions);
this.dom = {}; this.dom = {};
@ -21097,7 +21114,10 @@ return /******/ (function(modules) { // webpackBootstrap
var path, d; var path, d;
var svgHeight = Number(this.svg.style.height.replace('px','')); var svgHeight = Number(this.svg.style.height.replace('px',''));
path = DOMutil.getSVGElement('path', this.svgElements, this.svg); path = DOMutil.getSVGElement('path', this.svgElements, this.svg);
path.setAttributeNS(null, 'class', group.className);
path.setAttributeNS(null, "class", group.className);
if(group.style !== undefined) {
path.setAttributeNS(null, "style", group.style);
}
// construct path from dataset // construct path from dataset
if (group.options.catmullRom.enabled == true) { if (group.options.catmullRom.enabled == true) {
@ -21117,8 +21137,11 @@ return /******/ (function(modules) { // webpackBootstrap
else { else {
dFill = 'M' + dataset[0].x + ',' + svgHeight + ' ' + d + 'L' + dataset[dataset.length - 1].x + ',' + svgHeight; dFill = 'M' + dataset[0].x + ',' + svgHeight + ' ' + d + 'L' + dataset[dataset.length - 1].x + ',' + svgHeight;
} }
fillPath.setAttributeNS(null, 'class', group.className + ' fill');
fillPath.setAttributeNS(null, 'd', dFill);
fillPath.setAttributeNS(null, "class", group.className + " fill");
if(group.options.shaded.style !== undefined) {
fillPath.setAttributeNS(null, "style", group.options.shaded.style);
}
fillPath.setAttributeNS(null, "d", dFill);
} }
// copy properties to path for drawing. // copy properties to path for drawing.
path.setAttributeNS(null, 'd', 'M' + d); path.setAttributeNS(null, 'd', 'M' + d);
@ -21354,240 +21377,12 @@ return /******/ (function(modules) { // webpackBootstrap
/***/ }, /***/ },
/* 44 */ /* 44 */
/***/ function(module, exports, __webpack_require__) {
/**
* @constructor DataStep
* The class DataStep is an iterator for data for the lineGraph. You provide a start data point and an
* end data point. The class itself determines the best scale (step size) based on the
* provided start Date, end Date, and minimumStep.
*
* If minimumStep is provided, the step size is chosen as close as possible
* to the minimumStep but larger than minimumStep. If minimumStep is not
* provided, the scale is set to 1 DAY.
* The minimumStep should correspond with the onscreen size of about 6 characters
*
* Alternatively, you can set a scale by hand.
* After creation, you can initialize the class by executing first(). Then you
* can iterate from the start date to the end date via next(). You can check if
* the end date is reached with the function hasNext(). After each step, you can
* retrieve the current date via getCurrent().
* The DataStep has scales ranging from milliseconds, seconds, minutes, hours,
* days, to years.
*
* Version: 1.2
*
* @param {Date} [start] The start date, for example new Date(2010, 9, 21)
* or new Date(2010, 9, 21, 23, 45, 00)
* @param {Date} [end] The end date
* @param {Number} [minimumStep] Optional. Minimum step size in milliseconds
*/
function DataStep(start, end, minimumStep, containerHeight, customRange) {
// variables
this.current = 0;
this.autoScale = true;
this.stepIndex = 0;
this.step = 1;
this.scale = 1;
this.marginStart;
this.marginEnd;
this.deadSpace = 0;
this.majorSteps = [1, 2, 5, 10];
this.minorSteps = [0.25, 0.5, 1, 2];
this.setRange(start, end, minimumStep, containerHeight, customRange);
}
/**
* Set a new range
* If minimumStep is provided, the step size is chosen as close as possible
* to the minimumStep but larger than minimumStep. If minimumStep is not
* provided, the scale is set to 1 DAY.
* The minimumStep should correspond with the onscreen size of about 6 characters
* @param {Number} [start] The start date and time.
* @param {Number} [end] The end date and time.
* @param {Number} [minimumStep] Optional. Minimum step size in milliseconds
*/
DataStep.prototype.setRange = function(start, end, minimumStep, containerHeight, customRange) {
this._start = customRange.min === undefined ? start : customRange.min;
this._end = customRange.max === undefined ? end : customRange.max;
if (this._start == this._end) {
this._start -= 0.75;
this._end += 1;
}
if (this.autoScale) {
this.setMinimumStep(minimumStep, containerHeight);
}
this.setFirst(customRange);
};
/**
* Automatically determine the scale that bests fits the provided minimum step
* @param {Number} [minimumStep] The minimum step size in milliseconds
*/
DataStep.prototype.setMinimumStep = function(minimumStep, containerHeight) {
// round to floor
var size = this._end - this._start;
var safeSize = size * 1.2;
var minimumStepValue = minimumStep * (safeSize / containerHeight);
var orderOfMagnitude = Math.round(Math.log(safeSize)/Math.LN10);
var minorStepIdx = -1;
var magnitudefactor = Math.pow(10,orderOfMagnitude);
var start = 0;
if (orderOfMagnitude < 0) {
start = orderOfMagnitude;
}
var solutionFound = false;
for (var i = start; Math.abs(i) <= Math.abs(orderOfMagnitude); i++) {
magnitudefactor = Math.pow(10,i);
for (var j = 0; j < this.minorSteps.length; j++) {
var stepSize = magnitudefactor * this.minorSteps[j];
if (stepSize >= minimumStepValue) {
solutionFound = true;
minorStepIdx = j;
break;
}
}
if (solutionFound == true) {
break;
}
}
this.stepIndex = minorStepIdx;
this.scale = magnitudefactor;
this.step = magnitudefactor * this.minorSteps[minorStepIdx];
};
/**
* Round the current date to the first minor date value
* This must be executed once when the current date is set to start Date
*/
DataStep.prototype.setFirst = function(customRange) {
if (customRange === undefined) {
customRange = {};
}
var niceStart = customRange.min === undefined ? this._start - (this.scale * 2 * this.minorSteps[this.stepIndex]) : customRange.min;
var niceEnd = customRange.max === undefined ? this._end + (this.scale * this.minorSteps[this.stepIndex]) : customRange.max;
this.marginEnd = customRange.max === undefined ? this.roundToMinor(niceEnd) : customRange.max;
this.marginStart = customRange.min === undefined ? this.roundToMinor(niceStart) : customRange.min;
this.deadSpace = this.roundToMinor(niceEnd) - niceEnd + this.roundToMinor(niceStart) - niceStart;
this.marginRange = this.marginEnd - this.marginStart;
this.current = this.marginEnd;
};
DataStep.prototype.roundToMinor = function(value) {
var rounded = value - (value % (this.scale * this.minorSteps[this.stepIndex]));
if (value % (this.scale * this.minorSteps[this.stepIndex]) > 0.5 * (this.scale * this.minorSteps[this.stepIndex])) {
return rounded + (this.scale * this.minorSteps[this.stepIndex]);
}
else {
return rounded;
}
}
/**
* Check if the there is a next step
* @return {boolean} true if the current date has not passed the end date
*/
DataStep.prototype.hasNext = function () {
return (this.current >= this.marginStart);
};
/**
* Do the next step
*/
DataStep.prototype.next = function() {
var prev = this.current;
this.current -= this.step;
// safety mechanism: if current time is still unchanged, move to the end
if (this.current == prev) {
this.current = this._end;
}
};
/**
* Do the next step
*/
DataStep.prototype.previous = function() {
this.current += this.step;
this.marginEnd += this.step;
this.marginRange = this.marginEnd - this.marginStart;
};
/**
* Get the current datetime
* @return {String} current The current date
*/
DataStep.prototype.getCurrent = function() {
var toPrecision = '' + Number(this.current).toPrecision(5);
if (toPrecision.indexOf(",") != -1 || toPrecision.indexOf(".") != -1) {
for (var i = toPrecision.length-1; i > 0; i--) {
if (toPrecision[i] == "0") {
toPrecision = toPrecision.slice(0,i);
}
else if (toPrecision[i] == "." || toPrecision[i] == ",") {
toPrecision = toPrecision.slice(0,i);
break;
}
else{
break;
}
}
}
return toPrecision;
};
/**
* Snap a date to a rounded value.
* The snap intervals are dependent on the current scale and step.
* @param {Date} date the date to be snapped.
* @return {Date} snappedDate
*/
DataStep.prototype.snap = function(date) {
};
/**
* Check if the current value is a major value (for example when the step
* is DAY, a major value is each first day of the MONTH)
* @return {boolean} true if current date is major, else false.
*/
DataStep.prototype.isMajor = function() {
return (this.current % (this.scale * this.majorSteps[this.stepIndex]) == 0);
};
module.exports = DataStep;
/***/ },
/* 45 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
var util = __webpack_require__(1); var util = __webpack_require__(1);
var DOMutil = __webpack_require__(6); var DOMutil = __webpack_require__(6);
var Component = __webpack_require__(23); var Component = __webpack_require__(23);
var DataStep = __webpack_require__(44);
var DataStep = __webpack_require__(47);
/** /**
* A horizontal time axis * A horizontal time axis
@ -21616,6 +21411,14 @@ return /******/ (function(modules) { // webpackBootstrap
customRange: { customRange: {
left: {min:undefined, max:undefined}, left: {min:undefined, max:undefined},
right: {min:undefined, max:undefined} right: {min:undefined, max:undefined}
},
title: {
left: {text:undefined},
right: {text:undefined}
},
format: {
left: {decimals: undefined},
right: {decimals: undefined}
} }
}; };
@ -21624,7 +21427,8 @@ return /******/ (function(modules) { // webpackBootstrap
this.props = {}; this.props = {};
this.DOMelements = { // dynamic elements this.DOMelements = { // dynamic elements
lines: {}, lines: {},
labels: {}
labels: {},
title: {}
}; };
this.dom = {}; this.dom = {};
@ -21644,6 +21448,7 @@ return /******/ (function(modules) { // webpackBootstrap
this.lineOffset = 0; this.lineOffset = 0;
this.master = true; this.master = true;
this.svgElements = {}; this.svgElements = {};
this.iconsRemoved = false;
this.groups = {}; this.groups = {};
@ -21699,7 +21504,9 @@ return /******/ (function(modules) { // webpackBootstrap
'iconWidth', 'iconWidth',
'width', 'width',
'visible', 'visible',
'customRange'
'customRange',
'title',
'format'
]; ];
util.selectiveExtend(fields, this.options, options); util.selectiveExtend(fields, this.options, options);
@ -21762,8 +21569,17 @@ return /******/ (function(modules) { // webpackBootstrap
} }
DOMutil.cleanupElements(this.svgElements); DOMutil.cleanupElements(this.svgElements);
this.iconsRemoved = false;
}; };
DataAxis.prototype._cleanupIcons = function() {
if (this.iconsRemoved == false) {
DOMutil.prepareElements(this.svgElements);
DOMutil.cleanupElements(this.svgElements);
this.iconsRemoved = true;
}
}
/** /**
* Create the HTML DOM for the DataAxis * Create the HTML DOM for the DataAxis
*/ */
@ -21813,7 +21629,8 @@ return /******/ (function(modules) { // webpackBootstrap
DataAxis.prototype.redraw = function () { DataAxis.prototype.redraw = function () {
var changeCalled = false; var changeCalled = false;
var activeGroups = 0; var activeGroups = 0;
// Make sure the line container adheres to the vertical scrolling.
this.dom.lineContainer.style.top = this.body.domProps.scrollTop + 'px'; this.dom.lineContainer.style.top = this.body.domProps.scrollTop + 'px';
for (var groupId in this.groups) { for (var groupId in this.groups) {
@ -21829,8 +21646,8 @@ return /******/ (function(modules) { // webpackBootstrap
else { else {
this.show(); this.show();
this.height = Number(this.linegraphSVG.style.height.replace("px","")); this.height = Number(this.linegraphSVG.style.height.replace("px",""));
// svg offsetheight did not work in firefox and explorer...
// svg offsetheight did not work in firefox and explorer...
this.dom.lineContainer.style.height = this.height + 'px'; this.dom.lineContainer.style.height = this.height + 'px';
this.width = this.options.visible == true ? Number(('' + this.options.width).replace("px","")) : 0; this.width = this.options.visible == true ? Number(('' + this.options.width).replace("px","")) : 0;
@ -21847,7 +21664,7 @@ return /******/ (function(modules) { // webpackBootstrap
var showMinorLabels = this.options.showMinorLabels; var showMinorLabels = this.options.showMinorLabels;
var showMajorLabels = this.options.showMajorLabels; var showMajorLabels = this.options.showMajorLabels;
// determine the width and height of the elemens for the axis
// determine the width and height of the elements for the axis
props.minorLabelHeight = showMinorLabels ? props.minorCharHeight : 0; props.minorLabelHeight = showMinorLabels ? props.minorCharHeight : 0;
props.majorLabelHeight = showMajorLabels ? props.majorCharHeight : 0; props.majorLabelHeight = showMajorLabels ? props.majorCharHeight : 0;
@ -21872,9 +21689,15 @@ return /******/ (function(modules) { // webpackBootstrap
frame.style.height = this.height + "px"; frame.style.height = this.height + "px";
} }
changeCalled = this._redrawLabels(); changeCalled = this._redrawLabels();
if (this.options.icons == true) { if (this.options.icons == true) {
this._redrawGroupIcons(); this._redrawGroupIcons();
} }
else {
this._cleanupIcons();
}
this._redrawTitle(orientation);
} }
return changeCalled; return changeCalled;
}; };
@ -21921,23 +21744,28 @@ return /******/ (function(modules) { // webpackBootstrap
// do not draw the first label // do not draw the first label
var max = 1; var max = 1;
// Get the number of decimal places
var decimals;
if(this.options.format[orientation] !== undefined) {
decimals = this.options.format[orientation].decimals;
}
this.maxLabelSize = 0; this.maxLabelSize = 0;
var y = 0; var y = 0;
while (max < Math.round(amountOfSteps)) { while (max < Math.round(amountOfSteps)) {
step.next(); step.next();
y = Math.round(max * stepPixels); y = Math.round(max * stepPixels);
marginStartPos = max * stepPixels; marginStartPos = max * stepPixels;
var isMajor = step.isMajor(); var isMajor = step.isMajor();
if (this.options['showMinorLabels'] && isMajor == false || this.master == false && this.options['showMinorLabels'] == true) { if (this.options['showMinorLabels'] && isMajor == false || this.master == false && this.options['showMinorLabels'] == true) {
this._redrawLabel(y - 2, step.getCurrent(), orientation, 'yAxis minor', this.props.minorCharHeight);
this._redrawLabel(y - 2, step.getCurrent(decimals), orientation, 'yAxis minor', this.props.minorCharHeight);
} }
if (isMajor && this.options['showMajorLabels'] && this.master == true || if (isMajor && this.options['showMajorLabels'] && this.master == true ||
this.options['showMinorLabels'] == false && this.master == false && isMajor == true) { this.options['showMinorLabels'] == false && this.master == false && isMajor == true) {
if (y >= 0) { if (y >= 0) {
this._redrawLabel(y - 2, step.getCurrent(), orientation, 'yAxis major', this.props.majorCharHeight);
this._redrawLabel(y - 2, step.getCurrent(decimals), orientation, 'yAxis major', this.props.majorCharHeight);
} }
this._redrawLine(y, orientation, 'grid horizontal major', this.options.majorLinesOffset, this.props.majorLineWidth); this._redrawLine(y, orientation, 'grid horizontal major', this.options.majorLinesOffset, this.props.majorLineWidth);
} }
@ -21955,9 +21783,14 @@ return /******/ (function(modules) { // webpackBootstrap
this.conversionFactor = this.dom.frame.offsetHeight / step.marginRange; this.conversionFactor = this.dom.frame.offsetHeight / step.marginRange;
} }
var offset = this.options.icons == true ? this.options.iconWidth + this.options.labelOffsetX + 15 : this.options.labelOffsetX + 15;
// Note that title is rotated, so we're using the height, not width!
var titleWidth = 0;
if (this.options.title[orientation] !== undefined && this.options.title[orientation].text !== undefined) {
titleWidth = this.props.titleCharHeight;
}
var offset = this.options.icons == true ? Math.max(this.options.iconWidth, titleWidth) + this.options.labelOffsetX + 15 : titleWidth + this.options.labelOffsetX + 15;
// this will resize the yAxis to accomodate the labels.
// this will resize the yAxis to accommodate the labels.
if (this.maxLabelSize > (this.width - offset) && this.options.visible == true) { if (this.maxLabelSize > (this.width - offset) && this.options.visible == true) {
this.width = this.maxLabelSize + offset; this.width = this.maxLabelSize + offset;
this.options.width = this.width + "px"; this.options.width = this.width + "px";
@ -22047,6 +21880,38 @@ return /******/ (function(modules) { // webpackBootstrap
} }
}; };
/**
* Create a title for the axis
* @private
* @param orientation
*/
DataAxis.prototype._redrawTitle = function (orientation) {
DOMutil.prepareElements(this.DOMelements.title);
// Check if the title is defined for this axes
if (this.options.title[orientation] !== undefined && this.options.title[orientation].text !== undefined) {
var title = DOMutil.getDOMElement('div', this.DOMelements.title, this.dom.frame);
title.className = 'yAxis title ' + orientation;
title.innerHTML = this.options.title[orientation].text;
// Add style - if provided
if (this.options.title[orientation].style !== undefined) {
util.addCssText(title, this.options.title[orientation].style);
}
if (orientation == 'left') {
title.style.left = this.props.titleCharHeight + 'px';
}
else {
title.style.right = this.props.titleCharHeight + 'px';
}
title.style.width = this.height + 'px';
}
// we need to clean up in case we did not use all elements.
DOMutil.cleanupElements(this.DOMelements.title);
};
@ -22083,6 +21948,19 @@ return /******/ (function(modules) { // webpackBootstrap
this.dom.frame.removeChild(measureCharMajor); this.dom.frame.removeChild(measureCharMajor);
} }
if (!('titleCharHeight' in this.props)) {
var textTitle = document.createTextNode('0');
var measureCharTitle = document.createElement('DIV');
measureCharTitle.className = 'yAxis title measure';
measureCharTitle.appendChild(textTitle);
this.dom.frame.appendChild(measureCharTitle);
this.props.titleCharHeight = measureCharTitle.clientHeight;
this.props.titleCharWidth = measureCharTitle.clientWidth;
this.dom.frame.removeChild(measureCharTitle);
}
}; };
/** /**
@ -22099,7 +21977,7 @@ return /******/ (function(modules) { // webpackBootstrap
/***/ }, /***/ },
/* 46 */
/* 45 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
var util = __webpack_require__(1); var util = __webpack_require__(1);
@ -22175,6 +22053,7 @@ return /******/ (function(modules) { // webpackBootstrap
this.content = group.content || 'graph'; this.content = group.content || 'graph';
this.className = group.className || this.className || "graphGroup" + this.groupsUsingDefaultStyles[0] % 10; this.className = group.className || this.className || "graphGroup" + this.groupsUsingDefaultStyles[0] % 10;
this.visible = group.visible === undefined ? true : group.visible; this.visible = group.visible === undefined ? true : group.visible;
this.style = group.style;
this.setOptions(group.options); this.setOptions(group.options);
}; };
@ -22192,6 +22071,10 @@ return /******/ (function(modules) { // webpackBootstrap
if (this.options.style == 'line') { if (this.options.style == 'line') {
path = DOMutil.getSVGElement("path", JSONcontainer, SVGcontainer); path = DOMutil.getSVGElement("path", JSONcontainer, SVGcontainer);
path.setAttributeNS(null, "class", this.className); path.setAttributeNS(null, "class", this.className);
if(this.style !== undefined) {
path.setAttributeNS(null, "style", this.style);
}
path.setAttributeNS(null, "d", "M" + x + ","+y+" L" + (x + iconWidth) + ","+y+""); path.setAttributeNS(null, "d", "M" + x + ","+y+" L" + (x + iconWidth) + ","+y+"");
if (this.options.shaded.enabled == true) { if (this.options.shaded.enabled == true) {
fillPath = DOMutil.getSVGElement("path", JSONcontainer, SVGcontainer); fillPath = DOMutil.getSVGElement("path", JSONcontainer, SVGcontainer);
@ -22240,7 +22123,7 @@ return /******/ (function(modules) { // webpackBootstrap
/***/ }, /***/ },
/* 47 */
/* 46 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
var util = __webpack_require__(1); var util = __webpack_require__(1);
@ -22449,6 +22332,274 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = Legend; module.exports = Legend;
/***/ },
/* 47 */
/***/ function(module, exports, __webpack_require__) {
/**
* @constructor DataStep
* The class DataStep is an iterator for data for the lineGraph. You provide a start data point and an
* end data point. The class itself determines the best scale (step size) based on the
* provided start Date, end Date, and minimumStep.
*
* If minimumStep is provided, the step size is chosen as close as possible
* to the minimumStep but larger than minimumStep. If minimumStep is not
* provided, the scale is set to 1 DAY.
* The minimumStep should correspond with the onscreen size of about 6 characters
*
* Alternatively, you can set a scale by hand.
* After creation, you can initialize the class by executing first(). Then you
* can iterate from the start date to the end date via next(). You can check if
* the end date is reached with the function hasNext(). After each step, you can
* retrieve the current date via getCurrent().
* The DataStep has scales ranging from milliseconds, seconds, minutes, hours,
* days, to years.
*
* Version: 1.2
*
* @param {Date} [start] The start date, for example new Date(2010, 9, 21)
* or new Date(2010, 9, 21, 23, 45, 00)
* @param {Date} [end] The end date
* @param {Number} [minimumStep] Optional. Minimum step size in milliseconds
*/
function DataStep(start, end, minimumStep, containerHeight, customRange) {
// variables
this.current = 0;
this.autoScale = true;
this.stepIndex = 0;
this.step = 1;
this.scale = 1;
this.marginStart;
this.marginEnd;
this.deadSpace = 0;
this.majorSteps = [1, 2, 5, 10];
this.minorSteps = [0.25, 0.5, 1, 2];
this.setRange(start, end, minimumStep, containerHeight, customRange);
}
/**
* Set a new range
* If minimumStep is provided, the step size is chosen as close as possible
* to the minimumStep but larger than minimumStep. If minimumStep is not
* provided, the scale is set to 1 DAY.
* The minimumStep should correspond with the onscreen size of about 6 characters
* @param {Number} [start] The start date and time.
* @param {Number} [end] The end date and time.
* @param {Number} [minimumStep] Optional. Minimum step size in milliseconds
*/
DataStep.prototype.setRange = function(start, end, minimumStep, containerHeight, customRange) {
this._start = customRange.min === undefined ? start : customRange.min;
this._end = customRange.max === undefined ? end : customRange.max;
if (this._start == this._end) {
this._start -= 0.75;
this._end += 1;
}
if (this.autoScale) {
this.setMinimumStep(minimumStep, containerHeight);
}
this.setFirst(customRange);
};
/**
* Automatically determine the scale that bests fits the provided minimum step
* @param {Number} [minimumStep] The minimum step size in milliseconds
*/
DataStep.prototype.setMinimumStep = function(minimumStep, containerHeight) {
// round to floor
var size = this._end - this._start;
var safeSize = size * 1.2;
var minimumStepValue = minimumStep * (safeSize / containerHeight);
var orderOfMagnitude = Math.round(Math.log(safeSize)/Math.LN10);
var minorStepIdx = -1;
var magnitudefactor = Math.pow(10,orderOfMagnitude);
var start = 0;
if (orderOfMagnitude < 0) {
start = orderOfMagnitude;
}
var solutionFound = false;
for (var i = start; Math.abs(i) <= Math.abs(orderOfMagnitude); i++) {
magnitudefactor = Math.pow(10,i);
for (var j = 0; j < this.minorSteps.length; j++) {
var stepSize = magnitudefactor * this.minorSteps[j];
if (stepSize >= minimumStepValue) {
solutionFound = true;
minorStepIdx = j;
break;
}
}
if (solutionFound == true) {
break;
}
}
this.stepIndex = minorStepIdx;
this.scale = magnitudefactor;
this.step = magnitudefactor * this.minorSteps[minorStepIdx];
};
/**
* Round the current date to the first minor date value
* This must be executed once when the current date is set to start Date
*/
DataStep.prototype.setFirst = function(customRange) {
if (customRange === undefined) {
customRange = {};
}
var niceStart = customRange.min === undefined ? this._start - (this.scale * 2 * this.minorSteps[this.stepIndex]) : customRange.min;
var niceEnd = customRange.max === undefined ? this._end + (this.scale * this.minorSteps[this.stepIndex]) : customRange.max;
this.marginEnd = customRange.max === undefined ? this.roundToMinor(niceEnd) : customRange.max;
this.marginStart = customRange.min === undefined ? this.roundToMinor(niceStart) : customRange.min;
this.deadSpace = this.roundToMinor(niceEnd) - niceEnd + this.roundToMinor(niceStart) - niceStart;
this.marginRange = this.marginEnd - this.marginStart;
this.current = this.marginEnd;
};
DataStep.prototype.roundToMinor = function(value) {
var rounded = value - (value % (this.scale * this.minorSteps[this.stepIndex]));
if (value % (this.scale * this.minorSteps[this.stepIndex]) > 0.5 * (this.scale * this.minorSteps[this.stepIndex])) {
return rounded + (this.scale * this.minorSteps[this.stepIndex]);
}
else {
return rounded;
}
}
/**
* Check if the there is a next step
* @return {boolean} true if the current date has not passed the end date
*/
DataStep.prototype.hasNext = function () {
return (this.current >= this.marginStart);
};
/**
* Do the next step
*/
DataStep.prototype.next = function() {
var prev = this.current;
this.current -= this.step;
// safety mechanism: if current time is still unchanged, move to the end
if (this.current == prev) {
this.current = this._end;
}
};
/**
* Do the next step
*/
DataStep.prototype.previous = function() {
this.current += this.step;
this.marginEnd += this.step;
this.marginRange = this.marginEnd - this.marginStart;
};
/**
* Get the current datetime
* @return {String} current The current date
*/
DataStep.prototype.getCurrent = function(decimals) {
var toPrecision = '' + Number(this.current).toPrecision(5);
// If decimals is specified, then limit or extend the string as required
if(decimals !== undefined && !isNaN(Number(decimals))) {
// If string includes exponent, then we need to add it to the end
var exp = "";
var index = toPrecision.indexOf("e");
if(index != -1) {
// Get the exponent
exp = toPrecision.slice(index);
// Remove the exponent in case we need to zero-extend
toPrecision = toPrecision.slice(0, index);
}
index = Math.max(toPrecision.indexOf(","), toPrecision.indexOf("."));
if(index === -1) {
// No decimal found - if we want decimals, then we need to add it
if(decimals !== 0) {
toPrecision += '.';
}
// Calculate how long the string should be
index = toPrecision.length + decimals;
}
else if(decimals !== 0) {
// Calculate how long the string should be - accounting for the decimal place
index += decimals + 1;
}
if(index > toPrecision.length) {
// We need to add zeros!
for(var cnt = index - toPrecision.length; cnt > 0; cnt--) {
toPrecision += '0';
}
}
else {
// we need to remove characters
toPrecision = toPrecision.slice(0, index);
}
// Add the exponent if there is one
toPrecision += exp;
}
else {
if (toPrecision.indexOf(",") != -1 || toPrecision.indexOf(".") != -1) {
// If no decimal is specified, and there are decimal places, remove trailing zeros
for (var i = toPrecision.length - 1; i > 0; i--) {
if (toPrecision[i] == "0") {
toPrecision = toPrecision.slice(0, i);
}
else if (toPrecision[i] == "." || toPrecision[i] == ",") {
toPrecision = toPrecision.slice(0, i);
break;
}
else {
break;
}
}
}
}
return toPrecision;
};
/**
* Snap a date to a rounded value.
* The snap intervals are dependent on the current scale and step.
* @param {Date} date the date to be snapped.
* @return {Date} snappedDate
*/
DataStep.prototype.snap = function(date) {
};
/**
* Check if the current value is a major value (for example when the step
* is DAY, a major value is each first day of the MONTH)
* @return {boolean} true if current date is major, else false.
*/
DataStep.prototype.isMajor = function() {
return (this.current % (this.scale * this.majorSteps[this.stepIndex]) == 0);
};
module.exports = DataStep;
/***/ }, /***/ },
/* 48 */ /* 48 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {

+ 1
- 1
dist/vis.min.css
File diff suppressed because it is too large
View File


+ 7
- 7
examples/graph2d/16_bothAxis_titles.html View File

@ -43,7 +43,7 @@
<table> <table>
<tr> <tr>
<td> <td>
This example shows setting a title for the left and right axes. Optionally the example allows the user
This example shows setting a title for the left and right axis. Optionally the example allows the user
to show icons and labels on the left and right axis. to show icons and labels on the left and right axis.
</td> </td>
<td> <td>
@ -161,7 +161,7 @@
showMinorLabels: false, showMinorLabels: false,
title: { title: {
right: { right: {
text: 'Right (right axis)'
text: 'Title (right axis)'
} }
} }
}, },
@ -175,16 +175,16 @@
graph2d.setOptions({dataAxis: {icons: show}}); graph2d.setOptions({dataAxis: {icons: show}});
} }
function showTitle(axes, show) {
function showTitle(axis, show) {
var title; var title;
if(show == true) { if(show == true) {
title = {text: "Title (" + axes + " axes)", style: "color: green;"};
title = {text: "Title (" + axis + " axis)"};
} }
else { else {
title = undefined; title = undefined;
} }
if(axes == 'left') {
if(axis == 'left') {
graph2d.setOptions({dataAxis: {title: {left: title}}}); graph2d.setOptions({dataAxis: {title: {left: title}}});
} }
else { else {
@ -193,11 +193,11 @@
} }
var colors=['red','green','blue','black','yellow','purple','pink']; var colors=['red','green','blue','black','yellow','purple','pink'];
function styleTitle(axes) {
function styleTitle(axis) {
var title; var title;
title = {style: "color: " + colors[Math.floor(Math.random() * colors.length) + 1]}; title = {style: "color: " + colors[Math.floor(Math.random() * colors.length) + 1]};
if(axes == 'left') {
if(axis == 'left') {
graph2d.setOptions({dataAxis: {title: {left: title}}}); graph2d.setOptions({dataAxis: {title: {left: title}}});
} }
else { else {

+ 34
- 18
lib/timeline/component/DataAxis.js View File

@ -67,6 +67,7 @@ function DataAxis (body, options, svg, linegraphOptions) {
this.lineOffset = 0; this.lineOffset = 0;
this.master = true; this.master = true;
this.svgElements = {}; this.svgElements = {};
this.iconsRemoved = false;
this.groups = {}; this.groups = {};
@ -187,8 +188,17 @@ DataAxis.prototype._redrawGroupIcons = function () {
} }
DOMutil.cleanupElements(this.svgElements); DOMutil.cleanupElements(this.svgElements);
this.iconsRemoved = false;
}; };
DataAxis.prototype._cleanupIcons = function() {
if (this.iconsRemoved == false) {
DOMutil.prepareElements(this.svgElements);
DOMutil.cleanupElements(this.svgElements);
this.iconsRemoved = true;
}
}
/** /**
* Create the HTML DOM for the DataAxis * Create the HTML DOM for the DataAxis
*/ */
@ -255,8 +265,8 @@ DataAxis.prototype.redraw = function () {
else { else {
this.show(); this.show();
this.height = Number(this.linegraphSVG.style.height.replace("px","")); this.height = Number(this.linegraphSVG.style.height.replace("px",""));
// svg offsetheight did not work in firefox and explorer...
// svg offsetheight did not work in firefox and explorer...
this.dom.lineContainer.style.height = this.height + 'px'; this.dom.lineContainer.style.height = this.height + 'px';
this.width = this.options.visible == true ? Number(('' + this.options.width).replace("px","")) : 0; this.width = this.options.visible == true ? Number(('' + this.options.width).replace("px","")) : 0;
@ -298,9 +308,13 @@ DataAxis.prototype.redraw = function () {
frame.style.height = this.height + "px"; frame.style.height = this.height + "px";
} }
changeCalled = this._redrawLabels(); changeCalled = this._redrawLabels();
if (this.options.icons == true) { if (this.options.icons == true) {
this._redrawGroupIcons(); this._redrawGroupIcons();
} }
else {
this._cleanupIcons();
}
this._redrawTitle(orientation); this._redrawTitle(orientation);
} }
@ -390,7 +404,7 @@ DataAxis.prototype._redrawLabels = function () {
// Note that title is rotated, so we're using the height, not width! // Note that title is rotated, so we're using the height, not width!
var titleWidth = 0; var titleWidth = 0;
if(this.options.title[orientation] !== undefined) {
if (this.options.title[orientation] !== undefined && this.options.title[orientation].text !== undefined) {
titleWidth = this.props.titleCharHeight; titleWidth = this.props.titleCharHeight;
} }
var offset = this.options.icons == true ? Math.max(this.options.iconWidth, titleWidth) + this.options.labelOffsetX + 15 : titleWidth + this.options.labelOffsetX + 15; var offset = this.options.icons == true ? Math.max(this.options.iconWidth, titleWidth) + this.options.labelOffsetX + 15 : titleWidth + this.options.labelOffsetX + 15;
@ -494,26 +508,28 @@ DataAxis.prototype._redrawTitle = function (orientation) {
DOMutil.prepareElements(this.DOMelements.title); DOMutil.prepareElements(this.DOMelements.title);
// Check if the title is defined for this axes // Check if the title is defined for this axes
if(this.options.title[orientation] == undefined || this.options.title[orientation].text === undefined) {
return;
}
var title = DOMutil.getDOMElement('div',this.DOMelements.title, this.dom.frame);
title.className = 'yAxis title ' + orientation;
title.innerHTML = this.options.title[orientation].text;
if (this.options.title[orientation] !== undefined && this.options.title[orientation].text !== undefined) {
var title = DOMutil.getDOMElement('div', this.DOMelements.title, this.dom.frame);
title.className = 'yAxis title ' + orientation;
title.innerHTML = this.options.title[orientation].text;
// Add style - if provided
if (this.options.title[orientation].style !== undefined) {
util.addCssText(title, this.options.title[orientation].style);
}
// Add style - if provided
if(this.options.title[orientation].style !== undefined) {
util.addCssText(title, this.options.title[orientation].style);
}
if (orientation == 'left') {
title.style.left = this.props.titleCharHeight + 'px';
}
else {
title.style.right = this.props.titleCharHeight + 'px';
}
if (orientation == 'left') {
title.style.left = this.props.titleCharHeight + 'px';
}
else {
title.style.right = this.props.titleCharHeight + 'px';
title.style.width = this.height + 'px';
} }
title.style.width = this.height + 'px';
// we need to clean up in case we did not use all elements.
DOMutil.cleanupElements(this.DOMelements.title);
}; };

+ 15
- 0
lib/timeline/component/LineGraph.js View File

@ -56,6 +56,21 @@ function LineGraph(body, options) {
left: {min:undefined, max:undefined}, left: {min:undefined, max:undefined},
right: {min:undefined, max:undefined} right: {min:undefined, max:undefined}
} }
//,
//format: {
// left: {decimals: 2},
// right: {decimals: 2}
//},
//title: {
// left: {
// text: 'left',
// style: 'color:black;'
// },
// right: {
// text: 'right',
// style: 'color:black;'
// }
//}
}, },
legend: { legend: {
enabled: false, enabled: false,

Loading…
Cancel
Save