Added polar plot auto alignment
This commit is contained in:
Родитель
7b02c335f5
Коммит
87e5c514bd
|
@ -35,6 +35,7 @@ import { getSortDirection } from "../../..";
|
|||
import { ChartStateManager } from "../..";
|
||||
import { strings } from "../../../../strings";
|
||||
import { AxisDataBinding } from "../../../specification/types";
|
||||
import { PolarPlotSegmentPlugin } from "../../../solver/plugins";
|
||||
|
||||
export type PolarAxisMode = "null" | "default" | "numerical" | "categorical";
|
||||
|
||||
|
@ -61,6 +62,8 @@ export interface PolarAttributes extends Region2DAttributes {
|
|||
a2r1y: number;
|
||||
a2r2x: number;
|
||||
a2r2y: number;
|
||||
|
||||
autoMargin: boolean;
|
||||
}
|
||||
|
||||
export interface PolarState extends Specification.PlotSegmentState {
|
||||
|
@ -73,6 +76,7 @@ export interface PolarProperties extends Region2DProperties {
|
|||
innerRatio: number;
|
||||
outerRatio: number;
|
||||
equalizeArea: boolean;
|
||||
autoMargin: boolean;
|
||||
}
|
||||
|
||||
export interface PolarObject extends Specification.PlotSegment {
|
||||
|
@ -136,6 +140,7 @@ export class PolarPlotSegment extends PlotSegmentClass<
|
|||
endAngle: 360,
|
||||
innerRatio: 0.5,
|
||||
outerRatio: 0.9,
|
||||
autoMarginTitle: false,
|
||||
};
|
||||
|
||||
public readonly state: PolarState;
|
||||
|
@ -164,6 +169,7 @@ export class PolarPlotSegment extends PlotSegmentClass<
|
|||
"a2r1y",
|
||||
"a2r2x",
|
||||
"a2r2y",
|
||||
"autoMargin",
|
||||
];
|
||||
public attributes: { [name: string]: AttributeDescription } = {
|
||||
x1: {
|
||||
|
@ -258,6 +264,10 @@ export class PolarPlotSegment extends PlotSegmentClass<
|
|||
name: "a2r2y",
|
||||
type: Specification.AttributeType.Number,
|
||||
},
|
||||
autoMargin: {
|
||||
name: "autoMargin",
|
||||
type: Specification.AttributeType.Boolean,
|
||||
},
|
||||
};
|
||||
|
||||
public initializeState(): void {
|
||||
|
@ -284,6 +294,7 @@ export class PolarPlotSegment extends PlotSegmentClass<
|
|||
attrs.a2r1y = 0;
|
||||
attrs.a2r2x = 0;
|
||||
attrs.a2r2y = 0;
|
||||
attrs.autoMargin = false;
|
||||
}
|
||||
|
||||
public createBuilder(
|
||||
|
@ -397,7 +408,8 @@ export class PolarPlotSegment extends PlotSegmentClass<
|
|||
attrs,
|
||||
this.parent.object.constraints,
|
||||
this.object._id,
|
||||
manager
|
||||
manager,
|
||||
this.object.properties
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -808,6 +820,13 @@ export class PolarPlotSegment extends PlotSegmentClass<
|
|||
headerLabel: strings.objects.plotSegment.equalizeArea,
|
||||
}
|
||||
),
|
||||
manager.inputBoolean(
|
||||
{ property: "autoMargin" },
|
||||
{
|
||||
type: "checkbox",
|
||||
label: strings.objects.plotSegment.autoMarginTitle,
|
||||
}
|
||||
),
|
||||
]
|
||||
),
|
||||
...builder.buildPanelWidgets(manager),
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// Licensed under the MIT license.
|
||||
|
||||
import { ConstraintPlugin } from "../abstract";
|
||||
import { PolarAttributes } from "../../prototypes/plot_segments/region_2d/polar";
|
||||
import { PolarAttributes, PolarProperties, } from "../../prototypes/plot_segments/region_2d/polar";
|
||||
import { Geometry } from "../../common";
|
||||
import { Constraint } from "../../specification";
|
||||
import { ChartStateManager } from "../../prototypes";
|
||||
|
@ -13,18 +13,174 @@ export class PolarPlotSegmentPlugin extends ConstraintPlugin {
|
|||
private attrs: PolarAttributes,
|
||||
private chartConstraints: Constraint[],
|
||||
private objectID: string,
|
||||
private manager: ChartStateManager
|
||||
private manager: ChartStateManager,
|
||||
private properties: PolarProperties
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
// eslint-disable-next-line max-lines-per-function
|
||||
public static getCenterByAngle(isAutoMargin: boolean, attrs: PolarAttributes) {
|
||||
const {angle1, angle2, x1, y1, x2, y2, radial1, radial2} = attrs;
|
||||
let cx;
|
||||
let cy;
|
||||
let radialRatio = 1;
|
||||
if (isAutoMargin) {
|
||||
//pos case
|
||||
|
||||
const angleDelta = Math.abs(angle1 - angle2);
|
||||
const startAngle = angle1 % 360;
|
||||
|
||||
if (startAngle >= 0 && startAngle < 90) {
|
||||
//startAngle - 1 quadrant
|
||||
if (angleDelta <= 90 - startAngle) {
|
||||
//endAngle - 1 quadrant => move left bottom corner
|
||||
cx = x1;
|
||||
cy = y1;
|
||||
radialRatio = 2;
|
||||
} else if (angleDelta <= 180 - startAngle) {
|
||||
//endAngle - 4 quadrant => move left
|
||||
cx = x1;
|
||||
cy = (y2 + y1) / 2;
|
||||
} else if (angleDelta + startAngle > 180) {
|
||||
//endAngle - 3 and 4 quadrants
|
||||
cx = (x2 + x1) / 2;
|
||||
cy = (y2 + y1) / 2;
|
||||
}
|
||||
} else if (startAngle >= 90 && startAngle < 180) {
|
||||
//startAngle - 4 quadrant
|
||||
if (angleDelta <= 180 - startAngle) {
|
||||
//endAngle - 4 quadrant => move left top corner
|
||||
cx = x1;
|
||||
cy = y2;
|
||||
radialRatio = 2;
|
||||
} else if (angleDelta <= 270 - startAngle) {
|
||||
//endAngle - 3 quadrant => move top
|
||||
cx = (x2 + x1) / 2;
|
||||
cy = y2;
|
||||
} else if (angleDelta + startAngle > 270) {
|
||||
//endAngle - 2 and 1 quadrants
|
||||
cx = (x2 + x1) / 2;
|
||||
cy = (y2 + y1) / 2;
|
||||
}
|
||||
} else if (startAngle >= 180 && startAngle < 270) {
|
||||
//startAngle - 3 quadrant
|
||||
if (angleDelta <= 270 - startAngle) {
|
||||
//endAngle - 3 quadrant => move right top corner
|
||||
cx = x2;
|
||||
cy = y2;
|
||||
radialRatio = 2;
|
||||
} else if (angleDelta <= 360 - startAngle) {
|
||||
//endAngle - 1 quadrant => move right
|
||||
cx = x2;
|
||||
cy = (y2 + y1) / 2;
|
||||
} else if (angleDelta + startAngle > 360) {
|
||||
//endAngle - 2 and 1 quadrants
|
||||
cx = (x2 + x1) / 2;
|
||||
cy = (y2 + y1) / 2;
|
||||
}
|
||||
} else if (startAngle >= 270 && startAngle < 360) {
|
||||
//startAngle - 2 quadrant
|
||||
if (angleDelta <= 360 - startAngle) {
|
||||
//endAngle - 2 quadrant => move right bottom corner
|
||||
cx = x2;
|
||||
cy = y1;
|
||||
radialRatio = 2;
|
||||
} else if (angleDelta <= 450 - startAngle) {
|
||||
//endAngle - 1 quadrant => move bottom
|
||||
cx = (x2 + x1) / 2;
|
||||
cy = y1;
|
||||
} else if (angleDelta + startAngle > 450) {
|
||||
//endAngle - 2 and 1 quadrants
|
||||
cx = (x2 + x1) / 2;
|
||||
cy = (y2 + y1) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
//neg case
|
||||
if (startAngle < 0 && startAngle >= -90) {
|
||||
//startAngle - 3 quadrant
|
||||
if (angleDelta <= 90 - (90 + startAngle)) {
|
||||
//endAngle - 3 quadrant => move right bottom corner
|
||||
cx = x2;
|
||||
cy = y1;
|
||||
radialRatio = 2;
|
||||
} else if (angleDelta <= 180 - (90 + startAngle)) {
|
||||
//endAngle - 1 quadrant => move bottom
|
||||
cx = (x1 + x2) / 2;
|
||||
cy = y1;
|
||||
} else if (angleDelta - startAngle >= 180) {
|
||||
//endAngle - 2 and 3 quadrants
|
||||
cx = (x2 + x1) / 2;
|
||||
cy = (y2 + y1) / 2;
|
||||
}
|
||||
} else if (startAngle <= -90 && startAngle >= -180) {
|
||||
//startAngle - 3 quadrant
|
||||
if (angleDelta <= 90 - (180 + startAngle)) {
|
||||
//endAngle - 3 quadrant => move right
|
||||
cx = x2;
|
||||
cy = y2;
|
||||
radialRatio = 2;
|
||||
} else if (angleDelta <= 180 - (180 + startAngle)) {
|
||||
//endAngle - 2 quadrant => move top
|
||||
cx = x2;
|
||||
cy = (y2 + y1) / 2;
|
||||
} else if (angleDelta - startAngle >= -270) {
|
||||
//endAngle - 1 and 4 quadrants
|
||||
cx = (x2 + x1) / 2;
|
||||
cy = (y2 + y1) / 2;
|
||||
}
|
||||
} else if (startAngle <= -180 && startAngle >= -270) {
|
||||
//startAngle - 4 quadrant
|
||||
if (angleDelta <= 90 - (270 + startAngle)) {
|
||||
//endAngle - 4 quadrant => move left top corner
|
||||
cx = x1;
|
||||
cy = y2;
|
||||
radialRatio = 2;
|
||||
} else if (angleDelta <= 180 - (270 + startAngle)) {
|
||||
//endAngle - 3 quadrant => move top
|
||||
cx = (x2 + x1) / 2;
|
||||
cy = y2;
|
||||
} else if (angleDelta - startAngle >= -360) {
|
||||
//endAngle - 2 and 1 quadrants
|
||||
cx = (x2 + x1) / 2;
|
||||
cy = (y2 + y1) / 2;
|
||||
}
|
||||
} else if (startAngle <= -270 && startAngle > -360) {
|
||||
//startAngle - 1 quadrant
|
||||
if (angleDelta <= 90 - (360 + startAngle)) {
|
||||
//endAngle - 1 quadrant => move left bottom corner
|
||||
cx = x1;
|
||||
cy = y1;
|
||||
radialRatio = 2;
|
||||
} else if (angleDelta <= 180 - (360 + startAngle)) {
|
||||
//endAngle - 4 quadrant => move right
|
||||
cx = x1;
|
||||
cy = (y2 + y1) / 2;
|
||||
} else if (angleDelta - startAngle >= -450) {
|
||||
//endAngle - 2 and 3 quadrants
|
||||
cx = (x2 + x1) / 2;
|
||||
cy = (y2 + y1) / 2;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cx = (x2 + x1) / 2;
|
||||
cy = (y2 + y1) / 2;
|
||||
}
|
||||
return {cx, cy, ratio: radialRatio};
|
||||
}
|
||||
|
||||
public apply(): boolean {
|
||||
const { attrs } = this;
|
||||
const { angle1, angle2, radial1, radial2, x1, y1, x2, y2 } = attrs;
|
||||
const {attrs} = this;
|
||||
const {angle1, angle2, radial1, radial2} = attrs;
|
||||
|
||||
attrs.cx = (x2 + x1) / 2;
|
||||
attrs.cy = (y2 + y1) / 2;
|
||||
const isAutoMargin = this.properties.autoMargin;
|
||||
|
||||
const { cx, cy } = attrs;
|
||||
const center = PolarPlotSegmentPlugin.getCenterByAngle(isAutoMargin, attrs);
|
||||
attrs.cx = center.cx;
|
||||
attrs.cy = center.cy;
|
||||
|
||||
const {cx, cy} = attrs;
|
||||
|
||||
const toPoint = (radius: number, angle: number) => {
|
||||
const radians = Geometry.degreesToRadians(angle);
|
||||
|
|
|
@ -415,6 +415,7 @@ export const strings = {
|
|||
polarCoordinates: "Polar Coordinates",
|
||||
heightToArea: "Height to Area",
|
||||
equalizeArea: "Equalize area",
|
||||
autoMarginTitle: "Plot auto alignment",
|
||||
inner: "Inner:",
|
||||
outer: "Outer:",
|
||||
radius: "Radius",
|
||||
|
|
Загрузка…
Ссылка в новой задаче