mirror of
https://github.com/morrisjs/morris.js.git
synced 2024-11-10 21:36:34 +01:00
commit
b722937920
38
examples/diagonal-xlabels-bar.html
Normal file
38
examples/diagonal-xlabels-bar.html
Normal file
@ -0,0 +1,38 @@
|
||||
<!doctype html>
|
||||
<head>
|
||||
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
|
||||
<script src="https://raw.github.com/DmitryBaranovskiy/raphael/300aa589f5a0ba7fce667cd62c7cdda0bd5ad904/raphael-min.js"></script>
|
||||
<script src="../morris.js"></script>
|
||||
<script src="lib/prettify.js"></script>
|
||||
<script src="lib/example.js"></script>
|
||||
<link rel="stylesheet" href="lib/example.css">
|
||||
<link rel="stylesheet" href="lib/prettify.css">
|
||||
<link rel="stylesheet" href="../morris.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>Displaying X Labels Diagonally (Bar Chart)</h1>
|
||||
<div id="graph"></div>
|
||||
<pre id="code" class="prettyprint linenums">
|
||||
/* data stolen from http://howmanyleft.co.uk/vehicle/jaguar_'e'_type */
|
||||
var day_data = [
|
||||
{"period": "2012-10-01", "licensed": 3407, "sorned": 660},
|
||||
{"period": "2012-09-30", "licensed": 3351, "sorned": 629},
|
||||
{"period": "2012-09-29", "licensed": 3269, "sorned": 618},
|
||||
{"period": "2012-09-20", "licensed": 3246, "sorned": 661},
|
||||
{"period": "2012-09-19", "licensed": 3257, "sorned": 667},
|
||||
{"period": "2012-09-18", "licensed": 3248, "sorned": 627},
|
||||
{"period": "2012-09-17", "licensed": 3171, "sorned": 660},
|
||||
{"period": "2012-09-16", "licensed": 3171, "sorned": 676},
|
||||
{"period": "2012-09-15", "licensed": 3201, "sorned": 656},
|
||||
{"period": "2012-09-10", "licensed": 3215, "sorned": 622}
|
||||
];
|
||||
Morris.Bar({
|
||||
element: 'graph',
|
||||
data: day_data,
|
||||
xkey: 'period',
|
||||
ykeys: ['licensed', 'sorned'],
|
||||
labels: ['Licensed', 'SORN'],
|
||||
xLabelAngle: 60
|
||||
});
|
||||
</pre>
|
||||
</body>
|
38
examples/diagonal-xlabels.html
Normal file
38
examples/diagonal-xlabels.html
Normal file
@ -0,0 +1,38 @@
|
||||
<!doctype html>
|
||||
<head>
|
||||
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
|
||||
<script src="https://raw.github.com/DmitryBaranovskiy/raphael/300aa589f5a0ba7fce667cd62c7cdda0bd5ad904/raphael-min.js"></script>
|
||||
<script src="../morris.js"></script>
|
||||
<script src="lib/prettify.js"></script>
|
||||
<script src="lib/example.js"></script>
|
||||
<link rel="stylesheet" href="lib/example.css">
|
||||
<link rel="stylesheet" href="lib/prettify.css">
|
||||
<link rel="stylesheet" href="../morris.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>Displaying X Labels Diagonally</h1>
|
||||
<div id="graph"></div>
|
||||
<pre id="code" class="prettyprint linenums">
|
||||
/* data stolen from http://howmanyleft.co.uk/vehicle/jaguar_'e'_type */
|
||||
var day_data = [
|
||||
{"period": "2012-10-30", "licensed": 3407, "sorned": 660},
|
||||
{"period": "2012-09-30", "licensed": 3351, "sorned": 629},
|
||||
{"period": "2012-09-29", "licensed": 3269, "sorned": 618},
|
||||
{"period": "2012-09-20", "licensed": 3246, "sorned": 661},
|
||||
{"period": "2012-09-19", "licensed": 3257, "sorned": 667},
|
||||
{"period": "2012-09-18", "licensed": 3248, "sorned": 627},
|
||||
{"period": "2012-09-17", "licensed": 3171, "sorned": 660},
|
||||
{"period": "2012-09-16", "licensed": 3171, "sorned": 676},
|
||||
{"period": "2012-09-15", "licensed": 3201, "sorned": 656},
|
||||
{"period": "2012-09-10", "licensed": 3215, "sorned": 622}
|
||||
];
|
||||
Morris.Line({
|
||||
element: 'graph',
|
||||
data: day_data,
|
||||
xkey: 'period',
|
||||
ykeys: ['licensed', 'sorned'],
|
||||
labels: ['Licensed', 'SORN'],
|
||||
xLabelAngle: 60
|
||||
});
|
||||
</pre>
|
||||
</body>
|
@ -56,16 +56,29 @@ class Morris.Bar extends Morris.Grid
|
||||
# @private
|
||||
drawXAxis: ->
|
||||
# draw x axis labels
|
||||
ypos = @bottom + @options.gridTextSize * 1.25
|
||||
ypos = @bottom + @options.padding / 2
|
||||
prevLabelMargin = null
|
||||
prevAngleMargin = null
|
||||
for i in [0...@data.length]
|
||||
row = @data[@data.length - 1 - i]
|
||||
label = @drawXAxisLabel(row._x, ypos, row.label)
|
||||
textBox = label.getBBox()
|
||||
label.transform("r#{-@options.xLabelAngle}")
|
||||
labelBox = label.getBBox()
|
||||
# ensure a minimum of `xLabelMargin` pixels between labels, and ensure
|
||||
# labels don't overflow the container
|
||||
if (not prevLabelMargin? or prevLabelMargin >= labelBox.x + labelBox.width) and
|
||||
labelBox.x >= 0 and (labelBox.x + labelBox.width) < @el.width()
|
||||
label.transform("t0,#{labelBox.height / 2}...")
|
||||
if @options.xLabelAngle != 0
|
||||
offset = -0.5 * textBox.width *
|
||||
Math.cos(@options.xLabelAngle * Math.PI / 180.0)
|
||||
label.transform("t#{offset},0...")
|
||||
# try to avoid overlaps
|
||||
if (not prevLabelMargin? or
|
||||
prevLabelMargin >= labelBox.x + labelBox.width or
|
||||
prevAngleMargin? and prevAngleMargin >= labelBox.x) and
|
||||
labelBox.x >= 0 and (labelBox.x + labelBox.width) < @el.width()
|
||||
if @options.xLabelAngle != 0
|
||||
margin = 1.25 * @options.gridTextSize /
|
||||
Math.sin(@options.xLabelAngle * Math.PI / 180.0)
|
||||
prevAngleMargin = labelBox.x - margin
|
||||
prevLabelMargin = labelBox.x - @options.xLabelMargin
|
||||
else
|
||||
label.remove()
|
||||
|
@ -67,6 +67,7 @@ class Morris.Grid extends Morris.EventEmitter
|
||||
gridTextSize: 12
|
||||
hideHover: false
|
||||
yLabelFormat: null
|
||||
xLabelAngle: 0
|
||||
numLines: 5
|
||||
padding: 25
|
||||
parseTime: true
|
||||
@ -240,7 +241,9 @@ class Morris.Grid extends Morris.EventEmitter
|
||||
yLabelWidths = for gridLine in @grid
|
||||
@measureText(@yAxisFormat(gridLine), @options.gridTextSize).width
|
||||
@left += Math.max(yLabelWidths...)
|
||||
@bottom -= 1.5 * @options.gridTextSize
|
||||
bottomOffsets = for i in [0...@data.length]
|
||||
@measureText(@data[i].text, @options.gridTextSize, -@options.xLabelAngle).height
|
||||
@bottom -= Math.max(bottomOffsets...)
|
||||
@width = Math.max(1, @right - @left)
|
||||
@height = Math.max(1, @bottom - @top)
|
||||
@dx = @width / (@xmax - @xmin)
|
||||
@ -270,8 +273,8 @@ class Morris.Grid extends Morris.EventEmitter
|
||||
|
||||
# @private
|
||||
#
|
||||
measureText: (text, fontSize = 12) ->
|
||||
tt = @raphael.text(100, 100, text).attr('font-size', fontSize)
|
||||
measureText: (text, fontSize = 12, angle = 0) ->
|
||||
tt = @raphael.text(100, 100, text).attr('font-size', fontSize).rotate(angle)
|
||||
ret = tt.getBBox()
|
||||
tt.remove()
|
||||
ret
|
||||
|
@ -36,7 +36,7 @@ class Morris.Line extends Morris.Grid
|
||||
smooth: true
|
||||
xLabels: 'auto'
|
||||
xLabelFormat: null
|
||||
xLabelMargin: 50
|
||||
xLabelMargin: 24
|
||||
continuousLine: true
|
||||
hideHover: false
|
||||
|
||||
@ -143,15 +143,29 @@ class Morris.Line extends Morris.Grid
|
||||
# @private
|
||||
drawXAxis: ->
|
||||
# draw x axis labels
|
||||
ypos = @bottom + @options.gridTextSize * 1.25
|
||||
ypos = @bottom + @options.padding / 2
|
||||
prevLabelMargin = null
|
||||
prevAngleMargin = null
|
||||
drawLabel = (labelText, xpos) =>
|
||||
label = @drawXAxisLabel(@transX(xpos), ypos, labelText)
|
||||
textBox = label.getBBox()
|
||||
label.transform("r#{-@options.xLabelAngle}")
|
||||
labelBox = label.getBBox()
|
||||
# ensure a minimum of `xLabelMargin` pixels between labels, and ensure
|
||||
# labels don't overflow the container
|
||||
if (not prevLabelMargin? or prevLabelMargin >= labelBox.x + labelBox.width) and
|
||||
labelBox.x >= 0 and (labelBox.x + labelBox.width) < @el.width()
|
||||
label.transform("t0,#{labelBox.height / 2}...")
|
||||
if @options.xLabelAngle != 0
|
||||
offset = -0.5 * textBox.width *
|
||||
Math.cos(@options.xLabelAngle * Math.PI / 180.0)
|
||||
label.transform("t#{offset},0...")
|
||||
# try to avoid overlaps
|
||||
labelBox = label.getBBox()
|
||||
if (not prevLabelMargin? or
|
||||
prevLabelMargin >= labelBox.x + labelBox.width or
|
||||
prevAngleMargin? and prevAngleMargin >= labelBox.x) and
|
||||
labelBox.x >= 0 and (labelBox.x + labelBox.width) < @el.width()
|
||||
if @options.xLabelAngle != 0
|
||||
margin = 1.25 * @options.gridTextSize /
|
||||
Math.sin(@options.xLabelAngle * Math.PI / 180.0)
|
||||
prevAngleMargin = labelBox.x - margin
|
||||
prevLabelMargin = labelBox.x - @options.xLabelMargin
|
||||
else
|
||||
label.remove()
|
||||
|
61
morris.js
61
morris.js
@ -127,6 +127,7 @@
|
||||
gridTextSize: 12,
|
||||
hideHover: false,
|
||||
yLabelFormat: null,
|
||||
xLabelAngle: 0,
|
||||
numLines: 5,
|
||||
padding: 25,
|
||||
parseTime: true,
|
||||
@ -344,7 +345,7 @@
|
||||
};
|
||||
|
||||
Grid.prototype._calc = function() {
|
||||
var gridLine, h, w, yLabelWidths;
|
||||
var bottomOffsets, gridLine, h, i, w, yLabelWidths;
|
||||
w = this.el.width();
|
||||
h = this.el.height();
|
||||
if (this.elementWidth !== w || this.elementHeight !== h || this.dirty) {
|
||||
@ -367,7 +368,15 @@
|
||||
return _results;
|
||||
}).call(this);
|
||||
this.left += Math.max.apply(Math, yLabelWidths);
|
||||
this.bottom -= 1.5 * this.options.gridTextSize;
|
||||
bottomOffsets = (function() {
|
||||
var _i, _ref, _results;
|
||||
_results = [];
|
||||
for (i = _i = 0, _ref = this.data.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
|
||||
_results.push(this.measureText(this.data[i].text, this.options.gridTextSize, -this.options.xLabelAngle).height);
|
||||
}
|
||||
return _results;
|
||||
}).call(this);
|
||||
this.bottom -= Math.max.apply(Math, bottomOffsets);
|
||||
}
|
||||
this.width = Math.max(1, this.right - this.left);
|
||||
this.height = Math.max(1, this.bottom - this.top);
|
||||
@ -402,12 +411,15 @@
|
||||
}
|
||||
};
|
||||
|
||||
Grid.prototype.measureText = function(text, fontSize) {
|
||||
Grid.prototype.measureText = function(text, fontSize, angle) {
|
||||
var ret, tt;
|
||||
if (fontSize == null) {
|
||||
fontSize = 12;
|
||||
}
|
||||
tt = this.raphael.text(100, 100, text).attr('font-size', fontSize);
|
||||
if (angle == null) {
|
||||
angle = 0;
|
||||
}
|
||||
tt = this.raphael.text(100, 100, text).attr('font-size', fontSize).rotate(angle);
|
||||
ret = tt.getBBox();
|
||||
tt.remove();
|
||||
return ret;
|
||||
@ -663,7 +675,7 @@
|
||||
smooth: true,
|
||||
xLabels: 'auto',
|
||||
xLabelFormat: null,
|
||||
xLabelMargin: 50,
|
||||
xLabelMargin: 24,
|
||||
continuousLine: true,
|
||||
hideHover: false
|
||||
};
|
||||
@ -825,15 +837,28 @@
|
||||
};
|
||||
|
||||
Line.prototype.drawXAxis = function() {
|
||||
var drawLabel, l, labels, prevLabelMargin, row, ypos, _i, _len, _results,
|
||||
var drawLabel, l, labels, prevAngleMargin, prevLabelMargin, row, ypos, _i, _len, _results,
|
||||
_this = this;
|
||||
ypos = this.bottom + this.options.gridTextSize * 1.25;
|
||||
ypos = this.bottom + this.options.padding / 2;
|
||||
prevLabelMargin = null;
|
||||
prevAngleMargin = null;
|
||||
drawLabel = function(labelText, xpos) {
|
||||
var label, labelBox;
|
||||
var label, labelBox, margin, offset, textBox;
|
||||
label = _this.drawXAxisLabel(_this.transX(xpos), ypos, labelText);
|
||||
textBox = label.getBBox();
|
||||
label.transform("r" + (-_this.options.xLabelAngle));
|
||||
labelBox = label.getBBox();
|
||||
if ((!(prevLabelMargin != null) || prevLabelMargin >= labelBox.x + labelBox.width) && labelBox.x >= 0 && (labelBox.x + labelBox.width) < _this.el.width()) {
|
||||
label.transform("t0," + (labelBox.height / 2) + "...");
|
||||
if (_this.options.xLabelAngle !== 0) {
|
||||
offset = -0.5 * textBox.width * Math.cos(_this.options.xLabelAngle * Math.PI / 180.0);
|
||||
label.transform("t" + offset + ",0...");
|
||||
}
|
||||
labelBox = label.getBBox();
|
||||
if ((!(prevLabelMargin != null) || prevLabelMargin >= labelBox.x + labelBox.width || (prevAngleMargin != null) && prevAngleMargin >= labelBox.x) && labelBox.x >= 0 && (labelBox.x + labelBox.width) < _this.el.width()) {
|
||||
if (_this.options.xLabelAngle !== 0) {
|
||||
margin = 1.25 * _this.options.gridTextSize / Math.sin(_this.options.xLabelAngle * Math.PI / 180.0);
|
||||
prevAngleMargin = labelBox.x - margin;
|
||||
}
|
||||
return prevLabelMargin = labelBox.x - _this.options.xLabelMargin;
|
||||
} else {
|
||||
return label.remove();
|
||||
@ -1330,15 +1355,27 @@
|
||||
};
|
||||
|
||||
Bar.prototype.drawXAxis = function() {
|
||||
var i, label, labelBox, prevLabelMargin, row, ypos, _i, _ref, _results;
|
||||
ypos = this.bottom + this.options.gridTextSize * 1.25;
|
||||
var i, label, labelBox, margin, offset, prevAngleMargin, prevLabelMargin, row, textBox, ypos, _i, _ref, _results;
|
||||
ypos = this.bottom + this.options.padding / 2;
|
||||
prevLabelMargin = null;
|
||||
prevAngleMargin = null;
|
||||
_results = [];
|
||||
for (i = _i = 0, _ref = this.data.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
|
||||
row = this.data[this.data.length - 1 - i];
|
||||
label = this.drawXAxisLabel(row._x, ypos, row.label);
|
||||
textBox = label.getBBox();
|
||||
label.transform("r" + (-this.options.xLabelAngle));
|
||||
labelBox = label.getBBox();
|
||||
if ((!(prevLabelMargin != null) || prevLabelMargin >= labelBox.x + labelBox.width) && labelBox.x >= 0 && (labelBox.x + labelBox.width) < this.el.width()) {
|
||||
label.transform("t0," + (labelBox.height / 2) + "...");
|
||||
if (this.options.xLabelAngle !== 0) {
|
||||
offset = -0.5 * textBox.width * Math.cos(this.options.xLabelAngle * Math.PI / 180.0);
|
||||
label.transform("t" + offset + ",0...");
|
||||
}
|
||||
if ((!(prevLabelMargin != null) || prevLabelMargin >= labelBox.x + labelBox.width || (prevAngleMargin != null) && prevAngleMargin >= labelBox.x) && labelBox.x >= 0 && (labelBox.x + labelBox.width) < this.el.width()) {
|
||||
if (this.options.xLabelAngle !== 0) {
|
||||
margin = 1.25 * this.options.gridTextSize / Math.sin(this.options.xLabelAngle * Math.PI / 180.0);
|
||||
prevAngleMargin = labelBox.x - margin;
|
||||
}
|
||||
_results.push(prevLabelMargin = labelBox.x - this.options.xLabelMargin);
|
||||
} else {
|
||||
_results.push(label.remove());
|
||||
|
2
morris.min.js
vendored
2
morris.min.js
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user