-
29 May 2012 3:05 AM #1
[4.1.0] Chart Axis majorTickSteps appears to be not consistent
[4.1.0] Chart Axis majorTickSteps appears to be not consistent
REQUIRED INFORMATION
Ext version tested:- Ext 4.1.0
- Any
- Any
- The API docs article tells the following about the majorTickSteps config option
Here is the link to that article.If minimum and maximum are specified it forces the number of major ticks to the specified value. If a number of major ticks is forced, it wont search for pretty numbers at the ticks.
http://docs.sencha.com/ext-js/4-1/#!/api/Ext.chart.axis.Axis-cfg-majorTickSteps
- The problem is the fact that I can't get it work as expected, please refer the example to reproduce the problem.
- Just run the page
- 15 ticks between the minimum and maximum of the axis.
- The 60 step between these ticks: (1480 - 440) / (15 + 1) = 60
- There are 15 ticks as expected.
- But the step is about 55.38.
HELPFUL INFORMATIONCode:<html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>majorTickSteps Bug</title> <link type="text/css" rel="stylesheet" href="../resources/css/ext-all.css" /> <script type="text/javascript" src="../ext-all.js"></script> <script type="text/javascript"> Ext.onReady(function () { Ext.create("Ext.chart.Chart", { renderTo : Ext.getBody(), height : 400, width : 800, axes : [{ type : "Numeric", position : "bottom", title : "Time", fields : ["time"], maximum : 1440, minimum : 480, majorTickSteps : 15 }], store : { model : Ext.define(Ext.id(), { extend : "Ext.data.Model", fields : [{ name : "time" }] }), autoLoad : true, proxy : { data : [], type : "memory" } } }); }); </script> </head> <body> </body> </html>
Debugging already done:- The problem appears to be in the calcEnds of the Ext.chart.axis.Axis class or/and the snapEnds function of the Ext.draw.Draw class. Here is the code of the calcEnds function. I have highlighted the related code.
Code:calcEnds: function () { var me = this, fields = me.fields, range = me.getRange(), min = range.min, max = range.max, outfrom, outto, out; out = Ext.draw.Draw.snapEnds(min, max, me.majorTickSteps !== false ? (me.majorTickSteps + 1) : me.steps, (me.majorTickSteps === false)); outfrom = out.from; outto = out.to; if (me.forceMinMax) { if (!isNaN(max)) { out.to = max; } if (!isNaN(min)) { out.from = min; } } if (!isNaN(me.maximum)) { //TODO(nico) users are responsible for their own minimum/maximum values set. //Clipping should be added to remove lines in the chart which are below the axis. out.to = me.maximum; } if (!isNaN(me.minimum)) { //TODO(nico) users are responsible for their own minimum/maximum values set. //Clipping should be added to remove lines in the chart which are below the axis. out.from = me.minimum; } //Adjust after adjusting minimum and maximum out.step = (out.to - out.from) / (outto - outfrom) * out.step; if (me.adjustMaximumByMajorUnit) { out.to = Math.ceil(out.to / out.step) * out.step; out.steps = (out.to - out.from) / out.step; } if (me.adjustMinimumByMajorUnit) { out.from = Math.floor(out.from / out.step) * out.step; out.steps = (out.to - out.from) / out.step; } me.prevMin = min == max ? 0 : min; me.prevMax = max; return out; }- The Ext.draw.Draw.snapEnds returns the object with "from : 400". I can't understand why not 480, there is too hard logic to understand quicly. And it also returns the expected "step : 60".
- Then the step is adjusted here:
and it becomes ~ 55.38.Code://Adjust after adjusting minimum and maximum out.step = (out.to - out.from) / (outto - outfrom) * out.step;
Possible fix:- not provided
-
11 Jun 2012 5:23 AM #2Sencha - Senior Forum Manager
- Join Date
- Mar 2007
- Location
- St. Louis, MO
- Posts
- 33,599
- Vote Rating
- 434
Thanks for the report.
May I suggest one change in your code. Instead of defining the model like you are, just use the fields config in your store. This will create an implicit model for you making your code cleaner letting the framework handle it.Mitchell Simoens @SenchaMitch
Sencha Inc, Senior Forum Manager
________________
http://www.JSONPLint.com - Source to lint your JSONP!
Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
https://github.com/mitchellsimoens
Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/
Need more help with your app? Hire Sencha Services services@sencha.com
Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is almost in print!
When posting code, please use BBCode's CODE tags.
-
11 Jun 2012 5:39 AM #3
Thanks for the update, Mitchell. And, certainly, for opening a bug ticket.
By the way, the following thread appears to be related.
http://www.sencha.com/forum/showthread.php?136795
Thanks for the advice, much appreciate.
Sure, I could use it for such simple examples as my one and I will in the future.
-
12 Mar 2013 6:56 PM #4
-
9 Apr 2013 12:03 PM #5
-
9 Apr 2013 12:16 PM #6Sencha - Senior Forum Manager
- Join Date
- Mar 2007
- Location
- St. Louis, MO
- Posts
- 33,599
- Vote Rating
- 434
The status above updates every night. Once the bug ticket has been marked as closed it will reflect it here that night.
Mitchell Simoens @SenchaMitch
Sencha Inc, Senior Forum Manager
________________
http://www.JSONPLint.com - Source to lint your JSONP!
Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
https://github.com/mitchellsimoens
Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/
Need more help with your app? Hire Sencha Services services@sencha.com
Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is almost in print!
When posting code, please use BBCode's CODE tags.
-
10 Apr 2013 3:10 AM #7
A particular SOLUTION
A particular SOLUTION
Hi everybody,
"SOLVED". My solution to set a specific number of ticks was:
1. Add method "drawAxis" in my axes and then add bold lines.
Code:axes: [ { title: ..., drawAxis: function(init) { var me = this, i, j, x = me.x, y = me.y, gutterX = me.chart.maxGutter[0], gutterY = me.chart.maxGutter[1], dashSize = me.dashSize, subDashesX = me.minorTickSteps || 0, subDashesY = me.minorTickSteps || 0, length = me.length, position = me.position, inflections = [], calcLabels = false, stepCalcs = me.applyData(), step = stepCalcs.step, steps = stepCalcs.steps, from = stepCalcs.from, to = stepCalcs.to, trueLength, currentX, currentY, path, prev, dashesX, dashesY, delta; //If no steps are specified //then don't draw the axis. This generally happens //when an empty store. if (me.hidden || isNaN(step) || (from == to)) { return; } step = 128; // In my case, I want ticks every 128 steps = me.prevMax/step; // My data is a multiple of 128 me.from = stepCalcs.from; // minimum me.to = stepCalcs.to; // maximum if (position == 'left' || position == 'right') { currentX = Math.floor(x) + 0.5; path = ["M", currentX, y, "l", 0, -length]; trueLength = length - (gutterY * 2); } else { currentY = Math.floor(y) + 0.5; path = ["M", x, currentY, "l", length, 0]; trueLength = length - (gutterX * 2); } delta = trueLength / (steps || 1); dashesX = Math.max(subDashesX +1, 0); dashesY = Math.max(subDashesY +1, 0); if (me.type == 'Numeric' || me.type == 'Time') { calcLabels = true; me.labels = [stepCalcs.from]; } if (position == 'right' || position == 'left') { currentY = y - gutterY; currentX = x - ((position == 'left') * dashSize * 2); while (currentY >= y - gutterY - trueLength) { path.push("M", currentX, Math.floor(currentY) + 0.5, "l", dashSize * 2 + 1, 0); if (currentY != y - gutterY) { for (i = 1; i < dashesY; i++) { path.push("M", currentX + dashSize, Math.floor(currentY + delta * i / dashesY) + 0.5, "l", dashSize + 1, 0); } } inflections.push([ Math.floor(x), Math.floor(currentY) ]); currentY -= delta; if (calcLabels) { me.labels.push(me.labels[me.labels.length -1] + step); } if (delta === 0) { break; } } if (Math.round(currentY + delta - (y - gutterY - trueLength))) { path.push("M", currentX, Math.floor(y - length + gutterY) + 0.5, "l", dashSize * 2 + 1, 0); for (i = 1; i < dashesY; i++) { path.push("M", currentX + dashSize, Math.floor(y - length + gutterY + delta * i / dashesY) + 0.5, "l", dashSize + 1, 0); } inflections.push([ Math.floor(x), Math.floor(currentY) ]); if (calcLabels) { me.labels.push(me.labels[me.labels.length -1] + step); } } } else { currentX = x + gutterX; currentY = y - ((position == 'top') * dashSize * 2); while (currentX <= x + gutterX + trueLength) { path.push("M", Math.floor(currentX) + 0.5, currentY, "l", 0, dashSize * 2 + 1); if (currentX != x + gutterX) { for (i = 1; i < dashesX; i++) { path.push("M", Math.floor(currentX - delta * i / dashesX) + 0.5, currentY, "l", 0, dashSize + 1); } } inflections.push([ Math.floor(currentX), Math.floor(y) ]); currentX += delta; if (calcLabels) { me.labels.push(me.labels[me.labels.length -1] + step); } if (delta === 0) { break; } } if (Math.round(currentX - delta - (x + gutterX + trueLength))) { path.push("M", Math.floor(x + length - gutterX) + 0.5, currentY, "l", 0, dashSize * 2 + 1); for (i = 1; i < dashesX; i++) { path.push("M", Math.floor(x + length - gutterX - delta * i / dashesX) + 0.5, currentY, "l", 0, dashSize + 1); } inflections.push([ Math.floor(currentX), Math.floor(y) ]); if (calcLabels) { me.labels.push(me.labels[me.labels.length -1] + step); } } } if (!me.axis) { me.axis = me.chart.surface.add(Ext.apply({ type: 'path', path: path }, me.axisStyle)); } me.axis.setAttributes({ path: path }, true); me.inflections = inflections; if (!init && me.grid) { me.drawGrid(); } me.axisBBox = me.axis.getBBox(); me.drawLabel(); } ]
You found a bug! We've classified it as
EXTJSIV-6493
.
We encourage you to continue the discussion and to find an acceptable workaround while we work on a permanent fix.


Reply With Quote