diff --git a/src/app/cartography/shared/models/drawings/ellipse-element.ts b/src/app/cartography/shared/models/drawings/ellipse-element.ts new file mode 100644 index 00000000..7b3b6235 --- /dev/null +++ b/src/app/cartography/shared/models/drawings/ellipse-element.ts @@ -0,0 +1,15 @@ +import { DrawingElement } from "./drawing-element"; + + +export class EllipseElement implements DrawingElement { + height: number; + width: number; + cx: number; + cy: number; + fill: string; + fill_opacity: number; + rx: number; + ry: number; + stroke: string; + stroke_width: number; +} diff --git a/src/app/cartography/shared/models/drawings/image-element.ts b/src/app/cartography/shared/models/drawings/image-element.ts new file mode 100644 index 00000000..154e147b --- /dev/null +++ b/src/app/cartography/shared/models/drawings/image-element.ts @@ -0,0 +1,8 @@ +import { DrawingElement } from "./drawing-element"; + + +export class ImageElement implements DrawingElement { + height: number; + width: number; + data: string; +} diff --git a/src/app/cartography/shared/models/drawings/line-element.ts b/src/app/cartography/shared/models/drawings/line-element.ts new file mode 100644 index 00000000..18aba742 --- /dev/null +++ b/src/app/cartography/shared/models/drawings/line-element.ts @@ -0,0 +1,13 @@ +import { DrawingElement } from "./drawing-element"; + + +export class LineElement implements DrawingElement { + height: number; + width: number; + stroke: string; + stroke_width: number; + x1: number; + x2: number; + y1: number; + y2: number; +} diff --git a/src/app/cartography/shared/models/drawings/rect-element.ts b/src/app/cartography/shared/models/drawings/rect-element.ts new file mode 100644 index 00000000..dce73480 --- /dev/null +++ b/src/app/cartography/shared/models/drawings/rect-element.ts @@ -0,0 +1,11 @@ +import { DrawingElement } from "./drawing-element"; + + +export class RectElement implements DrawingElement { + height: number; + width: number; + fill: string; + fill_opacity: number; + stroke: string; + stroke_width: number; +} diff --git a/src/app/cartography/shared/widgets/drawings/image-drawing.spec.ts b/src/app/cartography/shared/widgets/drawings/image-drawing.spec.ts new file mode 100644 index 00000000..9a4758ff --- /dev/null +++ b/src/app/cartography/shared/widgets/drawings/image-drawing.spec.ts @@ -0,0 +1,43 @@ +import { TestSVGCanvas } from "../../../testing"; +import { Drawing } from "../../models/drawing"; +import { ImageDrawingWidget } from "./image-drawing"; +import { ImageElement } from "../../models/drawings/image-element"; + + +describe('ImageDrawingWidget', () => { + let svg: TestSVGCanvas; + let widget: ImageDrawingWidget; + let drawing: Drawing; + + + beforeEach(() => { + svg = new TestSVGCanvas(); + drawing = new Drawing(); + widget = new ImageDrawingWidget(); + }); + + afterEach(() => { + svg.destroy(); + }); + + it('should draw image drawing', () => { + const image = new ImageElement(); + image.width = 100; + image.height = 200; + image.data = "DATA"; + drawing.element = image; + + const drawings = svg.canvas.selectAll('g.drawing').data([drawing]); + const drawings_enter = drawings.enter().append('g').classed('drawing', true); + const drawings_merge = drawings.merge(drawings_enter); + + widget.draw(drawings_merge); + + const drew = drawings_merge.selectAll('image.image_element'); + expect(drew.size()).toEqual(1); + const image_element = drew.nodes()[0]; + expect(image_element.getAttribute('width')).toEqual('100'); + expect(image_element.getAttribute('height')).toEqual('200'); + expect(image_element.getAttribute('href')).toEqual('data:image/svg+xml;base64,REFUQQ=='); + }); +}); diff --git a/src/app/cartography/shared/widgets/drawings/image-drawing.ts b/src/app/cartography/shared/widgets/drawings/image-drawing.ts new file mode 100644 index 00000000..0ab96277 --- /dev/null +++ b/src/app/cartography/shared/widgets/drawings/image-drawing.ts @@ -0,0 +1,38 @@ +import { SVGSelection } from "../../models/types"; +import { Drawing } from "../../models/drawing"; +import { ImageElement } from "../../models/drawings/image-element"; + + +export class ImageDrawingWidget { + public draw(view: SVGSelection) { + const drawing = view + .selectAll('image.image_element') + .data((d: Drawing) => { + return (d.element && d.element instanceof ImageElement) ? [d.element] : []; + }); + + const drawing_enter = drawing + .enter() + .append('image') + .attr('class', 'image_element noselect'); + + const merge = drawing.merge(drawing_enter); + + merge + .attr('xlink:href', (image: ImageElement) => { + let svg = image.data; + if (svg.indexOf("xmlns") < 0) { + svg = svg.replace('svg', 'svg xmlns="http://www.w3.org/2000/svg"'); + } + return 'data:image/svg+xml;base64,' + btoa(svg); + }) + .attr('width', (image) => image.width) + .attr('height', (image) => image.height); + + + drawing + .exit() + .remove(); + + } +}