| Summary: | add quadratic setting for scale | ||
|---|---|---|---|
| Product: | z_Archived | Reporter: | Erdal Karaca <erdal.karaca.de> |
| Component: | BIRT | Assignee: | Xingsheng Zhu <xzhu> |
| Status: | VERIFIED FIXED | QA Contact: | Maggie Shen <lshen> |
| Severity: | enhancement | ||
| Priority: | P3 | CC: | bluesoldier, hchristensen, Lionel.wyl, wenfeng.fwd |
| Version: | unspecified | Keywords: | plan |
| Target Milestone: | 2.5.0 M6 | ||
| Hardware: | All | ||
| OS: | All | ||
| Whiteboard: | Autoed,G | ||
| Attachments: | |||
Will this be done for 2.5.0? The API change is fine. However we should define the behaviors here. Once new variable "factor" is set, the X/Y "factor" will be used as the X/Y axis coordinate step respectively, and the origin will be in the center. Meanwhile, other scale's settings such as min,max,step size, and origin settings will be ignored. If only one scale factor is set, the other scale factor will be the same. For instance, set X axis scale factory 1000 but doesn't set Y axis, the Y axis will use 1000 by default. In addition, if there are more than one Y axis, the factor UI will be disabled and factor setting will be ignored. This sounds good! Yet, I did not understand what you do mean by "the origin will be in the center". Does this mean that we cannot move the origin anymore when the scaling factor is set? (In reply to comment #4) > This sounds good! > > Yet, I did not understand what you do mean by "the origin will be in the > center". Does this mean that we cannot move the origin anymore when the scaling > factor is set? > No, we can't move the origin (0,0) when scale factor is set, but we can move the x/y axis. The intersection point can move. From my current point of understanding, providing the api change might overlap with Bounds.scale() or BoundsImpl.create( offsetX, offsetY, width * xScale, height * yScale ); where xScale and yScale are two values appropriately calculated to let the plot area look quadratic (I tried this but it got too messy and error-prone; you have to take the canvas' size into account *and* the legend area's size *and* all the other chart blocks which might be visible on the chart). The comment #2 (implementation suggestion) of Yulin Wang can thus be simplified either: If the factor UI (="quadratic setting") is enabled, then the plot area will be rendererd quadratic no matter if the chart's dimensions are equal or not. Maybe, there should be an update to the bug report... Now, I would simplify the whole suggestion and say the "quadratic setting" is a feature of the chart just like setting the - orientation - floor fill - rotation - etc. Fixed. Add an attribute ‘factor’ on scale. It indicates Value represents/Points. When the factor is set, only the step size for scale can be set as well. And the ‘factor’ attribute only works for non-category linear axis. Thanks, it seems to work! In case someone wonders how to use this new feature, here is an example of how I use it: Axis xAxis = chart.getPrimaryBaseAxes()[ 0 ]; Axis yAxis = chart.getPrimaryOrthogonalAxis( xAxis ); xAxis.getScale().setFactor( 25.4 ); yAxis.getScale().setFactor( 25.4 ); Both axes have value units in millimeters, so I set the factor to 25.4 (= 1 inch to millimeters). This results in having the plot area being drawn quadratic, i.e. 1 x value unit is the same as 1 y value unit on the screen. Unfortunately, I said it "seems" to work. There are some side-effects: - plot area does not render on all available space - zooming will not work any more - zooming was possible when doing Bounds.scale(...) and calling Generator.build(...) There is a typo in AutoScale.setFactor (AutoScale.setFcto). I will provide more feedback once I have done evaluation of the new feature... Auto zooming can adjust the value of step size if user did not set it, but it will also cause a small modification of coordinates and factors to fit the equation: Max-Min=Integer*StepSize. So I disable it and accordingly user need to set a proper step size when setting factors, otherwise the step size will be 10,100,1000 and so on. And about the plot area, i think it works as before. Could you attach a screen shot here? Created attachment 127133 [details]
quadratic plot area - without zooming
zooming is possible when scaling the bounds before generating the chart:
- Bounds.scale(...), then Generator.build(...)
Created attachment 127134 [details]
plot area - with zooming
Bounds.scale() is called passing 1.5 as argument, should zoom in by 1.5 of its initial size.
Instead, the axes dimensions grow.
Created attachment 127312 [details]
AutoScale to regard scale's min/max values when factor is set
AutoScale should take min/max values of the scale when user set them. This is just to ensure that the renderer will not cut off parts of the plot area...
(In reply to comment #13) > Created an attachment (id=127312) [details] > AutoScale to regard scale's min/max values when factor is set > > AutoScale should take min/max values of the scale when user set them. This is > just to ensure that the renderer will not cut off parts of the plot area... > Actually when the factor is set, the value of Max-Mix depends on the plot's bounds. So it doesn't make sense to set min/max value any more after setting factor value. I have made some more investigations on this issue and I think I found the best/optimal solution: When factor is set on scale: - if step is set, take it as is and do not calculate automagically - if min/max is set, take as is - do not modify factor, i.e. double factor = scModel.getFactor( ) * 72 / xs.getDpiResolution( ); may be wrong and should be taken as is: double factor = scModel.getFactor( ); In return to this change, the beforeComputation/afterComputation script event must be implemented in IChartEventHandler (JavaScript counterparts are marked deprecated?). This will allow the (api) user to calculate a proper scale factor and step based on some specific business logic and we do not have to argue why and whether it makes sense to set min/max when scale factor is set ;-) I will provide a patch to enable the new suggestion (and hopefully a representative example chart). If you think that this is the wrong direction, let me know... (In reply to comment #15) > When factor is set on scale: > - if step is set, take it as is and do not calculate automagically Right. User can set step size with factor. > - if min/max is set, take as is Now enable the minimum value of scale when the factor is set. I still consider that min and max value of scale can not be set at the same time with factor. Max-Mix depends on the plot bounds when factor is set. > - do not modify factor, i.e. > double factor = scModel.getFactor( ) * 72 / > xs.getDpiResolution( ); > may be wrong and should be taken as is: > double factor = scModel.getFactor( ); There's a comment in source to explain this. We set value/points in UI, and we use value/pixel in computation. So we need this translation which can deal with different dpi in different output formats. 1. If user can set step, he must be able to set min values either. - when omitting min values, the renderer might start rendering at a "bad" starting point - e.g.: step = 1000, min = -333 renderer will render using these values: (-333, 777.777, 1777.77, 2777.77, ...) -> the user can provide a "good" starting point by adjusting the min value; e.g. by setting min value to -500: (-500, 500, 1500, ...) 2. If we use value/pixel transformation, then not all of the plot area is used; plot area is always rendered equally, no matter how big the plot area is... (this can be circumvented by multiplying the factor with DISPLAY_RESOLUTION/72) Yes, your first point is exactly right. And the minimum value of scale is enabled in comment #16. The unit is always point in chart UI, e.g. insets. So we need this translation indeed. I think your problem about plot area can be resolved by bounds.scale(72d/dpi)(ChartPreviewPainter). Created attachment 128009 [details]
before-computation event enabled in java handler
It should be possible to calculate the scale factor in the before-computation event.
This event type is not propagated to the java handler.
Thus, this patch will enable the user to handle before-computation events.
For the second parameter to beforeComputations(),
I am not sure what to declare in the prototype.
Here is a sample on how you would use IExtendedChartEventsHandler
to calculate a dynamic scale factor which will make the plot area filled properly:
public class MyJavaEventHandler
extends ChartEventHandlerAdapter
implements IExtendedChartEventsHandler {
public void beforeComputations( Chart cm, Object computations ) {
PlotWith2DAxes comp = (PlotWith2DAxes) computations;
ChartWithAxes chart = (ChartWithAxes) cm;
Axis xAxis = chart.getPrimaryBaseAxes()[ 0 ];
Axis yAxis = chart.getPrimaryOrthogonalAxis( xAxis );
Scale xScale = xAxis.getScale();
Scale yScale = yAxis.getScale();
Bounds boPlot = cm.getPlot().getBounds();
Insets insPlot = cm.getPlot().getInsets();
boPlot = boPlot.adjustedInstance( insPlot );
double widthPix = boPlot.getWidth();
double heightPix = boPlot.getHeight();
double xMin = ((NumberDataElement) xAxis.getScale().getMin()).getValue();
double yMin = ((NumberDataElement) yAxis.getScale().getMin()).getValue();
double xMax = ((NumberDataElement) xAxis.getScale().getMax()).getValue();
double yMax = ((NumberDataElement) yAxis.getScale().getMax()).getValue();
double xRange = Math.abs( xMax
- xMin );
double yRange = Math.abs( yMax
- yMin );
{
double factor = -1;
if ( xRange < yRange ) {
factor = xRange
/ widthPix;
} else {
factor = yRange
/ heightPix;
}
factor = factor
* comp.getDisplayServer().getDpiResolution() / 72.;
xScale.setFactor( factor );
yScale.setFactor( factor );
}
}
}
Hi Erdal, Regarding the script method, beforeComputation/afterComputation was marked as deprecated, but still could be used in javascript editor. But I recommend you use other methods like beforeGeneration or afterDataSetFilled. Please have a try. This bug only focus on adding "factor" property to set fixed axis ticks span. It's not supposed to add script method here. We will close this bug if the "factor" works. Any further questions, please browse http://birt-exchange.com. Thank you! The implementation of the scale factor satisfies our needs; the bug can be closed. Just for clarification: I would not call it "the factor", but instead it should be just called "scaling factor" as of multiplying /dividing a number by a given 'factor'... I will report a new bug dealing with the beforeComputation event (the suggested alternatives do not fit well: called too late or too early)... verified on build 2.5.0 v20090317-0630. |
Created attachment 83761 [details] x and y scaling factors are same when chart is drawn Problem: I want the plot area to be rendered 'quadratic', i.e. there shall be the same scaling factors for both x and y axes. One can set the plot area to have symmetric values (abs(x-min) == abs(x-max) == abs(y-min) == abs(y-max)), but there are user requirements regarding chart visualisation (e.g. x and y scales have different values, but must be rendered quadratic)... Since this is a common requirement to a charting library, there should be an API interface to set same scaling factors. I suggest to provide an API interface to be used as followed: double scalingFactor = ...; xAxisPrimary.getScale().setFactor( scalingFactor ); yAxisPrimary.getScale().setFactor( scalingFactor );