diff --git a/examples/markers.html b/examples/markers.html
new file mode 100644
index 0000000..5c1521f
--- /dev/null
+++ b/examples/markers.html
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/markers.ts b/src/components/markers.ts
new file mode 100644
index 0000000..4b8c806
--- /dev/null
+++ b/src/components/markers.ts
@@ -0,0 +1,51 @@
+import { MarkerSerie } from "../models/marker";
+import { PodState } from "@chartwerk/core";
+import { LineTimeSerie, LineOptions } from "../types";
+
+import d3 from "d3";
+
+export class Markers {
+ // TODO: more sentic name
+ private _d3Holder = null;
+
+ constructor(private _markers: MarkerSerie[], private _state: PodState) {
+ }
+
+ render(metricContainer: d3.Selection) {
+ if(this._d3Holder !== null) {
+ this._d3Holder.remove();
+ }
+ this._d3Holder = metricContainer.append('g').attr('class', 'markers-layer');
+ for (const ms of this._markers) {
+ this.renderMarkerSerie(ms);
+ }
+ }
+
+ protected renderMarkerSerie(serie: MarkerSerie) {
+ serie.data.forEach((d) => {
+ let linePosition = this._state.xScale(d) as number;
+ this._d3Holder.append('line')
+ .attr('class', 'gap-line')
+ .attr('stroke', serie.color)
+ .attr('stroke-width', '1px')
+ .attr('stroke-opacity', '0.3')
+ .attr('stroke-dasharray', '4')
+ .attr('x1', linePosition)
+ .attr('x2', linePosition)
+ .attr('y1', 0)
+ // @ts-ignore // TODO: remove ignore but boxParams are protected
+ .attr('y2', this._state.boxParams.height)
+ .attr('pointer-events', 'none');
+ this._d3Holder.append('circle')
+ .attr('class', 'gap-circle')
+ .attr('stroke', serie.color)
+ .attr('stroke-width', '2px')
+ .attr('r', 4)
+ .attr('cx', linePosition)
+ .attr('cy', 5)
+ .attr('pointer-events', 'none') // TODO: make all on implementation of Events
+ .style('cursor', 'pointer')
+ });
+
+ }
+}
\ No newline at end of file
diff --git a/src/index.ts b/src/index.ts
index ca82f37..67db165 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,5 +1,6 @@
import { ChartwerkPod, VueChartwerkPodMixin, TimeFormat, CrosshairOrientation, BrushOrientation, yAxisOrientation } from '@chartwerk/core';
import { LineTimeSerie, LineOptions } from './types';
+import { Markers } from './components/markers';
import { LineSeries } from './models/line_series';
@@ -17,12 +18,17 @@ export class LinePod extends ChartwerkPod {
lineGeneratorY1 = null;
areaGeneratorY1 = null;
- constructor(_el: HTMLElement, _series: LineTimeSerie[] = [], _options: LineOptions = {}) {
+ private _markersLayer: Markers = null;
+
+ constructor(
+ _el: HTMLElement, _series: LineTimeSerie[] = [], _options: LineOptions = {},
+ private _markerSeries = []
+ ) {
super(_el, _series, _options);
this.series = new LineSeries(_series);
}
- renderMetrics(): void {
+ override renderMetrics(): void {
this.clearAllMetrics();
this.updateCrosshair();
@@ -36,6 +42,8 @@ export class LinePod extends ChartwerkPod {
for(const serie of this.series.visibleSeries) {
this._renderMetric(serie);
}
+ this._markersLayer = new Markers(this._markerSeries, this.state);
+ this._markersLayer.render(this.metricContainer);
}
clearAllMetrics(): void {
@@ -386,6 +394,7 @@ export class LinePod extends ChartwerkPod {
}
}
+// TODO: it should be moved to VUE folder
// it is used with Vue.component, e.g.: Vue.component('chartwerk-line-pod', VueChartwerkLinePod)
export const VueChartwerkLinePod = {
// alternative to `template: ''`
diff --git a/src/models/line_series.ts b/src/models/line_series.ts
index dd9039e..d75cf07 100644
--- a/src/models/line_series.ts
+++ b/src/models/line_series.ts
@@ -15,7 +15,6 @@ const LINE_SERIE_DEFAULTS = {
};
export class LineSeries extends CoreSeries {
-
constructor(series: LineTimeSerie[]) {
super(series, _.clone(LINE_SERIE_DEFAULTS));
}
diff --git a/src/models/marker.ts b/src/models/marker.ts
new file mode 100644
index 0000000..7253729
--- /dev/null
+++ b/src/models/marker.ts
@@ -0,0 +1,4 @@
+export type MarkerSerie = {
+ color: string;
+ data: [number, number, any][] // [x, y, payload] payload is any data for tooltip
+}