Collapsable list (#625)
* Initial implementation of CollapsiblePanel
* Add margins to group items
* Update text object attributes panel
* Update textbox object attributes panel
* Update rect object attributes panel
* Update chart object attributes panel
* Update symbol object attributes panel
* Update axes and plot segments objects attributes panel
* Update legends objects attributes panel
* Update icon & guide coordiantor objects attributes panel
* Update image object attributes panel
* Update line object attributes panel
* Update curve plot segment object attributes panel
* Fix jitter layout icon size
* Add delimiter between groups
* Update object name header of attribute panel
* Add polar-grid icon for Fluent UI icons
* Fix data binding menu for "Group by..." button
* Change border color
* Change border for group header
* Fix inputNumber layout
* Revert "Update chart object attributes panel"
This reverts commit 9bdb9e3fcb
.
* Configure Rotation input
Co-authored-by: Ilfat Galiev <v-igaliev@microsoft.com>
This commit is contained in:
Родитель
79abf0dfc9
Коммит
4b8c318c43
|
@ -514,7 +514,7 @@
|
|||
.editable-text-view {
|
||||
$font-size: 14px;
|
||||
$padding: 0;
|
||||
$height: 24px;
|
||||
$height: 32px;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
@ -540,7 +540,7 @@
|
|||
|
||||
transition: border-color $transition-default;
|
||||
|
||||
border-bottom: 2px solid transparent;
|
||||
border-bottom: 2px solid $gray-210;
|
||||
|
||||
&:hover {
|
||||
border-bottom: 2px solid $gray-210;
|
||||
|
|
|
@ -18,12 +18,12 @@
|
|||
font-size: 14px;
|
||||
line-height: 24px;
|
||||
padding-bottom: 4px;
|
||||
margin-top: 1px;
|
||||
margin-bottom: 0px;
|
||||
border-bottom: 1px solid $gray-180;
|
||||
border-bottom: 0px solid $gray-180;
|
||||
color: $black;
|
||||
|
||||
.svg-image-icon {
|
||||
padding: 2px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
vertical-align: top;
|
||||
|
@ -1104,7 +1104,7 @@
|
|||
padding-top: 4px;
|
||||
background: lighten($color-active, 30%);
|
||||
height: 26px;
|
||||
|
||||
|
||||
&-attrubutes {
|
||||
@extend .el-drag-over;
|
||||
width: auto;
|
||||
|
|
|
@ -7,7 +7,7 @@ $theme: "";
|
|||
$theme-primary-background: $gray-100;
|
||||
$theme-primary-foreground: "";
|
||||
|
||||
$theme-secondary-background: $gray-225;
|
||||
$theme-secondary-background: $gray-230;
|
||||
$theme-secondary-foreground: #333;
|
||||
|
||||
$theme-hover-background: $color-header-hover;
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
import * as React from "react";
|
||||
import { ButtonFlat } from "./buttons";
|
||||
import * as R from "../resources";
|
||||
import {
|
||||
FluentTextField,
|
||||
labelRender,
|
||||
} from "../views/panels/widgets/controls/fluentui_customized_components";
|
||||
import { TextField } from "@fluentui/react";
|
||||
|
||||
export interface EditableTextViewProps {
|
||||
text: string;
|
||||
|
@ -57,32 +60,22 @@ export class EditableTextView extends React.Component<
|
|||
});
|
||||
}
|
||||
|
||||
public componentDidMount() {
|
||||
if (this.props.autofocus) {
|
||||
this.refs.input.select();
|
||||
}
|
||||
}
|
||||
|
||||
public componentDidUpdate(
|
||||
prevProps: EditableTextViewProps,
|
||||
prevState: EditableTextViewState
|
||||
) {
|
||||
if (prevState.editing == false && this.state.editing == true) {
|
||||
this.refs.input.select();
|
||||
}
|
||||
}
|
||||
|
||||
public render() {
|
||||
if (this.state.editing) {
|
||||
return (
|
||||
<div className="editable-text-view editable-text-view-editing">
|
||||
<input
|
||||
type="text"
|
||||
ref="input"
|
||||
return (
|
||||
<div>
|
||||
<FluentTextField>
|
||||
<TextField
|
||||
value={this.state.currentText}
|
||||
onChange={() =>
|
||||
this.setState({ currentText: this.refs.input.value })
|
||||
}
|
||||
onRenderLabel={labelRender}
|
||||
type="text"
|
||||
onChange={(event, newValue) => {
|
||||
this.setState({ currentText: newValue });
|
||||
}}
|
||||
onBlur={() => {
|
||||
if (this.state.currentText == this.props.text) {
|
||||
this.cancelEdit();
|
||||
}
|
||||
}}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key == "Enter") {
|
||||
this.confirmEdit();
|
||||
|
@ -91,26 +84,15 @@ export class EditableTextView extends React.Component<
|
|||
this.cancelEdit();
|
||||
}
|
||||
}}
|
||||
autoFocus={true}
|
||||
onBlur={() => {
|
||||
if (this.state.currentText == this.props.text) {
|
||||
this.cancelEdit();
|
||||
}
|
||||
autoFocus={false}
|
||||
styles={{
|
||||
fieldGroup: {
|
||||
border: !this.state.editing && "none",
|
||||
},
|
||||
}}
|
||||
/>
|
||||
<ButtonFlat
|
||||
url={R.getSVGIcon("general/confirm")}
|
||||
onClick={this.confirmEdit}
|
||||
stopPropagation={true}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<div className="editable-text-view" onClick={this.startEdit}>
|
||||
<span className="text">{this.props.text}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
</FluentTextField>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -174,7 +174,11 @@ export class AttributePanel extends React.Component<
|
|||
<div className="attribute-editor charticulator__widget-container">
|
||||
<section className="attribute-editor-element" key={object._id}>
|
||||
<div className="header">
|
||||
<SVGImageIcon url={getObjectIcon(object.classID)} />
|
||||
<SVGImageIcon
|
||||
url={getObjectIcon(object.classID)}
|
||||
height={32}
|
||||
width={32}
|
||||
/>
|
||||
<EditableTextView
|
||||
text={object.properties.name}
|
||||
onEdit={(newValue) => {
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
import {
|
||||
GroupedList,
|
||||
GroupHeader,
|
||||
IGroupHeaderProps,
|
||||
SelectionMode,
|
||||
} from "@fluentui/react";
|
||||
import * as React from "react";
|
||||
import {
|
||||
FluentGroupedList,
|
||||
groupHeaderStyles,
|
||||
groupStyles,
|
||||
} from "./fluentui_customized_components";
|
||||
|
||||
export const CollapsiblePanel: React.FunctionComponent<{
|
||||
header: string;
|
||||
widgets: JSX.Element[];
|
||||
isCollapsed?: boolean;
|
||||
}> = ({ header, widgets, isCollapsed }) => {
|
||||
const [groupState, setIsCollapsed] = React.useState<boolean>(
|
||||
isCollapsed === undefined ? true : isCollapsed
|
||||
);
|
||||
return (
|
||||
<FluentGroupedList>
|
||||
<GroupedList
|
||||
groupProps={{
|
||||
onRenderHeader: (props?: IGroupHeaderProps): JSX.Element => {
|
||||
return (
|
||||
<GroupHeader
|
||||
onRenderGroupHeaderCheckbox={() => null}
|
||||
{...props}
|
||||
styles={groupHeaderStyles}
|
||||
onToggleCollapse={(group) => {
|
||||
setIsCollapsed(!group.isCollapsed);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
},
|
||||
}}
|
||||
selectionMode={SelectionMode.none}
|
||||
items={widgets
|
||||
.filter((w) => w !== null)
|
||||
.map((w, i) => ({
|
||||
key: i,
|
||||
item: w,
|
||||
}))}
|
||||
onRenderCell={(
|
||||
nestingDepth?: number,
|
||||
item?: {
|
||||
item: JSX.Element;
|
||||
key: number;
|
||||
},
|
||||
itemIndex?: number
|
||||
) => {
|
||||
return item && typeof itemIndex === "number" && itemIndex > -1 ? (
|
||||
<div className="charticulator__widget-collapsible-panel-item">
|
||||
{item.item}
|
||||
</div>
|
||||
) : null;
|
||||
}}
|
||||
groups={[
|
||||
{
|
||||
count: widgets.length,
|
||||
key: "group",
|
||||
level: 0,
|
||||
name: header,
|
||||
startIndex: 0,
|
||||
isCollapsed: groupState,
|
||||
},
|
||||
]}
|
||||
compact={true}
|
||||
styles={groupStyles}
|
||||
/>
|
||||
</FluentGroupedList>
|
||||
);
|
||||
};
|
|
@ -4,8 +4,13 @@
|
|||
import * as React from "react";
|
||||
import {
|
||||
IDropdownProps,
|
||||
IGroupedListStyleProps,
|
||||
IGroupedListStyles,
|
||||
IGroupHeaderStyleProps,
|
||||
IGroupHeaderStyles,
|
||||
ILabelStyles,
|
||||
IRenderFunction,
|
||||
IStyleFunctionOrObject,
|
||||
ITextFieldProps,
|
||||
Label,
|
||||
} from "@fluentui/react";
|
||||
|
@ -68,12 +73,6 @@ export const FluentLayoutItem = styled.div<{ flex: number }>`
|
|||
|
||||
export const defaultFontWeight = 400;
|
||||
|
||||
export const FluentLabelFontWeight = styled.div`
|
||||
label {
|
||||
font-weight: ${defaultFontWeight};
|
||||
}
|
||||
`;
|
||||
|
||||
export const defaultLabelStyle: ILabelStyles = {
|
||||
root: {
|
||||
fontWeight: defaultFontWeight,
|
||||
|
@ -88,6 +87,39 @@ export const NestedChartButtonsWrapper = styled.div`
|
|||
margin-top: 5px;
|
||||
`;
|
||||
|
||||
export const FluentGroupedList = styled.div`
|
||||
.charticulator__widget-collapsible-panel-item {
|
||||
margin-left: 15px;
|
||||
margin-right: 15px;
|
||||
min-width: 270px;
|
||||
}
|
||||
|
||||
.ms-List-surface .ms-List-cell .ms-List-cell:last-child {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
`;
|
||||
|
||||
export const groupHeaderStyles: IStyleFunctionOrObject<
|
||||
IGroupHeaderStyleProps,
|
||||
IGroupHeaderStyles
|
||||
> = {
|
||||
title: {
|
||||
fontWeight: 600,
|
||||
},
|
||||
headerCount: {
|
||||
display: "none",
|
||||
},
|
||||
};
|
||||
|
||||
export const groupStyles: IStyleFunctionOrObject<
|
||||
IGroupedListStyleProps,
|
||||
IGroupedListStyles
|
||||
> = {
|
||||
group: {
|
||||
borderTop: "1px #C8C6C4 solid",
|
||||
},
|
||||
};
|
||||
|
||||
export const PlaceholderStyle = styled.div<{ color?: string }>`
|
||||
input {
|
||||
::-webkit-input-placeholder {
|
||||
|
|
|
@ -11,8 +11,8 @@ import {
|
|||
import * as React from "react";
|
||||
import { prettyNumber } from "../../../../../core";
|
||||
import {
|
||||
defaultFontWeight,
|
||||
defaultLabelStyle,
|
||||
FluentLabelFontWeight,
|
||||
FluentLayoutItem,
|
||||
FluentRowLayout,
|
||||
labelRender,
|
||||
|
@ -126,38 +126,42 @@ export const FluentInputNumber: React.FC<InputNumberProps> = (props) => {
|
|||
const tick = props.updownTick || 0.1;
|
||||
return (
|
||||
<>
|
||||
<FluentLabelFontWeight>
|
||||
<SpinButton
|
||||
label={!props.showSlider ? props.label : null}
|
||||
labelPosition={Position.top}
|
||||
value={formatNumber(+value)}
|
||||
iconProps={
|
||||
props.updownStyle == "font"
|
||||
? {
|
||||
iconName: "Font",
|
||||
}
|
||||
: null
|
||||
<SpinButton
|
||||
label={!props.showSlider ? props.label : null}
|
||||
labelPosition={Position.top}
|
||||
value={formatNumber(+value)}
|
||||
iconProps={
|
||||
props.updownStyle == "font"
|
||||
? {
|
||||
iconName: "Font",
|
||||
}
|
||||
: null
|
||||
}
|
||||
step={tick}
|
||||
onIncrement={(value) => {
|
||||
if (reportValue(parseNumber(value) + tick)) {
|
||||
setValue(parseNumber(value) + tick);
|
||||
}
|
||||
step={tick}
|
||||
onIncrement={(value) => {
|
||||
if (reportValue(parseNumber(value) + tick)) {
|
||||
setValue(parseNumber(value) + tick);
|
||||
}
|
||||
}}
|
||||
onDecrement={(value) => {
|
||||
if (reportValue(parseNumber(value) - tick)) {
|
||||
setValue(parseNumber(value) - tick);
|
||||
}
|
||||
}}
|
||||
onValidate={(value) => {
|
||||
const num = parseNumber(value);
|
||||
if (reportValue(num)) {
|
||||
setValue(num);
|
||||
return formatNumber(parseNumber(value));
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</FluentLabelFontWeight>
|
||||
}}
|
||||
onDecrement={(value) => {
|
||||
if (reportValue(parseNumber(value) - tick)) {
|
||||
setValue(parseNumber(value) - tick);
|
||||
}
|
||||
}}
|
||||
onValidate={(value) => {
|
||||
const num = parseNumber(value);
|
||||
if (reportValue(num)) {
|
||||
setValue(num);
|
||||
return formatNumber(parseNumber(value));
|
||||
}
|
||||
}}
|
||||
styles={{
|
||||
label: {
|
||||
fontWeight: defaultFontWeight,
|
||||
height: 25,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -100,6 +100,8 @@ import { InputImage, InputImageProperty } from "./controls/fluentui_image";
|
|||
import { Director, IDefaultValue, MenuItemBuilder } from "../../dataset/data_field_binding_builder";
|
||||
import { FluentInputFormat } from "./controls/fluentui_input_format";
|
||||
|
||||
import { CollapsiblePanel } from "./controls/collapsiblePanel";
|
||||
|
||||
export type OnEditMappingHandler = (
|
||||
attribute: string,
|
||||
mapping: Specification.Mapping
|
||||
|
@ -264,7 +266,7 @@ export class FluentUIWidgetManager
|
|||
} catch (ex) {
|
||||
return {
|
||||
pass: false,
|
||||
error: "Invalid format",
|
||||
error: strings.objects.invalidFormat,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1205,62 +1207,72 @@ export class FluentUIWidgetManager
|
|||
options: Prototypes.Controls.GroupByEditorOptions
|
||||
): JSX.Element {
|
||||
let button: HTMLElement;
|
||||
let text = "Group by...";
|
||||
switch (options.mode) {
|
||||
case "button":
|
||||
if (options.value) {
|
||||
if (options.value.expression) {
|
||||
text = "Group by " + options.value.expression;
|
||||
let text = strings.objects.plotSegment.groupBy;
|
||||
const getControl = () => {
|
||||
switch (options.mode) {
|
||||
case "button":
|
||||
if (options.value) {
|
||||
if (options.value.expression) {
|
||||
text =
|
||||
strings.objects.plotSegment.groupByCategory +
|
||||
options.value.expression;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (
|
||||
<FluentButton
|
||||
marginTop={"0px"}
|
||||
key={
|
||||
this.getKeyFromProperty(options.target?.property) +
|
||||
options?.table +
|
||||
options?.value
|
||||
}
|
||||
>
|
||||
<DefaultButton
|
||||
text={text}
|
||||
elementRef={(e) => (button = e)}
|
||||
iconProps={{
|
||||
iconName: "RowsGroup",
|
||||
}}
|
||||
onClick={() => {
|
||||
globals.popupController.popupAt(
|
||||
(context) => {
|
||||
return (
|
||||
<PopupView context={context}>
|
||||
<GroupByEditor
|
||||
manager={this}
|
||||
value={options.value}
|
||||
options={options}
|
||||
/>
|
||||
</PopupView>
|
||||
);
|
||||
},
|
||||
{ anchor: ReactDOM.findDOMNode(button) as Element }
|
||||
);
|
||||
}}
|
||||
return (
|
||||
<FluentButton
|
||||
marginTop={"0px"}
|
||||
key={
|
||||
this.getKeyFromProperty(options.target?.property) +
|
||||
options?.table +
|
||||
options?.value
|
||||
}
|
||||
>
|
||||
<DefaultButton
|
||||
text={text}
|
||||
elementRef={(e) => (button = e)}
|
||||
iconProps={{
|
||||
iconName: "RowsGroup",
|
||||
}}
|
||||
onClick={() => {
|
||||
globals.popupController.popupAt(
|
||||
(context) => {
|
||||
return (
|
||||
<PopupView context={context}>
|
||||
<GroupByEditor
|
||||
manager={this}
|
||||
value={options.value}
|
||||
options={options}
|
||||
/>
|
||||
</PopupView>
|
||||
);
|
||||
},
|
||||
{ anchor: button as Element }
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</FluentButton>
|
||||
);
|
||||
case "panel":
|
||||
return (
|
||||
<GroupByEditor
|
||||
key={
|
||||
this.getKeyFromProperty(options?.target?.property) +
|
||||
options.table +
|
||||
options?.value
|
||||
}
|
||||
manager={this}
|
||||
value={options.value}
|
||||
options={options}
|
||||
/>
|
||||
</FluentButton>
|
||||
);
|
||||
case "panel":
|
||||
return (
|
||||
<GroupByEditor
|
||||
key={
|
||||
this.getKeyFromProperty(options?.target?.property) +
|
||||
options.table +
|
||||
options?.value
|
||||
}
|
||||
manager={this}
|
||||
value={options.value}
|
||||
options={options}
|
||||
/>
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ display: "inline" }} ref={(e) => (button = e)}>
|
||||
{getControl()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
public nestedChartEditor(
|
||||
|
@ -1371,6 +1383,19 @@ export class FluentUIWidgetManager
|
|||
);
|
||||
}
|
||||
|
||||
public verticalGroup(
|
||||
options: Prototypes.Controls.VerticalGroupOptions,
|
||||
widgets: JSX.Element[]
|
||||
) {
|
||||
return (
|
||||
<CollapsiblePanel
|
||||
header={options.header}
|
||||
widgets={widgets}
|
||||
isCollapsed={options.isCollapsed}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
public table(
|
||||
rows: JSX.Element[][],
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
|
|
|
@ -120,7 +120,9 @@ export class WidgetManager
|
|||
) {}
|
||||
|
||||
public tooltip(
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
widget: JSX.Element,
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
tooltipContent: JSX.Element
|
||||
): JSX.Element {
|
||||
throw new Error("Method not implemented.");
|
||||
|
@ -710,7 +712,7 @@ export class WidgetManager
|
|||
const items = this.getPropertyValue(property) as string[];
|
||||
return (
|
||||
<PopupView context={context}>
|
||||
<ReorderStringsValue
|
||||
<ReorderStringsValue
|
||||
items={items}
|
||||
onConfirm={(items, customOrder) => {
|
||||
this.emitSetProperty(property, items);
|
||||
|
@ -1213,6 +1215,21 @@ export class WidgetManager
|
|||
);
|
||||
}
|
||||
|
||||
public verticalGroup(
|
||||
options: Prototypes.Controls.VerticalGroupOptions,
|
||||
widgets: JSX.Element[]
|
||||
) {
|
||||
return (
|
||||
<div className="charticulator__widget-vertical">
|
||||
{widgets.map((x, id) => (
|
||||
<span className="el-layout-item" key={id}>
|
||||
{x}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
public table(
|
||||
rows: JSX.Element[][],
|
||||
// eslint-disable-next-line
|
||||
|
|
|
@ -132,6 +132,11 @@ export interface InputColorOptions {
|
|||
// eslint-disable-next-line
|
||||
export interface TableOptions {}
|
||||
|
||||
export interface VerticalGroupOptions {
|
||||
isCollapsed?: boolean;
|
||||
header: string;
|
||||
}
|
||||
|
||||
export interface FilterEditorOptions {
|
||||
table: string;
|
||||
target: {
|
||||
|
@ -184,6 +189,7 @@ export interface InputFormatOptions {
|
|||
|
||||
export interface InputFormatOptions {
|
||||
blank?: string;
|
||||
label?: string;
|
||||
}
|
||||
|
||||
export interface InputFormatOptions {
|
||||
|
@ -264,6 +270,7 @@ export interface WidgetManager {
|
|||
|
||||
// Basic layout elements
|
||||
horizontal(cols: number[], ...widgets: Widget[]): Widget;
|
||||
verticalGroup(options: VerticalGroupOptions, ...widgets: Widget[]): Widget;
|
||||
vertical(...widgets: Widget[]): Widget;
|
||||
table(rows: Widget[][], options?: TableOptions): Widget;
|
||||
scrollList(widgets: Widget[], options?: ScrollListOptions): Widget;
|
||||
|
|
|
@ -239,19 +239,16 @@ export class GuideCoordinatorClass extends ChartElementClass<
|
|||
manager: Controls.WidgetManager
|
||||
): Controls.Widget[] {
|
||||
return [
|
||||
manager.sectionHeader(strings.objects.guides.guideCoordinator),
|
||||
manager.row(
|
||||
strings.objects.guides.count,
|
||||
manager.inputNumber(
|
||||
{ property: "count" },
|
||||
{
|
||||
showUpdown: true,
|
||||
updownTick: 1,
|
||||
updownRange: [1, 100],
|
||||
minimum: 1,
|
||||
maximum: 100,
|
||||
}
|
||||
)
|
||||
manager.inputNumber(
|
||||
{ property: "count" },
|
||||
{
|
||||
showUpdown: true,
|
||||
updownTick: 1,
|
||||
updownRange: [1, 100],
|
||||
minimum: 1,
|
||||
maximum: 100,
|
||||
label: strings.objects.guides.count,
|
||||
}
|
||||
),
|
||||
];
|
||||
}
|
||||
|
|
|
@ -272,19 +272,26 @@ export class CategoricalLegendClass extends LegendClass {
|
|||
|
||||
return [
|
||||
...widgets,
|
||||
manager.inputSelect(
|
||||
{ property: "orientation" },
|
||||
manager.verticalGroup(
|
||||
{
|
||||
type: "radio",
|
||||
showLabel: false,
|
||||
icons: ["AlignHorizontalCenter", "AlignVerticalCenter"],
|
||||
labels: [
|
||||
strings.objects.legend.vertical,
|
||||
strings.objects.legend.horizontal,
|
||||
],
|
||||
options: ["vertical", "horizontal"],
|
||||
label: strings.objects.legend.orientation,
|
||||
}
|
||||
header: strings.objects.legend.categoricalLegend,
|
||||
},
|
||||
[
|
||||
manager.inputSelect(
|
||||
{ property: "orientation" },
|
||||
{
|
||||
type: "radio",
|
||||
showLabel: false,
|
||||
icons: ["AlignHorizontalCenter", "AlignVerticalCenter"],
|
||||
labels: [
|
||||
strings.objects.legend.vertical,
|
||||
strings.objects.legend.horizontal,
|
||||
],
|
||||
options: ["vertical", "horizontal"],
|
||||
label: strings.objects.legend.orientation,
|
||||
}
|
||||
),
|
||||
]
|
||||
),
|
||||
];
|
||||
}
|
||||
|
|
|
@ -189,106 +189,118 @@ export abstract class LegendClass extends ChartElementClass {
|
|||
manager: Prototypes.Controls.WidgetManager & CharticulatorPropertyAccessors
|
||||
): Controls.Widget[] {
|
||||
const widget = [
|
||||
manager.sectionHeader(strings.objects.legend.labels),
|
||||
manager.inputFontFamily(
|
||||
{ property: "fontFamily" },
|
||||
{ label: strings.objects.font }
|
||||
),
|
||||
manager.inputNumber(
|
||||
{ property: "fontSize" },
|
||||
manager.verticalGroup(
|
||||
{
|
||||
showUpdown: true,
|
||||
updownStyle: "font",
|
||||
updownTick: 2,
|
||||
label: strings.objects.size,
|
||||
}
|
||||
),
|
||||
manager.inputColor(
|
||||
{ property: "textColor" },
|
||||
{ label: strings.objects.color }
|
||||
),
|
||||
manager.inputSelect(
|
||||
{ property: "markerShape" },
|
||||
{
|
||||
type: "dropdown",
|
||||
showLabel: true,
|
||||
icons: ["RectangleShape", "TriangleShape", "Ellipse"],
|
||||
labels: [
|
||||
strings.toolbar.rectangle,
|
||||
strings.toolbar.triangle,
|
||||
strings.toolbar.ellipse,
|
||||
],
|
||||
options: ["rectangle", "triangle", "circle"],
|
||||
label: strings.objects.legend.markerShape,
|
||||
}
|
||||
),
|
||||
manager.label("Ordering"),
|
||||
manager.reorderWidget(
|
||||
{
|
||||
property: "order",
|
||||
header: strings.objects.legend.labels,
|
||||
},
|
||||
{
|
||||
items: this.getOrderingObjects(),
|
||||
onConfirm: (items: string[]) => {
|
||||
const scale = this.getScale()[0];
|
||||
const newMap: { [name: string]: ValueType } = {};
|
||||
items.forEach((item) => {
|
||||
newMap[item] = (<Specification.AttributeMap>(
|
||||
scale.properties.mapping
|
||||
))[item];
|
||||
});
|
||||
Prototypes.setProperty(scale, "mapping", newMap);
|
||||
manager.emitSetProperty(
|
||||
{
|
||||
property: "mapping",
|
||||
field: null,
|
||||
[
|
||||
manager.inputFontFamily(
|
||||
{ property: "fontFamily" },
|
||||
{ label: strings.objects.font }
|
||||
),
|
||||
manager.inputNumber(
|
||||
{ property: "fontSize" },
|
||||
{
|
||||
showUpdown: true,
|
||||
updownStyle: "font",
|
||||
updownTick: 2,
|
||||
label: strings.objects.size,
|
||||
}
|
||||
),
|
||||
manager.inputColor(
|
||||
{ property: "textColor" },
|
||||
{ label: strings.objects.color }
|
||||
),
|
||||
manager.inputSelect(
|
||||
{ property: "markerShape" },
|
||||
{
|
||||
type: "dropdown",
|
||||
showLabel: true,
|
||||
icons: ["RectangleShape", "TriangleShape", "Ellipse"],
|
||||
labels: [
|
||||
strings.toolbar.rectangle,
|
||||
strings.toolbar.triangle,
|
||||
strings.toolbar.ellipse,
|
||||
],
|
||||
options: ["rectangle", "triangle", "circle"],
|
||||
label: strings.objects.legend.markerShape,
|
||||
}
|
||||
),
|
||||
manager.label("Ordering"),
|
||||
manager.reorderWidget(
|
||||
{
|
||||
property: "order",
|
||||
},
|
||||
{
|
||||
items: this.getOrderingObjects(),
|
||||
onConfirm: (items: string[]) => {
|
||||
const scale = this.getScale()[0];
|
||||
const newMap: { [name: string]: ValueType } = {};
|
||||
items.forEach((item) => {
|
||||
newMap[item] = (<Specification.AttributeMap>(
|
||||
scale.properties.mapping
|
||||
))[item];
|
||||
});
|
||||
Prototypes.setProperty(scale, "mapping", newMap);
|
||||
manager.emitSetProperty(
|
||||
{
|
||||
property: "mapping",
|
||||
field: null,
|
||||
},
|
||||
<Specification.AttributeValue>newMap
|
||||
);
|
||||
},
|
||||
<Specification.AttributeValue>newMap
|
||||
);
|
||||
},
|
||||
}
|
||||
}
|
||||
),
|
||||
]
|
||||
),
|
||||
manager.sectionHeader(strings.objects.legend.layout),
|
||||
manager.vertical(
|
||||
manager.label(strings.alignment.alignment),
|
||||
manager.horizontal(
|
||||
[0, 0],
|
||||
manager.inputSelect(
|
||||
{ property: "alignX" },
|
||||
{
|
||||
type: "radio",
|
||||
icons: [
|
||||
"AlignHorizontalLeft",
|
||||
"AlignHorizontalCenter",
|
||||
"AlignHorizontalRight",
|
||||
],
|
||||
labels: [
|
||||
strings.alignment.left,
|
||||
strings.alignment.middle,
|
||||
strings.alignment.right,
|
||||
],
|
||||
options: ["start", "middle", "end"],
|
||||
}
|
||||
manager.verticalGroup(
|
||||
{
|
||||
header: strings.objects.legend.layout,
|
||||
},
|
||||
[
|
||||
manager.vertical(
|
||||
manager.label(strings.alignment.alignment),
|
||||
manager.horizontal(
|
||||
[0, 0],
|
||||
manager.inputSelect(
|
||||
{ property: "alignX" },
|
||||
{
|
||||
type: "radio",
|
||||
icons: [
|
||||
"AlignHorizontalLeft",
|
||||
"AlignHorizontalCenter",
|
||||
"AlignHorizontalRight",
|
||||
],
|
||||
labels: [
|
||||
strings.alignment.left,
|
||||
strings.alignment.middle,
|
||||
strings.alignment.right,
|
||||
],
|
||||
options: ["start", "middle", "end"],
|
||||
}
|
||||
),
|
||||
manager.inputSelect(
|
||||
{ property: "alignY" },
|
||||
{
|
||||
type: "radio",
|
||||
options: ["start", "middle", "end"],
|
||||
icons: [
|
||||
"AlignVerticalBottom",
|
||||
"AlignVerticalCenter",
|
||||
"AlignVerticalTop",
|
||||
],
|
||||
labels: [
|
||||
strings.alignment.bottom,
|
||||
strings.alignment.middle,
|
||||
strings.alignment.top,
|
||||
],
|
||||
}
|
||||
),
|
||||
null
|
||||
)
|
||||
),
|
||||
manager.inputSelect(
|
||||
{ property: "alignY" },
|
||||
{
|
||||
type: "radio",
|
||||
options: ["start", "middle", "end"],
|
||||
icons: [
|
||||
"AlignVerticalBottom",
|
||||
"AlignVerticalCenter",
|
||||
"AlignVerticalTop",
|
||||
],
|
||||
labels: [
|
||||
strings.alignment.bottom,
|
||||
strings.alignment.middle,
|
||||
strings.alignment.top,
|
||||
],
|
||||
}
|
||||
),
|
||||
null
|
||||
)
|
||||
]
|
||||
),
|
||||
];
|
||||
|
||||
|
|
|
@ -334,49 +334,62 @@ export class DataAxisClass extends MarkClass<
|
|||
manager,
|
||||
strings.toolbar.dataAxis
|
||||
);
|
||||
const r = [...axisWidgets];
|
||||
r.push(
|
||||
manager.inputSelect(
|
||||
{ property: "visibleOn" },
|
||||
const r = [
|
||||
manager.verticalGroup(
|
||||
{
|
||||
labels: [
|
||||
strings.objects.visibleOn.all,
|
||||
strings.objects.visibleOn.first,
|
||||
strings.objects.visibleOn.last,
|
||||
],
|
||||
showLabel: true,
|
||||
options: ["all", "first", "last"],
|
||||
type: "dropdown",
|
||||
label: strings.objects.visibleOn.label,
|
||||
}
|
||||
)
|
||||
);
|
||||
header: strings.objects.general,
|
||||
},
|
||||
[
|
||||
manager.inputSelect(
|
||||
{ property: "visibleOn" },
|
||||
{
|
||||
labels: [
|
||||
strings.objects.visibleOn.all,
|
||||
strings.objects.visibleOn.first,
|
||||
strings.objects.visibleOn.last,
|
||||
],
|
||||
showLabel: true,
|
||||
options: ["all", "first", "last"],
|
||||
type: "dropdown",
|
||||
label: strings.objects.visibleOn.label,
|
||||
}
|
||||
),
|
||||
]
|
||||
),
|
||||
...axisWidgets,
|
||||
];
|
||||
if (props.dataExpressions.length > 0) {
|
||||
r.push(manager.sectionHeader("Data Expressions"));
|
||||
r.push(
|
||||
manager.arrayWidget(
|
||||
{ property: "dataExpressions" },
|
||||
(item, index) => {
|
||||
const expressionInput = manager.inputExpression(
|
||||
{
|
||||
property: "dataExpressions",
|
||||
field:
|
||||
item.field instanceof Array
|
||||
? [...item.field, "expression"]
|
||||
: [item.field, "expression"],
|
||||
},
|
||||
{ table: this.getGlyphClass().object.table }
|
||||
);
|
||||
return React.createElement(
|
||||
"fragment",
|
||||
{ key: index },
|
||||
expressionInput
|
||||
);
|
||||
},
|
||||
manager.verticalGroup(
|
||||
{
|
||||
allowDelete: true,
|
||||
allowReorder: true,
|
||||
}
|
||||
header: strings.objects.axes.dataExpressions,
|
||||
},
|
||||
[
|
||||
manager.arrayWidget(
|
||||
{ property: "dataExpressions" },
|
||||
(item, index) => {
|
||||
const expressionInput = manager.inputExpression(
|
||||
{
|
||||
property: "dataExpressions",
|
||||
field:
|
||||
item.field instanceof Array
|
||||
? [...item.field, "expression"]
|
||||
: [item.field, "expression"],
|
||||
},
|
||||
{ table: this.getGlyphClass().object.table }
|
||||
);
|
||||
return React.createElement(
|
||||
"fragment",
|
||||
{ key: index },
|
||||
expressionInput
|
||||
);
|
||||
},
|
||||
{
|
||||
allowDelete: true,
|
||||
allowReorder: true,
|
||||
}
|
||||
),
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* eslint-disable max-lines-per-function */
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
|
@ -285,92 +286,112 @@ export class IconElementClass extends EmphasizableMarkClass<
|
|||
const parentWidgets = super.getAttributePanelWidgets(manager);
|
||||
const props = this.object.properties;
|
||||
let widgets = [
|
||||
manager.sectionHeader(strings.toolbar.icon),
|
||||
manager.mappingEditor(strings.objects.icon.image, "image", {}),
|
||||
manager.mappingEditor(strings.objects.size, "size", {
|
||||
acceptKinds: [Specification.DataKind.Numerical],
|
||||
hints: { rangeNumber: [0, 100] },
|
||||
defaultValue: 400,
|
||||
numberOptions: {
|
||||
showSlider: true,
|
||||
minimum: 0,
|
||||
sliderRange: [0, 3600],
|
||||
sliderFunction: "sqrt",
|
||||
manager.verticalGroup(
|
||||
{
|
||||
header: strings.toolbar.icon,
|
||||
},
|
||||
}),
|
||||
[
|
||||
manager.mappingEditor(strings.objects.icon.image, "image", {}),
|
||||
manager.mappingEditor(strings.objects.size, "size", {
|
||||
acceptKinds: [Specification.DataKind.Numerical],
|
||||
hints: { rangeNumber: [0, 100] },
|
||||
defaultValue: 400,
|
||||
numberOptions: {
|
||||
showSlider: true,
|
||||
minimum: 0,
|
||||
sliderRange: [0, 3600],
|
||||
sliderFunction: "sqrt",
|
||||
},
|
||||
}),
|
||||
manager.mappingEditor(
|
||||
strings.objects.visibleOn.visibility,
|
||||
"visible",
|
||||
{
|
||||
defaultValue: true,
|
||||
}
|
||||
),
|
||||
]
|
||||
),
|
||||
];
|
||||
|
||||
widgets = widgets.concat([
|
||||
manager.sectionHeader(strings.objects.icon.anchorAndRotation),
|
||||
manager.row(
|
||||
strings.objects.icon.anchorX,
|
||||
manager.horizontal(
|
||||
[0, 1],
|
||||
manager.inputSelect(
|
||||
{ property: "alignment", field: "x" },
|
||||
{
|
||||
type: "radio",
|
||||
icons: [
|
||||
"AlignHorizontalLeft",
|
||||
"AlignHorizontalCenter",
|
||||
"AlignHorizontalRight",
|
||||
],
|
||||
labels: [
|
||||
strings.alignment.left,
|
||||
strings.alignment.middle,
|
||||
strings.alignment.right,
|
||||
],
|
||||
options: ["left", "middle", "right"],
|
||||
}
|
||||
manager.verticalGroup(
|
||||
{
|
||||
header: strings.objects.anchorAndRotation,
|
||||
},
|
||||
[
|
||||
manager.horizontal(
|
||||
[0, 1],
|
||||
manager.inputSelect(
|
||||
{ property: "alignment", field: "x" },
|
||||
{
|
||||
type: "radio",
|
||||
icons: [
|
||||
"AlignHorizontalLeft",
|
||||
"AlignHorizontalCenter",
|
||||
"AlignHorizontalRight",
|
||||
],
|
||||
labels: [
|
||||
strings.alignment.left,
|
||||
strings.alignment.middle,
|
||||
strings.alignment.right,
|
||||
],
|
||||
options: ["left", "middle", "right"],
|
||||
label: strings.objects.anchorX,
|
||||
}
|
||||
),
|
||||
props.alignment.x != "middle"
|
||||
? manager.inputNumber(
|
||||
{ property: "alignment", field: "xMargin" },
|
||||
{
|
||||
label: strings.margins.margin,
|
||||
}
|
||||
)
|
||||
: null
|
||||
),
|
||||
props.alignment.x != "middle"
|
||||
? manager.horizontal(
|
||||
[0, 1],
|
||||
manager.label(strings.margins.margin),
|
||||
manager.inputNumber({ property: "alignment", field: "xMargin" })
|
||||
)
|
||||
: null
|
||||
)
|
||||
),
|
||||
manager.row(
|
||||
strings.objects.icon.anchorY,
|
||||
manager.horizontal(
|
||||
[0, 1],
|
||||
manager.inputSelect(
|
||||
{ property: "alignment", field: "y" },
|
||||
{
|
||||
type: "radio",
|
||||
icons: [
|
||||
"AlignVerticalTop",
|
||||
"AlignVerticalCenter",
|
||||
"AlignVerticalBottom",
|
||||
],
|
||||
labels: [
|
||||
strings.alignment.top,
|
||||
strings.alignment.middle,
|
||||
strings.alignment.bottom,
|
||||
],
|
||||
options: ["top", "middle", "bottom"],
|
||||
}
|
||||
manager.horizontal(
|
||||
[0, 1],
|
||||
manager.inputSelect(
|
||||
{ property: "alignment", field: "y" },
|
||||
{
|
||||
type: "radio",
|
||||
icons: [
|
||||
"AlignVerticalTop",
|
||||
"AlignVerticalCenter",
|
||||
"AlignVerticalBottom",
|
||||
],
|
||||
labels: [
|
||||
strings.alignment.top,
|
||||
strings.alignment.middle,
|
||||
strings.alignment.bottom,
|
||||
],
|
||||
options: ["top", "middle", "bottom"],
|
||||
label: strings.objects.anchorY,
|
||||
}
|
||||
),
|
||||
props.alignment.y != "middle"
|
||||
? manager.inputNumber(
|
||||
{ property: "alignment", field: "yMargin" },
|
||||
{
|
||||
label: strings.margins.margin,
|
||||
}
|
||||
)
|
||||
: null
|
||||
),
|
||||
props.alignment.y != "middle"
|
||||
? manager.horizontal(
|
||||
[0, 1],
|
||||
manager.label("Margin:"),
|
||||
manager.inputNumber({ property: "alignment", field: "yMargin" })
|
||||
)
|
||||
: null
|
||||
)
|
||||
]
|
||||
),
|
||||
manager.verticalGroup(
|
||||
{
|
||||
header: strings.objects.style,
|
||||
},
|
||||
[
|
||||
manager.mappingEditor(strings.objects.opacity, "opacity", {
|
||||
hints: { rangeNumber: [0, 1] },
|
||||
defaultValue: 1,
|
||||
numberOptions: { showSlider: true, minimum: 0, maximum: 1 },
|
||||
}),
|
||||
]
|
||||
),
|
||||
manager.sectionHeader(strings.objects.style),
|
||||
manager.mappingEditor(strings.objects.opacity, "opacity", {
|
||||
hints: { rangeNumber: [0, 1] },
|
||||
defaultValue: 1,
|
||||
numberOptions: { showSlider: true, minimum: 0, maximum: 1, step: 0.1 },
|
||||
}),
|
||||
manager.mappingEditor(strings.objects.visibleOn.visibility, "visible", {
|
||||
defaultValue: true,
|
||||
}),
|
||||
]);
|
||||
return widgets.concat(parentWidgets);
|
||||
}
|
||||
|
|
|
@ -96,115 +96,148 @@ export class ImageElementClass extends EmphasizableMarkClass<
|
|||
manager: Controls.WidgetManager
|
||||
): Controls.Widget[] {
|
||||
const parentWidgets = super.getAttributePanelWidgets(manager);
|
||||
let widgets: Controls.Widget[] = [
|
||||
manager.sectionHeader(strings.objects.size),
|
||||
manager.mappingEditor(strings.objects.width, "width", {
|
||||
hints: { autoRange: true, startWithZero: "always" },
|
||||
acceptKinds: [Specification.DataKind.Numerical],
|
||||
defaultAuto: true,
|
||||
}),
|
||||
manager.mappingEditor(strings.objects.height, "height", {
|
||||
hints: { autoRange: true, startWithZero: "always" },
|
||||
acceptKinds: [Specification.DataKind.Numerical],
|
||||
defaultAuto: true,
|
||||
}),
|
||||
manager.sectionHeader(strings.toolbar.image),
|
||||
manager.mappingEditor(strings.objects.icon.image, "image", {}),
|
||||
manager.inputSelect(
|
||||
{ property: "imageMode" },
|
||||
const widgets: Controls.Widget[] = [
|
||||
manager.verticalGroup(
|
||||
{
|
||||
type: "dropdown",
|
||||
showLabel: true,
|
||||
labels: [
|
||||
strings.objects.image.letterbox,
|
||||
strings.objects.image.stretch,
|
||||
],
|
||||
options: ["letterbox", "stretch"],
|
||||
label: strings.objects.image.imageMode,
|
||||
}
|
||||
header: strings.objects.general,
|
||||
},
|
||||
[
|
||||
manager.mappingEditor(strings.objects.width, "width", {
|
||||
hints: { autoRange: true, startWithZero: "always" },
|
||||
acceptKinds: [Specification.DataKind.Numerical],
|
||||
defaultAuto: true,
|
||||
}),
|
||||
manager.mappingEditor(strings.objects.height, "height", {
|
||||
hints: { autoRange: true, startWithZero: "always" },
|
||||
acceptKinds: [Specification.DataKind.Numerical],
|
||||
defaultAuto: true,
|
||||
}),
|
||||
manager.mappingEditor(
|
||||
strings.objects.visibleOn.visibility,
|
||||
"visible",
|
||||
{
|
||||
defaultValue: true,
|
||||
}
|
||||
),
|
||||
]
|
||||
),
|
||||
...(this.object.properties.imageMode == "letterbox"
|
||||
? [
|
||||
manager.label(strings.alignment.align),
|
||||
manager.horizontal(
|
||||
[0, 1],
|
||||
manager.inputSelect(
|
||||
{ property: "alignX" },
|
||||
// manager.sectionHeader(strings.objects.size),
|
||||
manager.verticalGroup(
|
||||
{
|
||||
header: strings.toolbar.image,
|
||||
},
|
||||
[
|
||||
manager.mappingEditor(strings.objects.icon.image, "image", {}),
|
||||
manager.inputSelect(
|
||||
{ property: "imageMode" },
|
||||
{
|
||||
type: "dropdown",
|
||||
showLabel: true,
|
||||
labels: [
|
||||
strings.objects.image.letterbox,
|
||||
strings.objects.image.stretch,
|
||||
],
|
||||
options: ["letterbox", "stretch"],
|
||||
label: strings.objects.image.imageMode,
|
||||
}
|
||||
),
|
||||
...(this.object.properties.imageMode == "letterbox"
|
||||
? [
|
||||
manager.label(strings.alignment.align),
|
||||
manager.horizontal(
|
||||
[0, 1],
|
||||
manager.inputSelect(
|
||||
{ property: "alignX" },
|
||||
{
|
||||
type: "radio",
|
||||
options: ["start", "middle", "end"],
|
||||
icons: [
|
||||
"AlignHorizontalLeft",
|
||||
"AlignHorizontalCenter",
|
||||
"AlignHorizontalRight",
|
||||
],
|
||||
labels: [
|
||||
strings.alignment.left,
|
||||
strings.alignment.middle,
|
||||
strings.alignment.right,
|
||||
],
|
||||
}
|
||||
),
|
||||
manager.inputSelect(
|
||||
{ property: "alignY" },
|
||||
{
|
||||
type: "radio",
|
||||
options: ["start", "middle", "end"],
|
||||
icons: [
|
||||
"AlignVerticalBottom",
|
||||
"AlignVerticalCenter",
|
||||
"AlignVerticalTop",
|
||||
],
|
||||
labels: [
|
||||
strings.alignment.bottom,
|
||||
strings.alignment.middle,
|
||||
strings.alignment.top,
|
||||
],
|
||||
}
|
||||
)
|
||||
),
|
||||
]
|
||||
: []),
|
||||
]
|
||||
),
|
||||
manager.verticalGroup(
|
||||
{
|
||||
header: strings.alignment.padding,
|
||||
},
|
||||
[
|
||||
manager.label(strings.coordinateSystem.x),
|
||||
manager.inputNumber(
|
||||
{ property: "paddingX" },
|
||||
{
|
||||
updownTick: 1,
|
||||
showUpdown: true,
|
||||
}
|
||||
),
|
||||
manager.label(strings.coordinateSystem.y),
|
||||
manager.inputNumber(
|
||||
{ property: "paddingY" },
|
||||
{
|
||||
updownTick: 1,
|
||||
showUpdown: true,
|
||||
}
|
||||
),
|
||||
]
|
||||
),
|
||||
manager.verticalGroup(
|
||||
{
|
||||
header: strings.objects.style,
|
||||
},
|
||||
[
|
||||
manager.mappingEditor(strings.objects.fill, "fill", {}),
|
||||
manager.mappingEditor(strings.objects.stroke, "stroke", {}),
|
||||
this.object.mappings.stroke != null
|
||||
? manager.mappingEditor(
|
||||
strings.objects.strokeWidth,
|
||||
"strokeWidth",
|
||||
{
|
||||
type: "radio",
|
||||
options: ["start", "middle", "end"],
|
||||
icons: [
|
||||
"AlignHorizontalLeft",
|
||||
"AlignHorizontalCenter",
|
||||
"AlignHorizontalRight",
|
||||
],
|
||||
labels: [
|
||||
strings.alignment.left,
|
||||
strings.alignment.middle,
|
||||
strings.alignment.right,
|
||||
],
|
||||
}
|
||||
),
|
||||
manager.inputSelect(
|
||||
{ property: "alignY" },
|
||||
{
|
||||
type: "radio",
|
||||
options: ["start", "middle", "end"],
|
||||
icons: [
|
||||
"AlignVerticalBottom",
|
||||
"AlignVerticalCenter",
|
||||
"AlignVerticalTop",
|
||||
],
|
||||
labels: [
|
||||
strings.alignment.bottom,
|
||||
strings.alignment.middle,
|
||||
strings.alignment.top,
|
||||
],
|
||||
hints: { rangeNumber: [0, 5] },
|
||||
defaultValue: 1,
|
||||
numberOptions: {
|
||||
showSlider: true,
|
||||
sliderRange: [0, 5],
|
||||
minimum: 0,
|
||||
},
|
||||
}
|
||||
)
|
||||
),
|
||||
]
|
||||
: []),
|
||||
manager.sectionHeader(strings.alignment.padding),
|
||||
manager.label(strings.coordinateSystem.x),
|
||||
manager.inputNumber(
|
||||
{ property: "paddingX" },
|
||||
{
|
||||
updownTick: 1,
|
||||
showUpdown: true,
|
||||
}
|
||||
: null,
|
||||
manager.mappingEditor(strings.objects.opacity, "opacity", {
|
||||
hints: { rangeNumber: [0, 1] },
|
||||
defaultValue: 1,
|
||||
numberOptions: { showSlider: true, minimum: 0, maximum: 1 },
|
||||
}),
|
||||
]
|
||||
),
|
||||
manager.label(strings.coordinateSystem.y),
|
||||
manager.inputNumber(
|
||||
{ property: "paddingY" },
|
||||
{
|
||||
updownTick: 1,
|
||||
showUpdown: true,
|
||||
}
|
||||
),
|
||||
manager.sectionHeader(strings.objects.style),
|
||||
manager.mappingEditor(strings.objects.fill, "fill", {}),
|
||||
manager.mappingEditor(strings.objects.stroke, "stroke", {}),
|
||||
];
|
||||
if (this.object.mappings.stroke != null) {
|
||||
widgets.push(
|
||||
manager.mappingEditor(strings.objects.strokeWidth, "strokeWidth", {
|
||||
hints: { rangeNumber: [0, 5] },
|
||||
defaultValue: 1,
|
||||
numberOptions: { showSlider: true, sliderRange: [0, 5], minimum: 0 },
|
||||
})
|
||||
);
|
||||
}
|
||||
widgets = widgets.concat([
|
||||
manager.mappingEditor(strings.objects.opacity, "opacity", {
|
||||
hints: { rangeNumber: [0, 1] },
|
||||
defaultValue: 1,
|
||||
numberOptions: { showSlider: true, minimum: 0, maximum: 1, step: 0.1 },
|
||||
}),
|
||||
manager.mappingEditor(strings.objects.visibleOn.visibility, "visible", {
|
||||
defaultValue: true,
|
||||
}),
|
||||
]);
|
||||
return widgets.concat(parentWidgets);
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ import * as Graphics from "../../graphics";
|
|||
import { EmphasizableMarkClass } from "./emphasis";
|
||||
import { ChartStateManager } from "../state";
|
||||
import { MappingType } from "../../specification";
|
||||
import { strings } from "../../../strings";
|
||||
|
||||
export { LineElementAttributes, LineElementProperties };
|
||||
|
||||
|
@ -305,45 +306,59 @@ export class LineElementClass extends EmphasizableMarkClass<
|
|||
): Controls.Widget[] {
|
||||
const parentWidgets = super.getAttributePanelWidgets(manager);
|
||||
return [
|
||||
manager.sectionHeader("Line"),
|
||||
manager.mappingEditor("X Span", "dx", {
|
||||
hints: { autoRange: true, startWithZero: "always" },
|
||||
acceptKinds: [Specification.DataKind.Numerical],
|
||||
defaultAuto: true,
|
||||
}),
|
||||
manager.mappingEditor("Y Span", "dy", {
|
||||
hints: { autoRange: true, startWithZero: "always" },
|
||||
acceptKinds: [Specification.DataKind.Numerical],
|
||||
defaultAuto: true,
|
||||
}),
|
||||
manager.sectionHeader("Style"),
|
||||
manager.mappingEditor("Stroke", "stroke", {}),
|
||||
manager.mappingEditor("Line Width", "strokeWidth", {
|
||||
hints: { rangeNumber: [0, 5] },
|
||||
defaultValue: 1,
|
||||
numberOptions: { showSlider: true, sliderRange: [0, 5], minimum: 0 },
|
||||
}),
|
||||
manager.row(
|
||||
"Line Style",
|
||||
manager.inputSelect(
|
||||
{ property: "strokeStyle" },
|
||||
{
|
||||
type: "dropdown",
|
||||
showLabel: true,
|
||||
icons: ["stroke/solid", "stroke/dashed", "stroke/dotted"],
|
||||
labels: ["Solid", "Dashed", "Dotted"],
|
||||
options: ["solid", "dashed", "dotted"],
|
||||
}
|
||||
)
|
||||
manager.verticalGroup(
|
||||
{
|
||||
header: strings.toolbar.line,
|
||||
},
|
||||
[
|
||||
manager.mappingEditor("X Span", "dx", {
|
||||
hints: { autoRange: true, startWithZero: "always" },
|
||||
acceptKinds: [Specification.DataKind.Numerical],
|
||||
defaultAuto: true,
|
||||
}),
|
||||
manager.mappingEditor("Y Span", "dy", {
|
||||
hints: { autoRange: true, startWithZero: "always" },
|
||||
acceptKinds: [Specification.DataKind.Numerical],
|
||||
defaultAuto: true,
|
||||
}),
|
||||
manager.mappingEditor("Visibility", "visible", {
|
||||
defaultValue: true,
|
||||
}),
|
||||
]
|
||||
),
|
||||
manager.verticalGroup(
|
||||
{
|
||||
header: strings.objects.style,
|
||||
},
|
||||
[
|
||||
manager.mappingEditor(strings.objects.stroke, "stroke", {}),
|
||||
manager.mappingEditor(strings.objects.strokeWidth, "strokeWidth", {
|
||||
hints: { rangeNumber: [0, 5] },
|
||||
defaultValue: 1,
|
||||
numberOptions: {
|
||||
showSlider: true,
|
||||
sliderRange: [0, 5],
|
||||
minimum: 0,
|
||||
},
|
||||
}),
|
||||
manager.inputSelect(
|
||||
{ property: "strokeStyle" },
|
||||
{
|
||||
type: "dropdown",
|
||||
showLabel: true,
|
||||
icons: ["stroke/solid", "stroke/dashed", "stroke/dotted"],
|
||||
labels: ["Solid", "Dashed", "Dotted"],
|
||||
options: ["solid", "dashed", "dotted"],
|
||||
label: strings.objects.line.lineStyle,
|
||||
}
|
||||
),
|
||||
manager.mappingEditor(strings.objects.opacity, "opacity", {
|
||||
hints: { rangeNumber: [0, 1] },
|
||||
defaultValue: 1,
|
||||
numberOptions: { showSlider: true, minimum: 0, maximum: 1 },
|
||||
}),
|
||||
]
|
||||
),
|
||||
manager.mappingEditor("Opacity", "opacity", {
|
||||
hints: { rangeNumber: [0, 1] },
|
||||
defaultValue: 1,
|
||||
numberOptions: { showSlider: true, minimum: 0, maximum: 1, step: 0.1 },
|
||||
}),
|
||||
manager.mappingEditor("Visibility", "visible", {
|
||||
defaultValue: true,
|
||||
}),
|
||||
].concat(parentWidgets);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* eslint-disable max-lines-per-function */
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
|
@ -25,6 +26,7 @@ import {
|
|||
RectElementAttributes,
|
||||
RectElementProperties,
|
||||
} from "./rect.attrs";
|
||||
import { strings } from "../../../strings";
|
||||
|
||||
export { RectElementAttributes, RectElementProperties };
|
||||
|
||||
|
@ -172,70 +174,99 @@ export class RectElementClass extends EmphasizableMarkClass<
|
|||
const parentWidgets = super.getAttributePanelWidgets(manager);
|
||||
|
||||
let widgets: Controls.Widget[] = [
|
||||
manager.sectionHeader("Size & Shape"),
|
||||
manager.mappingEditor("Width", "width", {
|
||||
hints: { autoRange: true, startWithZero: "always" },
|
||||
acceptKinds: [DataKind.Numerical],
|
||||
defaultAuto: true,
|
||||
}),
|
||||
manager.mappingEditor("Height", "height", {
|
||||
hints: { autoRange: true, startWithZero: "always" },
|
||||
acceptKinds: [DataKind.Numerical],
|
||||
defaultAuto: true,
|
||||
}),
|
||||
manager.inputSelect(
|
||||
{ property: "shape" },
|
||||
manager.verticalGroup(
|
||||
{
|
||||
type: "dropdown",
|
||||
showLabel: true,
|
||||
label: "Shape",
|
||||
icons: ["RectangleShape", "TriangleShape", "Ellipse"],
|
||||
labels: ["Rectangle", "Triangle", "Ellipse"],
|
||||
options: ["rectangle", "triangle", "ellipse"],
|
||||
}
|
||||
header: strings.objects.general,
|
||||
},
|
||||
[
|
||||
manager.mappingEditor(strings.objects.width, "width", {
|
||||
hints: { autoRange: true, startWithZero: "always" },
|
||||
acceptKinds: [DataKind.Numerical],
|
||||
defaultAuto: true,
|
||||
}),
|
||||
manager.mappingEditor(strings.objects.height, "height", {
|
||||
hints: { autoRange: true, startWithZero: "always" },
|
||||
acceptKinds: [DataKind.Numerical],
|
||||
defaultAuto: true,
|
||||
}),
|
||||
manager.inputSelect(
|
||||
{ property: "shape" },
|
||||
{
|
||||
type: "dropdown",
|
||||
showLabel: true,
|
||||
label: strings.objects.rect.shape,
|
||||
icons: ["RectangleShape", "TriangleShape", "Ellipse"],
|
||||
labels: [
|
||||
strings.objects.rect.shapes.rectangle,
|
||||
strings.objects.rect.shapes.triangle,
|
||||
strings.objects.rect.shapes.ellipse,
|
||||
],
|
||||
options: ["rectangle", "triangle", "ellipse"],
|
||||
}
|
||||
),
|
||||
manager.inputBoolean(
|
||||
{ property: "allowFlipping" },
|
||||
{
|
||||
type: "checkbox",
|
||||
label: strings.objects.rect.flipping,
|
||||
}
|
||||
),
|
||||
manager.mappingEditor(
|
||||
strings.objects.visibleOn.visibility,
|
||||
"visible",
|
||||
{
|
||||
defaultValue: true,
|
||||
}
|
||||
),
|
||||
]
|
||||
),
|
||||
manager.inputBoolean(
|
||||
{ property: "allowFlipping" },
|
||||
manager.verticalGroup(
|
||||
{
|
||||
type: "checkbox",
|
||||
label: "Flipping",
|
||||
}
|
||||
header: strings.objects.style,
|
||||
},
|
||||
[
|
||||
manager.mappingEditor(strings.objects.fill, "fill", {}),
|
||||
manager.mappingEditor(strings.objects.stroke, "stroke", {}),
|
||||
this.object.mappings.stroke != null
|
||||
? manager.mappingEditor(
|
||||
strings.objects.strokeWidth,
|
||||
"strokeWidth",
|
||||
{
|
||||
hints: { rangeNumber: [0, 5] },
|
||||
defaultValue: 1,
|
||||
numberOptions: {
|
||||
showSlider: true,
|
||||
sliderRange: [0, 5],
|
||||
minimum: 0,
|
||||
},
|
||||
}
|
||||
)
|
||||
: null,
|
||||
this.object.mappings.stroke != null
|
||||
? manager.inputSelect(
|
||||
{ property: "strokeStyle" },
|
||||
{
|
||||
type: "dropdown",
|
||||
showLabel: true,
|
||||
label: "Line Style",
|
||||
icons: ["stroke/solid", "stroke/dashed", "stroke/dotted"],
|
||||
labels: [
|
||||
strings.objects.links.solid,
|
||||
strings.objects.links.dashed,
|
||||
strings.objects.links.dotted,
|
||||
],
|
||||
options: ["solid", "dashed", "dotted"],
|
||||
}
|
||||
)
|
||||
: null,
|
||||
manager.mappingEditor(strings.objects.opacity, "opacity", {
|
||||
hints: { rangeNumber: [0, 1] },
|
||||
defaultValue: 1,
|
||||
numberOptions: { showSlider: true, minimum: 0, maximum: 1 },
|
||||
}),
|
||||
]
|
||||
),
|
||||
manager.sectionHeader("Style"),
|
||||
manager.mappingEditor("Fill", "fill", {}),
|
||||
manager.mappingEditor("Stroke", "stroke", {}),
|
||||
];
|
||||
if (this.object.mappings.stroke != null) {
|
||||
widgets.push(
|
||||
manager.mappingEditor("Line Width", "strokeWidth", {
|
||||
hints: { rangeNumber: [0, 5] },
|
||||
defaultValue: 1,
|
||||
numberOptions: { showSlider: true, sliderRange: [0, 5], minimum: 0 },
|
||||
})
|
||||
);
|
||||
manager.inputSelect(
|
||||
{ property: "strokeStyle" },
|
||||
{
|
||||
type: "dropdown",
|
||||
showLabel: true,
|
||||
label: "Line Style",
|
||||
icons: ["stroke/solid", "stroke/dashed", "stroke/dotted"],
|
||||
labels: ["Solid", "Dashed", "Dotted"],
|
||||
options: ["solid", "dashed", "dotted"],
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
widgets = widgets.concat([
|
||||
manager.mappingEditor("Opacity", "opacity", {
|
||||
hints: { rangeNumber: [0, 1] },
|
||||
defaultValue: 1,
|
||||
numberOptions: { showSlider: true, minimum: 0, maximum: 1, step: 0.1 },
|
||||
}),
|
||||
manager.mappingEditor("Visibility", "visible", {
|
||||
defaultValue: true,
|
||||
}),
|
||||
]);
|
||||
|
||||
widgets = widgets.concat(parentWidgets);
|
||||
return widgets;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import { strings } from "../../../strings";
|
||||
import { Point, Color, rgbToHex } from "../../common";
|
||||
import * as Graphics from "../../graphics";
|
||||
import * as Specification from "../../specification";
|
||||
|
@ -297,46 +298,68 @@ export class SymbolElementClass extends EmphasizableMarkClass<
|
|||
): Controls.Widget[] {
|
||||
const parentWidgets = super.getAttributePanelWidgets(manager);
|
||||
let widgets = [
|
||||
manager.sectionHeader("Symbol"),
|
||||
manager.mappingEditor("Shape", "symbol", {
|
||||
acceptKinds: [Specification.DataKind.Categorical],
|
||||
hints: { rangeEnum: symbolTypes },
|
||||
defaultValue: "circle",
|
||||
}),
|
||||
manager.mappingEditor("Size", "size", {
|
||||
acceptKinds: [Specification.DataKind.Numerical],
|
||||
hints: { rangeNumber: [0, 200 * Math.PI] },
|
||||
defaultValue: 60,
|
||||
numberOptions: {
|
||||
showSlider: true,
|
||||
minimum: 0,
|
||||
sliderRange: [0, 3600],
|
||||
sliderFunction: "sqrt",
|
||||
manager.verticalGroup(
|
||||
{
|
||||
header: strings.objects.general,
|
||||
},
|
||||
}),
|
||||
manager.sectionHeader("Style"),
|
||||
manager.mappingEditor("Fill", "fill", {}),
|
||||
manager.mappingEditor("Stroke", "stroke", {}),
|
||||
[
|
||||
manager.mappingEditor(strings.objects.rect.shape, "symbol", {
|
||||
acceptKinds: [Specification.DataKind.Categorical],
|
||||
hints: { rangeEnum: symbolTypes },
|
||||
defaultValue: "circle",
|
||||
}),
|
||||
manager.mappingEditor(strings.objects.size, "size", {
|
||||
acceptKinds: [Specification.DataKind.Numerical],
|
||||
hints: { rangeNumber: [0, 200 * Math.PI] },
|
||||
defaultValue: 60,
|
||||
numberOptions: {
|
||||
showSlider: true,
|
||||
minimum: 0,
|
||||
sliderRange: [0, 3600],
|
||||
sliderFunction: "sqrt",
|
||||
},
|
||||
}),
|
||||
manager.mappingEditor(
|
||||
strings.objects.visibleOn.visibility,
|
||||
"visible",
|
||||
{
|
||||
defaultValue: true,
|
||||
}
|
||||
),
|
||||
]
|
||||
),
|
||||
manager.verticalGroup(
|
||||
{
|
||||
header: strings.objects.style,
|
||||
},
|
||||
[
|
||||
manager.mappingEditor(strings.objects.fill, "fill", {}),
|
||||
manager.mappingEditor(strings.objects.stroke, "stroke", {}),
|
||||
this.object.mappings.stroke != null
|
||||
? manager.mappingEditor(
|
||||
strings.objects.strokeWidth,
|
||||
"strokeWidth",
|
||||
{
|
||||
hints: { rangeNumber: [0, 5] },
|
||||
defaultValue: 1,
|
||||
numberOptions: {
|
||||
showSlider: true,
|
||||
sliderRange: [0, 5],
|
||||
minimum: 0,
|
||||
},
|
||||
}
|
||||
)
|
||||
: null,
|
||||
manager.mappingEditor(strings.objects.opacity, "opacity", {
|
||||
hints: { rangeNumber: [0, 1] },
|
||||
defaultValue: 1,
|
||||
numberOptions: { showSlider: true, minimum: 0, maximum: 1 },
|
||||
}),
|
||||
]
|
||||
),
|
||||
];
|
||||
if (this.object.mappings.stroke != null) {
|
||||
widgets.push(
|
||||
manager.mappingEditor("Line Width", "strokeWidth", {
|
||||
hints: { rangeNumber: [0, 5] },
|
||||
defaultValue: 1,
|
||||
numberOptions: { showSlider: true, sliderRange: [0, 5], minimum: 0 },
|
||||
})
|
||||
);
|
||||
}
|
||||
widgets = widgets.concat([
|
||||
manager.mappingEditor("Opacity", "opacity", {
|
||||
hints: { rangeNumber: [0, 1] },
|
||||
defaultValue: 1,
|
||||
numberOptions: { showSlider: true, minimum: 0, maximum: 1, step: 0.1 },
|
||||
}),
|
||||
manager.mappingEditor("Visibility", "visible", {
|
||||
defaultValue: true,
|
||||
}),
|
||||
]);
|
||||
widgets = widgets.concat([]);
|
||||
|
||||
return widgets.concat(parentWidgets);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
/* eslint-disable max-lines-per-function */
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import { defaultFont, defaultFontSize } from "../../../app/stores/defaults";
|
||||
import { strings } from "../../../strings";
|
||||
import {
|
||||
Point,
|
||||
replaceNewLineBySymbol,
|
||||
|
@ -291,80 +293,111 @@ export class TextElementClass extends EmphasizableMarkClass<
|
|||
const parentWidgets = super.getAttributePanelWidgets(manager);
|
||||
const props = this.object.properties;
|
||||
return [
|
||||
manager.mappingEditor("Text", "text", {}),
|
||||
manager.mappingEditor("Font", "fontFamily", {
|
||||
defaultValue: defaultFont,
|
||||
}),
|
||||
manager.mappingEditor("Size", "fontSize", {
|
||||
hints: { rangeNumber: [0, 36] },
|
||||
defaultValue: defaultFontSize,
|
||||
numberOptions: {
|
||||
showUpdown: true,
|
||||
updownStyle: "font",
|
||||
minimum: 0,
|
||||
updownTick: 2,
|
||||
manager.verticalGroup(
|
||||
{
|
||||
header: strings.objects.general,
|
||||
},
|
||||
}),
|
||||
manager.sectionHeader("Anchor & Rotation"),
|
||||
manager.inputSelect(
|
||||
{ property: "alignment", field: "x" },
|
||||
{
|
||||
type: "radio",
|
||||
icons: [
|
||||
"AlignHorizontalLeft",
|
||||
"AlignHorizontalCenter",
|
||||
"AlignHorizontalRight",
|
||||
],
|
||||
labels: ["Left", "Middle", "Right"],
|
||||
options: ["left", "middle", "right"],
|
||||
label: "Anchor X",
|
||||
}
|
||||
),
|
||||
props.alignment.x != "middle"
|
||||
? manager.inputNumber(
|
||||
{ property: "alignment", field: "xMargin" },
|
||||
{
|
||||
updownTick: 1,
|
||||
[
|
||||
manager.mappingEditor(strings.toolbar.text, "text", {}),
|
||||
manager.mappingEditor(strings.objects.font, "fontFamily", {
|
||||
defaultValue: defaultFont,
|
||||
}),
|
||||
manager.mappingEditor(strings.objects.size, "fontSize", {
|
||||
hints: { rangeNumber: [0, 36] },
|
||||
defaultValue: defaultFontSize,
|
||||
numberOptions: {
|
||||
showUpdown: true,
|
||||
label: "Margin",
|
||||
}
|
||||
)
|
||||
: null,
|
||||
manager.inputSelect(
|
||||
{ property: "alignment", field: "y" },
|
||||
{
|
||||
type: "radio",
|
||||
icons: [
|
||||
"AlignVerticalTop",
|
||||
"AlignVerticalCenter",
|
||||
"AlignVerticalBottom",
|
||||
],
|
||||
labels: ["Top", "Middle", "Bottom"],
|
||||
options: ["top", "middle", "bottom"],
|
||||
label: "Anchor Y",
|
||||
}
|
||||
),
|
||||
props.alignment.y != "middle"
|
||||
? manager.inputNumber(
|
||||
{ property: "alignment", field: "yMargin" },
|
||||
updownStyle: "font",
|
||||
minimum: 0,
|
||||
updownTick: 2,
|
||||
},
|
||||
}),
|
||||
manager.mappingEditor(
|
||||
strings.objects.visibleOn.visibility,
|
||||
"visible",
|
||||
{
|
||||
updownTick: 1,
|
||||
showUpdown: true,
|
||||
label: "Margin",
|
||||
defaultValue: true,
|
||||
}
|
||||
)
|
||||
: null,
|
||||
// manager.row("Rotation", manager.inputNumber({ property: "rotation" })),
|
||||
manager.sectionHeader("Style"),
|
||||
manager.mappingEditor("Color", "color", {}),
|
||||
manager.mappingEditor("Outline", "outline", {}),
|
||||
manager.mappingEditor("Opacity", "opacity", {
|
||||
hints: { rangeNumber: [0, 1] },
|
||||
numberOptions: { showSlider: true, minimum: 0, maximum: 1, step: 0.1 },
|
||||
}),
|
||||
manager.mappingEditor("Visibility", "visible", {
|
||||
defaultValue: true,
|
||||
}),
|
||||
),
|
||||
]
|
||||
),
|
||||
manager.verticalGroup(
|
||||
{
|
||||
header: strings.objects.anchorAndRotation,
|
||||
},
|
||||
[
|
||||
manager.inputSelect(
|
||||
{ property: "alignment", field: "x" },
|
||||
{
|
||||
type: "radio",
|
||||
icons: [
|
||||
"AlignHorizontalLeft",
|
||||
"AlignHorizontalCenter",
|
||||
"AlignHorizontalRight",
|
||||
],
|
||||
labels: ["Left", "Middle", "Right"],
|
||||
options: ["left", "middle", "right"],
|
||||
label: strings.objects.anchorX,
|
||||
}
|
||||
),
|
||||
props.alignment.x != "middle"
|
||||
? manager.inputNumber(
|
||||
{ property: "alignment", field: "xMargin" },
|
||||
{
|
||||
updownTick: 1,
|
||||
showUpdown: true,
|
||||
label: "Margin",
|
||||
}
|
||||
)
|
||||
: null,
|
||||
manager.inputSelect(
|
||||
{ property: "alignment", field: "y" },
|
||||
{
|
||||
type: "radio",
|
||||
icons: [
|
||||
"AlignVerticalTop",
|
||||
"AlignVerticalCenter",
|
||||
"AlignVerticalBottom",
|
||||
],
|
||||
labels: ["Top", "Middle", "Bottom"],
|
||||
options: ["top", "middle", "bottom"],
|
||||
label: strings.objects.anchorY,
|
||||
}
|
||||
),
|
||||
props.alignment.y != "middle"
|
||||
? manager.inputNumber(
|
||||
{ property: "alignment", field: "yMargin" },
|
||||
{
|
||||
updownTick: 1,
|
||||
showUpdown: true,
|
||||
label: strings.objects.text.margin,
|
||||
}
|
||||
)
|
||||
: null,
|
||||
manager.inputNumber(
|
||||
{ property: "rotation" },
|
||||
{
|
||||
label: strings.objects.rotation,
|
||||
showUpdown: true,
|
||||
updownTick: 1,
|
||||
}
|
||||
),
|
||||
]
|
||||
),
|
||||
manager.verticalGroup(
|
||||
{
|
||||
header: "Style",
|
||||
},
|
||||
[
|
||||
manager.mappingEditor(strings.objects.color, "color", {}),
|
||||
manager.mappingEditor(strings.objects.outline, "outline", {}),
|
||||
manager.mappingEditor(strings.objects.opacity, "opacity", {
|
||||
hints: { rangeNumber: [0, 1] },
|
||||
defaultValue: 1,
|
||||
numberOptions: { showSlider: true, minimum: 0, maximum: 1 },
|
||||
}),
|
||||
]
|
||||
),
|
||||
].concat(parentWidgets);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the MIT license.
|
||||
|
||||
import { defaultFont, defaultFontSize } from "../../../app/stores/defaults";
|
||||
import { strings } from "../../../strings";
|
||||
import {
|
||||
Point,
|
||||
replaceNewLineBySymbol,
|
||||
|
@ -109,36 +110,52 @@ export class TextboxElementClass extends EmphasizableMarkClass<
|
|||
const props = this.object.properties;
|
||||
const parentWidgets = super.getAttributePanelWidgets(manager);
|
||||
const widgets: Controls.Widget[] = [
|
||||
manager.sectionHeader("Size"),
|
||||
manager.mappingEditor("Width", "width", {
|
||||
hints: { autoRange: true, startWithZero: "always" },
|
||||
acceptKinds: [Specification.DataKind.Numerical],
|
||||
defaultAuto: true,
|
||||
}),
|
||||
manager.mappingEditor("Height", "height", {
|
||||
hints: { autoRange: true, startWithZero: "always" },
|
||||
acceptKinds: [Specification.DataKind.Numerical],
|
||||
defaultAuto: true,
|
||||
}),
|
||||
manager.sectionHeader("Text"),
|
||||
manager.mappingEditor("Text", "text", {}),
|
||||
manager.mappingEditor("Font", "fontFamily", {
|
||||
defaultValue: defaultFont,
|
||||
}),
|
||||
manager.mappingEditor("Size", "fontSize", {
|
||||
hints: { rangeNumber: [0, 36] },
|
||||
defaultValue: defaultFontSize,
|
||||
numberOptions: {
|
||||
showUpdown: true,
|
||||
updownStyle: "font",
|
||||
minimum: 0,
|
||||
updownTick: 2,
|
||||
manager.verticalGroup(
|
||||
{
|
||||
header: strings.objects.general,
|
||||
},
|
||||
}),
|
||||
manager.row(
|
||||
"Align X",
|
||||
manager.horizontal(
|
||||
[0, 1],
|
||||
[
|
||||
manager.mappingEditor("Width", "width", {
|
||||
hints: { autoRange: true, startWithZero: "always" },
|
||||
acceptKinds: [Specification.DataKind.Numerical],
|
||||
defaultAuto: true,
|
||||
}),
|
||||
manager.mappingEditor("Height", "height", {
|
||||
hints: { autoRange: true, startWithZero: "always" },
|
||||
acceptKinds: [Specification.DataKind.Numerical],
|
||||
defaultAuto: true,
|
||||
}),
|
||||
manager.mappingEditor("Visibility", "visible", {
|
||||
defaultValue: true,
|
||||
}),
|
||||
]
|
||||
),
|
||||
manager.verticalGroup(
|
||||
{
|
||||
header: strings.toolbar.text,
|
||||
},
|
||||
[
|
||||
manager.mappingEditor("Text", "text", {}),
|
||||
manager.mappingEditor("Font", "fontFamily", {
|
||||
defaultValue: defaultFont,
|
||||
}),
|
||||
manager.mappingEditor("Size", "fontSize", {
|
||||
hints: { rangeNumber: [0, 36] },
|
||||
defaultValue: defaultFontSize,
|
||||
numberOptions: {
|
||||
showUpdown: true,
|
||||
updownStyle: "font",
|
||||
minimum: 0,
|
||||
updownTick: 2,
|
||||
},
|
||||
}),
|
||||
]
|
||||
),
|
||||
manager.verticalGroup(
|
||||
{
|
||||
header: strings.objects.layout,
|
||||
},
|
||||
[
|
||||
manager.inputSelect(
|
||||
{ property: "alignX" },
|
||||
{
|
||||
|
@ -150,6 +167,7 @@ export class TextboxElementClass extends EmphasizableMarkClass<
|
|||
"AlignHorizontalRight",
|
||||
],
|
||||
labels: ["Left", "Middle", "Right"],
|
||||
label: strings.objects.alignX,
|
||||
}
|
||||
),
|
||||
props.alignX != "middle"
|
||||
|
@ -161,16 +179,11 @@ export class TextboxElementClass extends EmphasizableMarkClass<
|
|||
{
|
||||
updownTick: 1,
|
||||
showUpdown: true,
|
||||
label: strings.objects.text.margin,
|
||||
}
|
||||
)
|
||||
)
|
||||
: null
|
||||
)
|
||||
),
|
||||
manager.row(
|
||||
"Align Y",
|
||||
manager.horizontal(
|
||||
[0, 1],
|
||||
: null,
|
||||
manager.inputSelect(
|
||||
{ property: "alignY" },
|
||||
{
|
||||
|
@ -182,6 +195,7 @@ export class TextboxElementClass extends EmphasizableMarkClass<
|
|||
"AlignVerticalTop",
|
||||
],
|
||||
labels: ["Bottom", "Middle", "Top"],
|
||||
label: strings.objects.alignX,
|
||||
}
|
||||
),
|
||||
props.alignY != "middle"
|
||||
|
@ -193,65 +207,68 @@ export class TextboxElementClass extends EmphasizableMarkClass<
|
|||
{
|
||||
updownTick: 1,
|
||||
showUpdown: true,
|
||||
label: strings.objects.text.margin,
|
||||
}
|
||||
)
|
||||
)
|
||||
: null
|
||||
)
|
||||
),
|
||||
manager.sectionHeader("Layout"),
|
||||
manager.row(
|
||||
"Wrap text",
|
||||
manager.inputBoolean(
|
||||
{ property: "wordWrap" },
|
||||
{
|
||||
type: "checkbox",
|
||||
}
|
||||
)
|
||||
),
|
||||
props.wordWrap
|
||||
? manager.row(
|
||||
"Alignment",
|
||||
manager.horizontal(
|
||||
[0, 1],
|
||||
manager.inputSelect(
|
||||
{ property: "alignText" },
|
||||
{
|
||||
type: "radio",
|
||||
options: ["end", "middle", "start"],
|
||||
icons: [
|
||||
"AlignVerticalBottom",
|
||||
"AlignVerticalCenter",
|
||||
"AlignVerticalTop",
|
||||
],
|
||||
labels: ["Bottom", "Middle", "Top"],
|
||||
}
|
||||
)
|
||||
)
|
||||
)
|
||||
: null,
|
||||
props.wordWrap
|
||||
? manager.row(
|
||||
"Overflow",
|
||||
: null,
|
||||
manager.row(
|
||||
"Wrap text",
|
||||
manager.inputBoolean(
|
||||
{ property: "overFlow" },
|
||||
{ property: "wordWrap" },
|
||||
{
|
||||
type: "checkbox",
|
||||
}
|
||||
)
|
||||
)
|
||||
: null,
|
||||
manager.sectionHeader("Style"),
|
||||
manager.mappingEditor("Color", "color", {}),
|
||||
manager.mappingEditor("Outline", "outline", {}),
|
||||
manager.mappingEditor("Opacity", "opacity", {
|
||||
hints: { rangeNumber: [0, 1] },
|
||||
defaultValue: 1,
|
||||
numberOptions: { showSlider: true, minimum: 0, maximum: 1, step: 0.1 },
|
||||
}),
|
||||
manager.mappingEditor("Visibility", "visible", {
|
||||
defaultValue: true,
|
||||
}),
|
||||
),
|
||||
props.wordWrap
|
||||
? manager.row(
|
||||
"Alignment",
|
||||
manager.horizontal(
|
||||
[0, 1],
|
||||
manager.inputSelect(
|
||||
{ property: "alignText" },
|
||||
{
|
||||
type: "radio",
|
||||
options: ["end", "middle", "start"],
|
||||
icons: [
|
||||
"AlignVerticalBottom",
|
||||
"AlignVerticalCenter",
|
||||
"AlignVerticalTop",
|
||||
],
|
||||
labels: ["Bottom", "Middle", "Top"],
|
||||
}
|
||||
)
|
||||
)
|
||||
)
|
||||
: null,
|
||||
props.wordWrap
|
||||
? manager.row(
|
||||
"Overflow",
|
||||
manager.inputBoolean(
|
||||
{ property: "overFlow" },
|
||||
{
|
||||
type: "checkbox",
|
||||
}
|
||||
)
|
||||
)
|
||||
: null,
|
||||
]
|
||||
),
|
||||
manager.verticalGroup(
|
||||
{
|
||||
header: strings.objects.style,
|
||||
},
|
||||
[
|
||||
manager.mappingEditor("Color", "color", {}),
|
||||
manager.mappingEditor("Outline", "outline", {}),
|
||||
manager.mappingEditor("Opacity", "opacity", {
|
||||
hints: { rangeNumber: [0, 1] },
|
||||
defaultValue: 1,
|
||||
numberOptions: { showSlider: true, minimum: 0, maximum: 1 },
|
||||
}),
|
||||
]
|
||||
),
|
||||
];
|
||||
return widgets.concat(parentWidgets);
|
||||
}
|
||||
|
|
|
@ -92,27 +92,33 @@ export abstract class ObjectClass<
|
|||
manager: Controls.WidgetManager
|
||||
): Controls.Widget[] {
|
||||
return [
|
||||
manager.sectionHeader("Interactivity"),
|
||||
manager.inputBoolean(
|
||||
{ property: "enableTooltips" },
|
||||
manager.verticalGroup(
|
||||
{
|
||||
type: "checkbox",
|
||||
label: "Tooltips",
|
||||
}
|
||||
),
|
||||
manager.inputBoolean(
|
||||
{ property: "enableContextMenu" },
|
||||
{
|
||||
type: "checkbox",
|
||||
label: "Context menu",
|
||||
}
|
||||
),
|
||||
manager.inputBoolean(
|
||||
{ property: "enableSelection" },
|
||||
{
|
||||
type: "checkbox",
|
||||
label: "Selection",
|
||||
}
|
||||
header: "Interactivity",
|
||||
},
|
||||
[
|
||||
manager.inputBoolean(
|
||||
{ property: "enableTooltips" },
|
||||
{
|
||||
type: "checkbox",
|
||||
label: "Tooltips",
|
||||
}
|
||||
),
|
||||
manager.inputBoolean(
|
||||
{ property: "enableContextMenu" },
|
||||
{
|
||||
type: "checkbox",
|
||||
label: "Context menu",
|
||||
}
|
||||
),
|
||||
manager.inputBoolean(
|
||||
{ property: "enableSelection" },
|
||||
{
|
||||
type: "checkbox",
|
||||
label: "Selection",
|
||||
}
|
||||
),
|
||||
]
|
||||
),
|
||||
];
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* eslint-disable max-lines-per-function */
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
|
@ -960,85 +961,105 @@ export function getNumericalInterpolate(
|
|||
export function buildAxisAppearanceWidgets(
|
||||
isVisible: boolean,
|
||||
axisProperty: string,
|
||||
m: Controls.WidgetManager
|
||||
manager: Controls.WidgetManager
|
||||
) {
|
||||
if (isVisible) {
|
||||
return [
|
||||
m.vertical(
|
||||
m.inputBoolean(
|
||||
{ property: axisProperty, field: "visible" },
|
||||
{ type: "checkbox", label: "Visible", headerLabel: "Appearance" }
|
||||
),
|
||||
m.inputSelect(
|
||||
{ property: axisProperty, field: "side" },
|
||||
manager.vertical(
|
||||
manager.verticalGroup(
|
||||
{
|
||||
type: "dropdown",
|
||||
showLabel: true,
|
||||
label: "Position:",
|
||||
options: ["default", "opposite"],
|
||||
labels: ["Default", "Opposite"],
|
||||
}
|
||||
),
|
||||
m.sectionHeader("Axis Style"),
|
||||
m.inputColor(
|
||||
{
|
||||
property: axisProperty,
|
||||
field: ["style", "lineColor"],
|
||||
header: strings.objects.appearance,
|
||||
},
|
||||
{
|
||||
label: "Line Color",
|
||||
}
|
||||
[
|
||||
manager.inputBoolean(
|
||||
{ property: axisProperty, field: "visible" },
|
||||
{ type: "checkbox", label: "Visible", headerLabel: "Appearance" }
|
||||
),
|
||||
manager.inputSelect(
|
||||
{ property: axisProperty, field: "side" },
|
||||
{
|
||||
type: "dropdown",
|
||||
showLabel: true,
|
||||
label: "Position:",
|
||||
options: ["default", "opposite"],
|
||||
labels: ["Default", "Opposite"],
|
||||
}
|
||||
),
|
||||
]
|
||||
),
|
||||
m.inputColor(
|
||||
manager.verticalGroup(
|
||||
{
|
||||
property: axisProperty,
|
||||
field: ["style", "tickColor"],
|
||||
header: strings.objects.style,
|
||||
},
|
||||
{
|
||||
label: "Tick Color",
|
||||
}
|
||||
),
|
||||
m.inputNumber(
|
||||
{
|
||||
property: axisProperty,
|
||||
field: ["style", "tickSize"],
|
||||
},
|
||||
{
|
||||
label: "Tick Size",
|
||||
}
|
||||
),
|
||||
m.inputFontFamily(
|
||||
{
|
||||
property: axisProperty,
|
||||
field: ["style", "fontFamily"],
|
||||
},
|
||||
{
|
||||
label: "Font Family",
|
||||
}
|
||||
),
|
||||
m.inputNumber(
|
||||
{ property: axisProperty, field: ["style", "fontSize"] },
|
||||
{
|
||||
showUpdown: true,
|
||||
updownStyle: "font",
|
||||
updownTick: 2,
|
||||
label: "Font Size",
|
||||
}
|
||||
),
|
||||
m.inputBoolean(
|
||||
{ property: axisProperty, field: ["style", "wordWrap"] },
|
||||
{
|
||||
type: "checkbox",
|
||||
headerLabel: "Text displaying",
|
||||
label: "Wrap text",
|
||||
}
|
||||
[
|
||||
manager.inputColor(
|
||||
{
|
||||
property: axisProperty,
|
||||
field: ["style", "lineColor"],
|
||||
},
|
||||
{
|
||||
label: "Line Color",
|
||||
}
|
||||
),
|
||||
manager.inputColor(
|
||||
{
|
||||
property: axisProperty,
|
||||
field: ["style", "tickColor"],
|
||||
},
|
||||
{
|
||||
label: "Tick Color",
|
||||
}
|
||||
),
|
||||
manager.inputNumber(
|
||||
{
|
||||
property: axisProperty,
|
||||
field: ["style", "tickSize"],
|
||||
},
|
||||
{
|
||||
label: "Tick Size",
|
||||
}
|
||||
),
|
||||
manager.inputFontFamily(
|
||||
{
|
||||
property: axisProperty,
|
||||
field: ["style", "fontFamily"],
|
||||
},
|
||||
{
|
||||
label: "Font Family",
|
||||
}
|
||||
),
|
||||
manager.inputNumber(
|
||||
{ property: axisProperty, field: ["style", "fontSize"] },
|
||||
{
|
||||
showUpdown: true,
|
||||
updownStyle: "font",
|
||||
updownTick: 2,
|
||||
label: "Font Size",
|
||||
}
|
||||
),
|
||||
manager.inputBoolean(
|
||||
{ property: axisProperty, field: ["style", "wordWrap"] },
|
||||
{
|
||||
type: "checkbox",
|
||||
headerLabel: "Text displaying",
|
||||
label: "Wrap text",
|
||||
}
|
||||
),
|
||||
]
|
||||
)
|
||||
),
|
||||
];
|
||||
} else {
|
||||
return m.inputBoolean(
|
||||
{ property: axisProperty, field: "visible" },
|
||||
{ type: "checkbox", label: "Visible", headerLabel: "Appearance" }
|
||||
return manager.verticalGroup(
|
||||
{
|
||||
header: strings.objects.appearance,
|
||||
},
|
||||
[
|
||||
manager.inputBoolean(
|
||||
{ property: axisProperty, field: "visible" },
|
||||
{ type: "checkbox", label: "Visible", headerLabel: "Appearance" }
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1047,7 +1068,7 @@ export function buildAxisAppearanceWidgets(
|
|||
export function buildAxisWidgets(
|
||||
data: Specification.Types.AxisDataBinding,
|
||||
axisProperty: string,
|
||||
m: Controls.WidgetManager,
|
||||
manager: Controls.WidgetManager,
|
||||
axisName: string
|
||||
): Controls.Widget[] {
|
||||
const widgets = [];
|
||||
|
@ -1059,99 +1080,93 @@ export function buildAxisWidgets(
|
|||
},
|
||||
};
|
||||
const makeAppearance = () => {
|
||||
return buildAxisAppearanceWidgets(data.visible, axisProperty, m);
|
||||
return buildAxisAppearanceWidgets(data.visible, axisProperty, manager);
|
||||
};
|
||||
if (data != null) {
|
||||
switch (data.type) {
|
||||
case "numerical":
|
||||
{
|
||||
widgets.push(
|
||||
m.sectionHeader(
|
||||
axisName + ": Numerical",
|
||||
m.clearButton({ property: axisProperty }, null, true),
|
||||
dropzoneOptions
|
||||
)
|
||||
);
|
||||
if (axisName != "Data Axis") {
|
||||
widgets.push(
|
||||
m.inputExpression(
|
||||
{
|
||||
property: axisProperty,
|
||||
field: "expression",
|
||||
},
|
||||
{
|
||||
label: "Data",
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
if (data.valueType === "date") {
|
||||
widgets.push(m.label("Range"));
|
||||
widgets.push(
|
||||
m.inputDate(
|
||||
{ property: axisProperty, field: "domainMin" },
|
||||
{ label: "Start" }
|
||||
)
|
||||
);
|
||||
widgets.push(
|
||||
m.inputDate(
|
||||
{ property: axisProperty, field: "domainMax" },
|
||||
{ label: "End" }
|
||||
)
|
||||
);
|
||||
} else {
|
||||
widgets.push(
|
||||
m.vertical(
|
||||
m.label("Range"),
|
||||
m.horizontal(
|
||||
[1, 0, 1],
|
||||
m.inputNumber({ property: axisProperty, field: "domainMin" }),
|
||||
m.label(" - ", {
|
||||
addMargins: true,
|
||||
}),
|
||||
m.inputNumber({ property: axisProperty, field: "domainMax" })
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
if (data.numericalMode != "temporal") {
|
||||
widgets.push(
|
||||
m.inputSelect(
|
||||
{ property: axisProperty, field: "numericalMode" },
|
||||
{
|
||||
options: ["linear", "logarithmic"],
|
||||
labels: ["Linear", "Logarithmic"],
|
||||
showLabel: true,
|
||||
type: "dropdown",
|
||||
label: "Mode",
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
widgets.push(
|
||||
m.inputExpression(
|
||||
manager.verticalGroup(
|
||||
{
|
||||
property: axisProperty,
|
||||
field: "tickDataExpression",
|
||||
header: axisName + strings.objects.axes.numericalSuffix,
|
||||
},
|
||||
{
|
||||
label: "Tick Data",
|
||||
}
|
||||
)
|
||||
);
|
||||
widgets.push(
|
||||
m.inputFormat(
|
||||
{
|
||||
property: axisProperty,
|
||||
field: "tickFormat",
|
||||
},
|
||||
{
|
||||
blank: strings.core.auto,
|
||||
isDateField:
|
||||
data.numericalMode === NumericalMode.Temporal ||
|
||||
data.valueType === DataType.Date,
|
||||
label: "Tick Format",
|
||||
}
|
||||
[
|
||||
manager.sectionHeader(
|
||||
axisName + strings.objects.axes.numericalSuffix,
|
||||
manager.clearButton({ property: axisProperty }, null, true),
|
||||
dropzoneOptions
|
||||
),
|
||||
manager.inputExpression(
|
||||
{
|
||||
property: axisProperty,
|
||||
field: "expression",
|
||||
},
|
||||
{
|
||||
label: "Data",
|
||||
}
|
||||
),
|
||||
data.valueType === "date" ? manager.label("Range") : null,
|
||||
data.valueType === "date"
|
||||
? manager.inputDate(
|
||||
{ property: axisProperty, field: "domainMin" },
|
||||
{ label: "Start" }
|
||||
)
|
||||
: null,
|
||||
data.valueType === "date"
|
||||
? manager.inputDate(
|
||||
{ property: axisProperty, field: "domainMax" },
|
||||
{ label: "End" }
|
||||
)
|
||||
: null,
|
||||
data.valueType !== "date" ? manager.label("Range") : null,
|
||||
data.valueType !== "date"
|
||||
? manager.inputNumber(
|
||||
{ property: axisProperty, field: "domainMin" },
|
||||
{ label: strings.objects.axes.from }
|
||||
)
|
||||
: null,
|
||||
data.valueType !== "date"
|
||||
? manager.inputNumber(
|
||||
{ property: axisProperty, field: "domainMax" },
|
||||
{ label: strings.objects.axes.to }
|
||||
)
|
||||
: null,
|
||||
data.numericalMode != "temporal"
|
||||
? manager.inputSelect(
|
||||
{ property: axisProperty, field: "numericalMode" },
|
||||
{
|
||||
options: ["linear", "logarithmic"],
|
||||
labels: ["Linear", "Logarithmic"],
|
||||
showLabel: true,
|
||||
type: "dropdown",
|
||||
label: "Mode",
|
||||
}
|
||||
)
|
||||
: null,
|
||||
manager.inputExpression(
|
||||
{
|
||||
property: axisProperty,
|
||||
field: "tickDataExpression",
|
||||
},
|
||||
{
|
||||
label: "Tick Data",
|
||||
}
|
||||
),
|
||||
manager.inputFormat(
|
||||
{
|
||||
property: axisProperty,
|
||||
field: "tickFormat",
|
||||
},
|
||||
{
|
||||
blank: strings.core.auto,
|
||||
isDateField:
|
||||
data.numericalMode === NumericalMode.Temporal ||
|
||||
data.valueType === DataType.Date,
|
||||
label: strings.objects.axes.tickFormat,
|
||||
}
|
||||
),
|
||||
]
|
||||
)
|
||||
);
|
||||
widgets.push(makeAppearance());
|
||||
|
@ -1160,66 +1175,67 @@ export function buildAxisWidgets(
|
|||
case "categorical":
|
||||
{
|
||||
widgets.push(
|
||||
m.sectionHeader(
|
||||
axisName + ": Categorical",
|
||||
m.clearButton({ property: axisProperty }, null, true),
|
||||
dropzoneOptions
|
||||
)
|
||||
);
|
||||
widgets.push(
|
||||
m.vertical(
|
||||
m.label("Data"),
|
||||
m.horizontal(
|
||||
[1, 0],
|
||||
m.inputExpression({
|
||||
property: axisProperty,
|
||||
field: "expression",
|
||||
}),
|
||||
m.reorderWidget(
|
||||
{ property: axisProperty, field: "categories" },
|
||||
{ allowReset: true }
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
if (data.valueType === "date") {
|
||||
widgets.push(
|
||||
m.inputExpression(
|
||||
{
|
||||
property: axisProperty,
|
||||
field: "tickDataExpression",
|
||||
},
|
||||
{
|
||||
label: "Tick Data",
|
||||
}
|
||||
)
|
||||
);
|
||||
widgets.push(
|
||||
m.inputFormat(
|
||||
{
|
||||
property: axisProperty,
|
||||
field: "tickFormat",
|
||||
},
|
||||
{
|
||||
blank: strings.core.auto,
|
||||
isDateField:
|
||||
data.numericalMode === NumericalMode.Temporal ||
|
||||
data.valueType === DataType.Date,
|
||||
label: "Tick Format",
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
widgets.push(
|
||||
m.inputNumber(
|
||||
{ property: axisProperty, field: "gapRatio" },
|
||||
manager.verticalGroup(
|
||||
{
|
||||
minimum: 0,
|
||||
maximum: 1,
|
||||
percentage: true,
|
||||
showSlider: true,
|
||||
label: "Gap",
|
||||
}
|
||||
header: axisName + ": Categorical",
|
||||
},
|
||||
[
|
||||
manager.sectionHeader(
|
||||
"Data",
|
||||
manager.clearButton({ property: axisProperty }, null, true),
|
||||
dropzoneOptions
|
||||
),
|
||||
manager.vertical(
|
||||
manager.label("Data"),
|
||||
manager.horizontal(
|
||||
[1, 0],
|
||||
manager.inputExpression({
|
||||
property: axisProperty,
|
||||
field: "expression",
|
||||
}),
|
||||
manager.reorderWidget(
|
||||
{ property: axisProperty, field: "categories" },
|
||||
{ allowReset: true }
|
||||
)
|
||||
),
|
||||
manager.inputNumber(
|
||||
{ property: axisProperty, field: "gapRatio" },
|
||||
{
|
||||
minimum: 0,
|
||||
maximum: 1,
|
||||
percentage: true,
|
||||
showSlider: true,
|
||||
label: "Gap",
|
||||
}
|
||||
),
|
||||
data.valueType === "date"
|
||||
? (manager.inputExpression(
|
||||
{
|
||||
property: axisProperty,
|
||||
field: "tickDataExpression",
|
||||
},
|
||||
{
|
||||
label: "Tick Data",
|
||||
}
|
||||
),
|
||||
manager.row(
|
||||
"Tick Format",
|
||||
manager.inputFormat(
|
||||
{
|
||||
property: axisProperty,
|
||||
field: "tickFormat",
|
||||
},
|
||||
{
|
||||
blank: strings.core.auto,
|
||||
isDateField:
|
||||
data.numericalMode === NumericalMode.Temporal ||
|
||||
data.valueType === DataType.Date,
|
||||
}
|
||||
)
|
||||
))
|
||||
: null
|
||||
),
|
||||
]
|
||||
)
|
||||
);
|
||||
widgets.push(makeAppearance());
|
||||
|
@ -1228,57 +1244,64 @@ export function buildAxisWidgets(
|
|||
case "default":
|
||||
{
|
||||
widgets.push(
|
||||
m.sectionHeader(
|
||||
axisName + ": Stacking",
|
||||
m.clearButton({ property: axisProperty }, null, true),
|
||||
dropzoneOptions
|
||||
)
|
||||
);
|
||||
widgets.push(
|
||||
m.inputNumber(
|
||||
{ property: axisProperty, field: "gapRatio" },
|
||||
manager.verticalGroup(
|
||||
{
|
||||
minimum: 0,
|
||||
maximum: 1,
|
||||
percentage: true,
|
||||
showSlider: true,
|
||||
label: "Gap",
|
||||
}
|
||||
header: axisName + ": Stacking",
|
||||
},
|
||||
[
|
||||
manager.sectionHeader(
|
||||
axisName + ": Stacking",
|
||||
manager.clearButton({ property: axisProperty }, null, true),
|
||||
dropzoneOptions
|
||||
),
|
||||
manager.inputNumber(
|
||||
{ property: axisProperty, field: "gapRatio" },
|
||||
{
|
||||
minimum: 0,
|
||||
maximum: 1,
|
||||
percentage: true,
|
||||
showSlider: true,
|
||||
label: "Gap",
|
||||
}
|
||||
),
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
widgets.push(
|
||||
m.sectionHeader(axisName + strings.objects.dataAxis.exportProperties)
|
||||
);
|
||||
widgets.push(
|
||||
m.inputBoolean(
|
||||
manager.verticalGroup(
|
||||
{
|
||||
property: axisProperty,
|
||||
field: "autoDomainMin",
|
||||
header: axisName + strings.objects.dataAxis.exportProperties,
|
||||
},
|
||||
{
|
||||
type: "checkbox",
|
||||
label: strings.objects.dataAxis.autoMin,
|
||||
}
|
||||
)
|
||||
);
|
||||
widgets.push(
|
||||
m.inputBoolean(
|
||||
{
|
||||
property: axisProperty,
|
||||
field: "autoDomainMax",
|
||||
},
|
||||
{
|
||||
type: "checkbox",
|
||||
label: strings.objects.dataAxis.autoMax,
|
||||
}
|
||||
[
|
||||
manager.inputBoolean(
|
||||
{
|
||||
property: axisProperty,
|
||||
field: "autoDomainMin",
|
||||
},
|
||||
{
|
||||
type: "checkbox",
|
||||
label: strings.objects.dataAxis.autoMin,
|
||||
}
|
||||
),
|
||||
manager.inputBoolean(
|
||||
{
|
||||
property: axisProperty,
|
||||
field: "autoDomainMax",
|
||||
},
|
||||
{
|
||||
type: "checkbox",
|
||||
label: strings.objects.dataAxis.autoMax,
|
||||
}
|
||||
),
|
||||
]
|
||||
)
|
||||
);
|
||||
} else {
|
||||
widgets.push(
|
||||
m.sectionHeader(
|
||||
manager.sectionHeader(
|
||||
axisName + ": " + strings.core.none,
|
||||
null,
|
||||
dropzoneOptions
|
||||
|
|
|
@ -15,6 +15,7 @@ import {
|
|||
import { AxisRenderer } from "./axis";
|
||||
import { utcFormat } from "d3-time-format";
|
||||
import { NumericalMode } from "../../specification/types";
|
||||
import { strings } from "../../../strings";
|
||||
|
||||
export abstract class PlotSegmentClass<
|
||||
PropertiesType extends Specification.AttributeMap = Specification.AttributeMap,
|
||||
|
@ -98,49 +99,49 @@ export abstract class PlotSegmentClass<
|
|||
return [];
|
||||
}
|
||||
return [
|
||||
manager.sectionHeader("Gridline"),
|
||||
manager.horizontal(
|
||||
[1, 1],
|
||||
manager.inputSelect(
|
||||
{ property: axisProperty, field: ["style", "gridlineStyle"] },
|
||||
{
|
||||
type: "dropdown",
|
||||
showLabel: true,
|
||||
icons: [
|
||||
"ChromeClose",
|
||||
"stroke/solid",
|
||||
"stroke/dashed",
|
||||
"stroke/dotted",
|
||||
],
|
||||
options: ["none", "solid", "dashed", "dotted"],
|
||||
labels: ["None", "Solid", "Dashed", "Dotted"],
|
||||
label: "Style",
|
||||
}
|
||||
)
|
||||
),
|
||||
manager.horizontal(
|
||||
[1, 1],
|
||||
manager.inputColor(
|
||||
{
|
||||
property: axisProperty,
|
||||
field: ["style", "gridlineColor"],
|
||||
},
|
||||
{
|
||||
label: "Color",
|
||||
}
|
||||
)
|
||||
),
|
||||
manager.inputNumber(
|
||||
manager.verticalGroup(
|
||||
{
|
||||
property: axisProperty,
|
||||
field: ["style", "gridlineWidth"],
|
||||
header: strings.objects.plotSegment.gridline,
|
||||
},
|
||||
{
|
||||
minimum: 0,
|
||||
maximum: 100,
|
||||
showUpdown: true,
|
||||
label: "Width",
|
||||
}
|
||||
[
|
||||
manager.inputSelect(
|
||||
{ property: axisProperty, field: ["style", "gridlineStyle"] },
|
||||
{
|
||||
type: "dropdown",
|
||||
showLabel: true,
|
||||
icons: [
|
||||
"ChromeClose",
|
||||
"stroke/solid",
|
||||
"stroke/dashed",
|
||||
"stroke/dotted",
|
||||
],
|
||||
options: ["none", "solid", "dashed", "dotted"],
|
||||
labels: ["None", "Solid", "Dashed", "Dotted"],
|
||||
label: strings.objects.style,
|
||||
}
|
||||
),
|
||||
manager.inputColor(
|
||||
{
|
||||
property: axisProperty,
|
||||
field: ["style", "gridlineColor"],
|
||||
},
|
||||
{
|
||||
label: strings.objects.color,
|
||||
}
|
||||
),
|
||||
manager.inputNumber(
|
||||
{
|
||||
property: axisProperty,
|
||||
field: ["style", "gridlineWidth"],
|
||||
},
|
||||
{
|
||||
minimum: 0,
|
||||
maximum: 100,
|
||||
showUpdown: true,
|
||||
label: strings.objects.width,
|
||||
}
|
||||
),
|
||||
]
|
||||
),
|
||||
];
|
||||
}
|
||||
|
|
|
@ -2605,18 +2605,24 @@ export class Region2DConstraintBuilder {
|
|||
}
|
||||
const options = this.applicableSublayoutOptions();
|
||||
return [
|
||||
m.sectionHeader("Sub-layout"),
|
||||
m.inputSelect(
|
||||
{ property: "sublayout", field: "type" },
|
||||
m.verticalGroup(
|
||||
{
|
||||
type: "radio",
|
||||
options: options.map((x) => x.value),
|
||||
icons: options.map((x) => x.icon),
|
||||
labels: options.map((x) => x.label),
|
||||
label: "Type",
|
||||
}
|
||||
header: strings.objects.plotSegment.subLayout,
|
||||
},
|
||||
[
|
||||
m.inputSelect(
|
||||
{ property: "sublayout", field: "type" },
|
||||
{
|
||||
type: "radio",
|
||||
options: options.map((x) => x.value),
|
||||
icons: options.map((x) => x.icon),
|
||||
labels: options.map((x) => x.label),
|
||||
label: strings.objects.plotSegment.type,
|
||||
}
|
||||
),
|
||||
...extra,
|
||||
]
|
||||
),
|
||||
...extra,
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
@ -582,22 +582,22 @@ export class CurvePlotSegment extends PlotSegmentClass<
|
|||
const builder = this.createBuilder();
|
||||
return [
|
||||
...super.getAttributePanelWidgets(manager),
|
||||
manager.sectionHeader("Curve Coordinates"),
|
||||
manager.vertical(
|
||||
manager.label("Normal"),
|
||||
manager.horizontal(
|
||||
[1, 0, 1],
|
||||
manager.inputNumber({ property: "normalStart" }),
|
||||
manager.label("-"),
|
||||
manager.inputNumber({ property: "normalEnd" })
|
||||
)
|
||||
manager.verticalGroup(
|
||||
{
|
||||
header: strings.objects.plotSegment.curveCoordinates,
|
||||
},
|
||||
[
|
||||
manager.vertical(
|
||||
manager.label(strings.objects.plotSegment.normal),
|
||||
manager.horizontal(
|
||||
[1, 0, 1],
|
||||
manager.inputNumber({ property: "normalStart" }),
|
||||
manager.label("-"),
|
||||
manager.inputNumber({ property: "normalEnd" })
|
||||
)
|
||||
),
|
||||
]
|
||||
),
|
||||
// manager.row("Radius", manager.horizontal([0, 1, 0, 1],
|
||||
// manager.label("Inner:"),
|
||||
// manager.inputNumber({ property: "innerRatio" }),
|
||||
// manager.label("Outer:"),
|
||||
// manager.inputNumber({ property: "outerRatio" })
|
||||
// )),
|
||||
...builder.buildPanelWidgets(manager),
|
||||
];
|
||||
}
|
||||
|
|
|
@ -773,33 +773,39 @@ export class PolarPlotSegment extends PlotSegmentClass<
|
|||
const builder = this.createBuilder();
|
||||
return [
|
||||
...super.getAttributePanelWidgets(manager),
|
||||
manager.sectionHeader("Polar Coordinates"),
|
||||
manager.vertical(
|
||||
manager.label("Angle"),
|
||||
manager.horizontal(
|
||||
[1, 0, 1],
|
||||
manager.inputNumber({ property: "startAngle" }),
|
||||
manager.label("-"),
|
||||
manager.inputNumber({ property: "endAngle" })
|
||||
)
|
||||
),
|
||||
manager.vertical(
|
||||
manager.label("Radius"),
|
||||
manager.horizontal(
|
||||
[0, 1, 0, 1],
|
||||
manager.label("Inner:"),
|
||||
manager.inputNumber({ property: "innerRatio" }),
|
||||
manager.label("Outer:"),
|
||||
manager.inputNumber({ property: "outerRatio" })
|
||||
)
|
||||
),
|
||||
manager.inputBoolean(
|
||||
{ property: "equalizeArea" },
|
||||
manager.verticalGroup(
|
||||
{
|
||||
type: "checkbox",
|
||||
label: "Height to Area",
|
||||
headerLabel: "Equalize area",
|
||||
}
|
||||
header: strings.objects.plotSegment.polarCoordinates,
|
||||
},
|
||||
[
|
||||
manager.vertical(
|
||||
manager.label(strings.objects.plotSegment.angle),
|
||||
manager.horizontal(
|
||||
[1, 0, 1],
|
||||
manager.inputNumber({ property: "startAngle" }),
|
||||
manager.label("-"),
|
||||
manager.inputNumber({ property: "endAngle" })
|
||||
)
|
||||
),
|
||||
manager.vertical(
|
||||
manager.label(strings.objects.plotSegment.radius),
|
||||
manager.horizontal(
|
||||
[0, 1, 0, 1],
|
||||
manager.label(strings.objects.plotSegment.inner),
|
||||
manager.inputNumber({ property: "innerRatio" }),
|
||||
manager.label(strings.objects.plotSegment.outer),
|
||||
manager.inputNumber({ property: "outerRatio" })
|
||||
)
|
||||
),
|
||||
manager.inputBoolean(
|
||||
{ property: "equalizeArea" },
|
||||
{
|
||||
type: "checkbox",
|
||||
label: strings.objects.plotSegment.heightToArea,
|
||||
headerLabel: strings.objects.plotSegment.equalizeArea,
|
||||
}
|
||||
),
|
||||
]
|
||||
),
|
||||
...builder.buildPanelWidgets(manager),
|
||||
];
|
||||
|
|
|
@ -2462,7 +2462,7 @@ export function initializeIcons(
|
|||
"sublayout/jitter": (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 32 32"
|
||||
viewBox="0 0 16 16"
|
||||
width="16"
|
||||
height="16"
|
||||
style={{
|
||||
|
@ -2483,6 +2483,123 @@ export function initializeIcons(
|
|||
/>
|
||||
</svg>
|
||||
),
|
||||
"sublayout/polar-grid": (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 16 16"
|
||||
width="16"
|
||||
height="16"
|
||||
style={{
|
||||
fill: "#0078d4",
|
||||
strokeWidth: 0.1,
|
||||
}}
|
||||
>
|
||||
<g>
|
||||
<path
|
||||
d="M10.766,1.558c0.242,0.038,0.483,0.082,0.723,0.13C11.249,1.64,11.008,1.596,10.766,1.558L10.766,1.558z M11.489,1.688
|
||||
c0.317,0.064,0.632,0.137,0.945,0.218C12.121,1.825,11.806,1.752,11.489,1.688L11.489,1.688z"
|
||||
/>
|
||||
<path d="M14.353,2.521c0.524,0.202,1.042,0.422,1.548,0.676C15.395,2.943,14.877,2.722,14.353,2.521L14.353,2.521z" />
|
||||
<path
|
||||
d="M5.234,1.558C4.992,1.596,4.751,1.64,4.511,1.688C4.751,1.64,4.992,1.596,5.234,1.558L5.234,1.558z M4.511,1.688
|
||||
C4.194,1.752,3.879,1.825,3.566,1.906C3.879,1.825,4.194,1.752,4.511,1.688L4.511,1.688z"
|
||||
/>
|
||||
<path d="M1.647,2.521C1.123,2.722,0.605,2.943,0.098,3.197C0.605,2.943,1.123,2.723,1.647,2.521L1.647,2.521z" />
|
||||
<path
|
||||
d="M3.398,1.95c-0.321,0.086-0.639,0.18-0.956,0.284C2.759,2.131,3.078,2.037,3.398,1.95L3.398,1.95z M2.443,2.235
|
||||
C2.238,2.302,2.034,2.373,1.831,2.448C2.034,2.373,2.238,2.302,2.443,2.235L2.443,2.235z"
|
||||
/>
|
||||
<path
|
||||
d="M12.602,1.95c0.321,0.086,0.639,0.181,0.956,0.284C13.241,2.131,12.922,2.036,12.602,1.95L12.602,1.95z M13.557,2.235
|
||||
c0.205,0.067,0.409,0.138,0.611,0.214C13.966,2.373,13.762,2.302,13.557,2.235L13.557,2.235z"
|
||||
/>
|
||||
<path
|
||||
d="M7.299,13.415c-0.04,0.005-0.08,0.011-0.12,0.017C7.218,13.425,7.259,13.42,7.299,13.415L7.299,13.415z M7.179,13.431
|
||||
c-0.125,0.019-0.25,0.042-0.373,0.069C6.929,13.474,7.053,13.45,7.179,13.431L7.179,13.431z"
|
||||
/>
|
||||
<path d="M9.937,13.713c0.197,0.073,0.391,0.154,0.581,0.249C10.329,13.868,10.134,13.786,9.937,13.713L9.937,13.713z" />
|
||||
<path d="M6.063,13.713c-0.197,0.072-0.391,0.154-0.581,0.249C5.672,13.868,5.866,13.786,6.063,13.713L6.063,13.713z" />
|
||||
<path
|
||||
d="M6.673,13.529c-0.079,0.019-0.158,0.041-0.236,0.064C6.516,13.57,6.594,13.548,6.673,13.529L6.673,13.529z M6.438,13.593
|
||||
c-0.082,0.024-0.163,0.05-0.244,0.078C6.275,13.644,6.356,13.617,6.438,13.593L6.438,13.593z"
|
||||
/>
|
||||
<path
|
||||
d="M9.327,13.529c0.079,0.019,0.158,0.041,0.236,0.064C9.484,13.57,9.406,13.548,9.327,13.529L9.327,13.529z M9.562,13.593
|
||||
c0.082,0.024,0.163,0.051,0.244,0.078C9.725,13.643,9.644,13.617,9.562,13.593L9.562,13.593z"
|
||||
/>
|
||||
<path
|
||||
d="M8.701,13.415c0.04,0.005,0.08,0.011,0.12,0.017C8.781,13.425,8.741,13.42,8.701,13.415L8.701,13.415z M8.821,13.431
|
||||
c0.125,0.019,0.249,0.043,0.373,0.069C9.071,13.474,8.947,13.45,8.821,13.431L8.821,13.431z"
|
||||
/>
|
||||
<path d="M10.748,1.556c0.006,0.001,0.012,0.002,0.018,0.003C10.76,1.557,10.754,1.556,10.748,1.556L10.748,1.556z" />
|
||||
<path
|
||||
d="M9.806,13.671c0.023,0.008,0.047,0.015,0.07,0.022C9.853,13.686,9.83,13.679,9.806,13.671L9.806,13.671z M9.877,13.693
|
||||
c0.02,0.006,0.041,0.013,0.061,0.02C9.917,13.706,9.897,13.7,9.877,13.693L9.877,13.693z"
|
||||
/>
|
||||
<path
|
||||
d="M14.169,2.448c0.026,0.01,0.053,0.02,0.079,0.031C14.221,2.469,14.195,2.458,14.169,2.448L14.169,2.448z M14.248,2.479
|
||||
c0.035,0.014,0.07,0.028,0.106,0.042C14.318,2.507,14.283,2.493,14.248,2.479L14.248,2.479z"
|
||||
/>
|
||||
<path d="M8.571,13.401c0.044,0.004,0.087,0.008,0.131,0.014C8.658,13.409,8.614,13.405,8.571,13.401L8.571,13.401z" />
|
||||
<path
|
||||
d="M9.195,13.501c0.023,0.005,0.046,0.01,0.069,0.014C9.241,13.51,9.218,13.506,9.195,13.501L9.195,13.501z M9.264,13.515
|
||||
c0.021,0.004,0.042,0.009,0.063,0.014C9.306,13.524,9.285,13.519,9.264,13.515L9.264,13.515z"
|
||||
/>
|
||||
<path
|
||||
d="M12.434,1.906c0.034,0.009,0.068,0.018,0.102,0.027C12.502,1.924,12.468,1.915,12.434,1.906L12.434,1.906z M12.536,1.933
|
||||
c0.022,0.006,0.044,0.012,0.065,0.018C12.58,1.944,12.558,1.939,12.536,1.933L12.536,1.933z"
|
||||
/>
|
||||
<path
|
||||
d="M9.921,2.453c0.229,0.026,0.459,0.057,0.69,0.093c0.504,0.079,1.033,0.189,1.572,0.328l0.159,0.042
|
||||
c0.506,0.135,1.003,0.293,1.477,0.469l0.081,0.032l0.094,0.037c0.191,0.073,0.374,0.147,0.55,0.22l-1.319,2.639
|
||||
c-1.099-0.449-2.26-0.751-3.469-0.901L9.921,2.453 M8.979,1.369L8.704,6.322c1.714,0.095,3.414,0.514,4.985,1.3l2.212-4.425
|
||||
c-0.507-0.253-1.025-0.475-1.548-0.676c-0.062-0.024-0.123-0.05-0.185-0.073c-0.516-0.191-1.039-0.357-1.567-0.498
|
||||
c-0.056-0.015-0.112-0.03-0.167-0.044c-0.551-0.142-1.108-0.26-1.668-0.348c-0.006-0.001-0.012-0.002-0.018-0.003
|
||||
C10.162,1.464,9.571,1.402,8.979,1.369L8.979,1.369z"
|
||||
/>
|
||||
<path
|
||||
d="M9.527,9.537c0.639,0.099,1.256,0.258,1.848,0.477l-1.34,2.679c-0.156-0.051-0.313-0.097-0.473-0.136l-0.153-0.033
|
||||
c-0.016-0.003-0.032-0.007-0.047-0.01L9.527,9.537 M8.587,8.435l-0.274,4.938c0.087,0.005,0.172,0.019,0.258,0.028
|
||||
c0.044,0.004,0.087,0.008,0.131,0.014c0.166,0.021,0.33,0.05,0.494,0.086c0.044,0.01,0.088,0.017,0.132,0.028
|
||||
c0.162,0.04,0.321,0.088,0.48,0.142c0.044,0.015,0.088,0.026,0.131,0.042c0.197,0.073,0.391,0.154,0.581,0.249l2.222-4.445
|
||||
C11.432,8.863,10.015,8.514,8.587,8.435L8.587,8.435z"
|
||||
/>
|
||||
<path
|
||||
d="M6.805,13.501c-0.023,0.005-0.046,0.01-0.069,0.014C6.759,13.51,6.782,13.506,6.805,13.501L6.805,13.501z M6.736,13.515
|
||||
c-0.021,0.004-0.042,0.009-0.063,0.014C6.694,13.524,6.715,13.519,6.736,13.515L6.736,13.515z"
|
||||
/>
|
||||
<path d="M7.429,13.401c-0.044,0.004-0.087,0.008-0.131,0.014C7.342,13.409,7.386,13.405,7.429,13.401L7.429,13.401z" />
|
||||
<path
|
||||
d="M6.194,13.671c-0.023,0.008-0.047,0.015-0.07,0.022C6.147,13.686,6.17,13.679,6.194,13.671L6.194,13.671z M6.123,13.693
|
||||
c-0.02,0.006-0.041,0.013-0.061,0.02C6.083,13.706,6.103,13.7,6.123,13.693L6.123,13.693z"
|
||||
/>
|
||||
<path d="M5.252,1.556C5.246,1.556,5.24,1.557,5.234,1.558C5.24,1.557,5.246,1.556,5.252,1.556L5.252,1.556z" />
|
||||
<path
|
||||
d="M3.566,1.906C3.532,1.915,3.498,1.924,3.464,1.933C3.498,1.924,3.532,1.915,3.566,1.906L3.566,1.906z M3.464,1.933
|
||||
C3.442,1.939,3.42,1.944,3.398,1.95C3.42,1.944,3.442,1.939,3.464,1.933L3.464,1.933z"
|
||||
/>
|
||||
<path
|
||||
d="M1.831,2.448c-0.026,0.01-0.053,0.02-0.079,0.031C1.779,2.469,1.805,2.458,1.831,2.448L1.831,2.448z M1.752,2.479
|
||||
c-0.035,0.014-0.07,0.028-0.106,0.042C1.682,2.507,1.717,2.493,1.752,2.479L1.752,2.479z"
|
||||
/>
|
||||
<path
|
||||
d="M6.079,2.453l0.164,2.96c-1.209,0.151-2.37,0.452-3.469,0.901L1.456,3.675c0.176-0.074,0.359-0.147,0.55-0.221l0.093-0.037
|
||||
l0.08-0.031c0.475-0.176,0.972-0.334,1.479-0.47l0.157-0.042c0.541-0.139,1.07-0.249,1.591-0.331
|
||||
C5.629,2.509,5.854,2.478,6.079,2.453 M7.021,1.369C6.429,1.402,5.838,1.464,5.252,1.556C5.246,1.556,5.24,1.557,5.234,1.558
|
||||
c-0.56,0.088-1.117,0.206-1.668,0.348C3.51,1.92,3.454,1.935,3.398,1.95C2.87,2.092,2.347,2.257,1.831,2.448
|
||||
C1.769,2.471,1.708,2.497,1.647,2.521C1.123,2.722,0.605,2.943,0.098,3.197l2.212,4.425c1.571-0.786,3.271-1.205,4.985-1.3
|
||||
L7.021,1.369L7.021,1.369z"
|
||||
/>
|
||||
<path
|
||||
d="M6.473,9.537l0.165,2.977c-0.027,0.006-0.054,0.011-0.082,0.018l-0.12,0.026c-0.154,0.038-0.306,0.082-0.471,0.135
|
||||
l-1.339-2.679C5.217,9.795,5.834,9.636,6.473,9.537 M7.413,8.435C5.985,8.514,4.568,8.863,3.259,9.518l2.222,4.445
|
||||
c0.19-0.095,0.385-0.177,0.581-0.249c0.043-0.016,0.088-0.028,0.131-0.042c0.158-0.054,0.318-0.103,0.48-0.142
|
||||
c0.044-0.011,0.088-0.018,0.132-0.028c0.163-0.036,0.328-0.065,0.494-0.086c0.044-0.005,0.087-0.01,0.131-0.014
|
||||
c0.086-0.009,0.172-0.023,0.258-0.028L7.413,8.435L7.413,8.435z"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -328,10 +328,12 @@ export const strings = {
|
|||
bottom: "Bottom",
|
||||
},
|
||||
objects: {
|
||||
general: "General",
|
||||
contextMenu: "Context menu",
|
||||
interactivity: "Interactivity",
|
||||
colors: "Colors",
|
||||
color: "Color",
|
||||
outline: "Outline",
|
||||
dimensions: "Dimensions",
|
||||
scale: "Scale",
|
||||
width: "Width",
|
||||
|
@ -342,9 +344,45 @@ export const strings = {
|
|||
size: "Size",
|
||||
axis: "Axis",
|
||||
style: "Style",
|
||||
rotation: "Rotation",
|
||||
anchorAndRotation: "Anchor & Rotation",
|
||||
fill: "Fill",
|
||||
strokeWidth: "Line Width",
|
||||
stroke: "Stroke",
|
||||
anchorX: "Anchor X",
|
||||
anchorY: "Anchor Y",
|
||||
alignX: "Align X",
|
||||
alignY: "Align Y",
|
||||
layout: "Layout",
|
||||
appearance: "Appearance",
|
||||
invalidFormat: "Invalid format",
|
||||
axes: {
|
||||
numericalSuffix: ": Numerical",
|
||||
categoricalSuffix: ": Categorical",
|
||||
tickFormat: "Tick Format",
|
||||
from: "from",
|
||||
to: "to",
|
||||
gap: "Gap",
|
||||
direction: "Direction",
|
||||
count: "Count",
|
||||
dataExpressions: "Data Expressions",
|
||||
},
|
||||
plotSegment: {
|
||||
subLayout: "Sub-layout",
|
||||
type: "Type",
|
||||
gridline: "Gridline",
|
||||
polarCoordinates: "Polar Coordinates",
|
||||
heightToArea: "Height to Area",
|
||||
equalizeArea: "Equalize area",
|
||||
inner: "Inner:",
|
||||
outer: "Outer:",
|
||||
radius: "Radius",
|
||||
angle: "Angle",
|
||||
curveCoordinates: "Curve Coordinates",
|
||||
normal: "Normal",
|
||||
groupBy: "Group by...",
|
||||
groupByCategory: "Group by ",
|
||||
},
|
||||
visibleOn: {
|
||||
visibility: "Visibility",
|
||||
label: "Visible On",
|
||||
|
@ -371,6 +409,7 @@ export const strings = {
|
|||
markerShape: "Shape",
|
||||
labels: "Labels",
|
||||
layout: "Layout",
|
||||
categoricalLegend: "Categorical legend",
|
||||
},
|
||||
links: {
|
||||
lineType: "Line Type",
|
||||
|
@ -384,6 +423,9 @@ export const strings = {
|
|||
linkMarkType: "Line mark type",
|
||||
curveness: "Curveness",
|
||||
},
|
||||
line: {
|
||||
lineStyle: "Line Style",
|
||||
},
|
||||
anchor: {
|
||||
label: "(drag the anchor in the glyph editor)",
|
||||
},
|
||||
|
@ -402,16 +444,13 @@ export const strings = {
|
|||
icon: {
|
||||
label: "Icon",
|
||||
image: "Image",
|
||||
anchorAndRotation: "Anchor & Rotation",
|
||||
anchorX: "Anchor X",
|
||||
anchorY: "Anchor Y",
|
||||
},
|
||||
image: {
|
||||
imageMode: "Resize Mode",
|
||||
letterbox: "Letterbox",
|
||||
stretch: "Stretch",
|
||||
dropImage: "Drop Image Here",
|
||||
defaultPlaceholder: "Drop/Paste Image"
|
||||
defaultPlaceholder: "Drop/Paste Image",
|
||||
},
|
||||
scales: {
|
||||
mode: "Mode",
|
||||
|
@ -420,5 +459,17 @@ export const strings = {
|
|||
interval: "Interval",
|
||||
inclusive: "Inclusive",
|
||||
},
|
||||
text: {
|
||||
margin: "Margin",
|
||||
},
|
||||
rect: {
|
||||
shape: "Shape",
|
||||
flipping: "Flipping",
|
||||
shapes: {
|
||||
rectangle: "Rectangle",
|
||||
triangle: "Triangle",
|
||||
ellipse: "Ellipse",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче