Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/maps/vector-style-properties.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ Use *Icon* to symbolize Points as icons.

*Fill color*:: The fill color of the point features.

*Border color*:: The border color of the point features.

*Border width*:: The border width of the point features.

*Symbol orientation*:: The symbol orientation rotating the icon clockwise.

*Symbol size*:: The radius of the symbol size, in pixels.
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -15,31 +15,35 @@ export class SymbolIcon extends Component {
imgDataUrl: undefined,
prevSymbolId: undefined,
prevFill: undefined,
prevStroke: undefined,
prevStrokeWidth: undefined,
}

componentDidMount() {
this._isMounted = true;
this._loadSymbol(this.props.symbolId, this.props.fill);
this._loadSymbol(this.props.symbolId, this.props.fill, this.props.stroke, this.props.strokeWidth);
}

componentDidUpdate() {
this._loadSymbol(this.props.symbolId, this.props.fill);
this._loadSymbol(this.props.symbolId, this.props.fill, this.props.stroke, this.props.strokeWidth);
}

componentWillUnmount() {
this._isMounted = false;
}

async _loadSymbol(nextSymbolId, nextFill) {
async _loadSymbol(nextSymbolId, nextFill, nextStroke, nextStrokeWidth) {
if (nextSymbolId === this.state.prevSymbolId
&& nextFill === this.state.prevFill) {
&& nextFill === this.state.prevFill
&& nextStroke === this.state.prevStroke
&& nextStrokeWidth === this.state.prevStrokeWidth) {
return;
}

let imgDataUrl;
try {
const svg = getMakiSymbolSvg(nextSymbolId);
const styledSvg = await styleSvg(svg, nextFill);
const styledSvg = await styleSvg(svg, nextFill, nextStroke, nextStrokeWidth);
imgDataUrl = buildSrcUrl(styledSvg);
} catch (error) {
// ignore failures - component will just not display an icon
Expand All @@ -49,7 +53,9 @@ export class SymbolIcon extends Component {
this.setState({
imgDataUrl,
prevSymbolId: nextSymbolId,
prevFill: nextFill
prevFill: nextFill,
prevStroke: nextStroke,
prevStrokeWidth: nextStrokeWidth
});
}
}
Expand All @@ -68,4 +74,6 @@ export class SymbolIcon extends Component {
SymbolIcon.propTypes = {
symbolId: PropTypes.string.isRequired,
fill: PropTypes.string.isRequired,
stroke: PropTypes.string.isRequired,
strokeWidth: PropTypes.string.isRequired
};
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ export class VectorIcon extends Component {
<SymbolIcon
symbolId={this.props.symbolId}
fill={style.fill}
stroke={style.stroke}
strokeWidth={style.strokeWidth}
/>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { VectorStyleSymbolEditor } from './vector_style_symbol_editor';
import { OrientationEditor } from './orientation/orientation_editor';
import { getDefaultDynamicProperties, getDefaultStaticProperties } from '../../vector_style_defaults';
import { VECTOR_SHAPE_TYPES } from '../../../sources/vector_feature_types';
import { SYMBOLIZE_AS_CIRCLE } from '../../vector_constants';
import { SYMBOLIZE_AS_ICON } from '../../vector_constants';
import { i18n } from '@kbn/i18n';
import { SYMBOL_OPTIONS } from '../../symbol_utils';

Expand Down Expand Up @@ -140,23 +140,8 @@ export class VectorStyleEditor extends Component {
}

_renderPointProperties() {
let lineColor;
let lineWidth;
let iconOrientation;
if (this.props.styleProperties.symbol.options.symbolizeAs === SYMBOLIZE_AS_CIRCLE) {
lineColor = (
<Fragment>
{this._renderLineColor()}
<EuiSpacer size="m" />
</Fragment>
);
lineWidth = (
<Fragment>
{this._renderLineWidth()}
<EuiSpacer size="m" />
</Fragment>
);
} else {
if (this.props.styleProperties.symbol.options.symbolizeAs === SYMBOLIZE_AS_ICON) {
iconOrientation = (
<Fragment>
<OrientationEditor
Expand Down Expand Up @@ -185,9 +170,11 @@ export class VectorStyleEditor extends Component {
{this._renderFillColor()}
<EuiSpacer size="m" />

{lineColor}
{this._renderLineColor()}
<EuiSpacer size="m" />

{lineWidth}
{this._renderLineWidth()}
<EuiSpacer size="m" />

{iconOrientation}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ export function VectorStyleSymbolEditor({ styleOptions, handlePropertyChange, sy
<SymbolIcon
symbolId={value}
fill={isDarkMode ? 'rgb(223, 229, 239)' : 'rgb(52, 55, 65)'}
stroke={isDarkMode ? 'rgb(255, 255, 255)' : 'rgb(0, 0, 0)'}
strokeWidth={'1px'}
/>
</EuiFlexItem>
<EuiFlexItem>
Expand Down
12 changes: 10 additions & 2 deletions x-pack/legacy/plugins/maps/public/layers/styles/symbol_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,19 @@ export function buildSrcUrl(svgString) {
return domUrl.createObjectURL(svg);
}

export async function styleSvg(svgString, fill) {
export async function styleSvg(svgString, fill, stroke, strokeWidth) {
const svgXml = await parseXmlString(svgString);
let style = '';
if (fill) {
svgXml.svg.$.style = `fill: ${fill};`;
style += `fill:${fill};`;
}
if (stroke) {
style += `stroke:${stroke};`;
}
if (strokeWidth) {
style += `stroke-width:${strokeWidth};`;
}
if (style) svgXml.svg.$.style = style;
const builder = new xml2js.Builder();
return builder.buildObject(svgXml);
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,30 @@ describe('getMakiSymbolSvg', () => {
});

describe('styleSvg', () => {
it('Should not add style property when fill not provided', async () => {
it('Should not add style property when style not provided', async () => {
const unstyledSvgString = '<svg version="1.1" width="11px" height="11px" viewBox="0 0 11 11"><path/></svg>';
const styledSvg = await styleSvg(unstyledSvgString);
expect(styledSvg.split('\n')[1]).toBe('<svg version=\"1.1\" width=\"11px\" height=\"11px\" viewBox=\"0 0 11 11\">');
});

it('Should add style property to svg element', async () => {
it('Should add fill style property to svg element', async () => {
const unstyledSvgString = '<svg version="1.1" width="11px" height="11px" viewBox="0 0 11 11"><path/></svg>';
const styledSvg = await styleSvg(unstyledSvgString, 'red');
// eslint-disable-next-line max-len
expect(styledSvg.split('\n')[1]).toBe('<svg version=\"1.1\" width=\"11px\" height=\"11px\" viewBox=\"0 0 11 11\" style=\"fill: red;\">');
expect(styledSvg.split('\n')[1]).toBe('<svg version=\"1.1\" width=\"11px\" height=\"11px\" viewBox=\"0 0 11 11\" style=\"fill:red;\">');
});

it('Should add stroke style property to svg element', async () => {
const unstyledSvgString = '<svg version="1.1" width="11px" height="11px" viewBox="0 0 11 11"><path/></svg>';
const styledSvg = await styleSvg(unstyledSvgString, 'red', 'white');
// eslint-disable-next-line max-len
expect(styledSvg.split('\n')[1]).toBe('<svg version=\"1.1\" width=\"11px\" height=\"11px\" viewBox=\"0 0 11 11\" style=\"fill:red;stroke:white;\">');
});

it('Should add stroke-width style property to svg element', async () => {
const unstyledSvgString = '<svg version="1.1" width="11px" height="11px" viewBox="0 0 11 11"><path/></svg>';
const styledSvg = await styleSvg(unstyledSvgString, 'red', 'white', '2px');
// eslint-disable-next-line max-len
expect(styledSvg.split('\n')[1]).toBe('<svg version=\"1.1\" width=\"11px\" height=\"11px\" viewBox=\"0 0 11 11\" style=\"fill:red;stroke:white;stroke-width:2px;\">');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -546,8 +546,12 @@ export class VectorStyle extends AbstractStyle {
const symbolId = this._descriptor.properties.symbol.options.symbolId;
mbMap.setLayoutProperty(symbolLayerId, 'icon-anchor', getMakiSymbolAnchor(symbolId));
const color = this._getMBColor(this._descriptor.properties.fillColor);
const haloColor = this._getMBColor(this._descriptor.properties.lineColor);
const haloWidth = this._getMbSize(this._descriptor.properties.lineWidth);
// icon-color is only supported on SDF icons.
mbMap.setPaintProperty(symbolLayerId, 'icon-color', color);
mbMap.setPaintProperty(symbolLayerId, 'icon-halo-color', haloColor);
mbMap.setPaintProperty(symbolLayerId, 'icon-halo-width', haloWidth);
mbMap.setPaintProperty(symbolLayerId, 'icon-opacity', alpha);

// circle sizing is by radius
Expand Down