Added polar plot auto alignment

This commit is contained in:
Ramil Minyukov (Akvelon INC) 2021-09-02 14:19:17 +03:00
Родитель 7b02c335f5
Коммит 87e5c514bd
3 изменённых файлов: 184 добавлений и 8 удалений

Просмотреть файл

@ -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",