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
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ const Interactable = {
let params = []

// Pass additional paramater (Marker config object) in case it's a Marker.
if (this.config && this.config.marker) {
params.push(this.config.marker)
if (this.constructor.Name === 'marker') {
params.push(this.getConfig())
}

// Becuase we need to add the key always at the end
Expand Down
100 changes: 72 additions & 28 deletions packages/jsvectormap/src/js/components/marker.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,57 +2,101 @@ import { inherit } from '../util'
import BaseComponent from './base'
import Interactable from './concerns/interactable'

const NAME = 'marker'
const JVM_PREFIX = 'jvm-'
const MARKER_CLASS = `${JVM_PREFIX}element ${JVM_PREFIX}marker`
const MARKER_LABEL_CLASS = `${JVM_PREFIX}element ${JVM_PREFIX}label`

class Marker extends BaseComponent {
constructor({ index, style, label, cx, cy, map, group }) {
static get Name() {
return NAME
}

constructor(options, style) {
super()

// Private
this._map = map
this._options = options
this._style = style
this._labelX = null
this._labelY = null
this._offsets = null
this._isImage = !!style.initial.image

// Protected
this.config = arguments[0]
this.shape = map.canvas[this._isImage ? 'createImage' : 'createCircle']({ dataIndex: index, cx, cy }, style, group)
this._draw()

this.shape.addClass('jvm-marker jvm-element')
if (this._options.label) {
this._drawLabel()
}

if (this._isImage) {
this.updateLabelPosition()
}
}

if (label) {
this._createLabel(this.config)
}
getConfig() {
return this._options.config
}

updateLabelPosition() {
const map = this._options.map
if (this.label) {
this.label.set({
x: this._labelX * this._map.scale + this._offsets[0] +
this._map.transX * this._map.scale + 5 + (
this._isImage ? (this.shape.width || 0) / 2 : this.shape.node.r.baseVal.value
),
y: this._labelY * this._map.scale + this._map.transY * this._map.scale + this._offsets[1]
x:
this._labelX * map.scale +
this._offsets[0] +
map.transX * map.scale +
5 +
(this._isImage
? (this.shape.width || 0) / 2
: this.shape.node.r.baseVal.value),
y:
this._labelY * map.scale +
map.transY * this._options.map.scale +
this._offsets[1],
})
}
}

_createLabel({ index, map, label, labelsGroup, cx, cy, marker, isRecentlyCreated }) {
_draw() {
const { index, map, group, cx, cy } = this._options
const shapeType = this._isImage ? 'createImage' : 'createCircle'

this.shape = map.canvas[shapeType](
{ dataIndex: index, cx, cy },
this._style,
group
)
this.shape.addClass(MARKER_CLASS)
}

_drawLabel() {
const {
index,
map,
label,
labelsGroup,
cx,
cy,
config,
isRecentlyCreated,
} = this._options
const labelText = this.getLabelText(index, label)

this._labelX = cx / map.scale - map.transX
this._labelY = cy / map.scale - map.transY
this._offsets = isRecentlyCreated && marker.offsets ? marker.offsets : this.getLabelOffsets(index, label)

this.label = map.canvas.createText({
text: labelText,
dataIndex: index,
x: this._labelX,
y: this._labelY,
dy: '0.6ex',
}, map.params.markerLabelStyle, labelsGroup)

this.label.addClass('jvm-marker jvm-element')
this._offsets = isRecentlyCreated && config.offsets ? config.offsets : this.getLabelOffsets(index, label)
this.label = map.canvas.createText(
{
text: labelText,
dataIndex: index,
x: this._labelX,
y: this._labelY,
dy: '0.6ex',
},
map.params.markerLabelStyle,
labelsGroup
)
this.label.addClass(MARKER_LABEL_CLASS)

if (isRecentlyCreated) {
this.updateLabelPosition()
Expand All @@ -62,4 +106,4 @@ class Marker extends BaseComponent {

inherit(Marker, Interactable)

export default Marker
export default Marker
49 changes: 18 additions & 31 deletions packages/jsvectormap/src/js/core/createLines.js
Original file line number Diff line number Diff line change
@@ -1,53 +1,40 @@
import { merge, getLineUid } from '../util'
import Line from '../components/line'

const LINES_GROUP_CLASS = 'jvm-lines-group'

export default function createLines(lines, isRecentlyCreated = false) {
// Create group for holding lines we're checking if `linesGroup`
// exists or not becuase we may add lines after the map has
// loaded so we will append the futured lines to this group as well.
this.linesGroup = this.linesGroup || this.canvas.createGroup(LINES_GROUP_CLASS)

export default function createLines(lines) {
const markers = this._markers
const { style, elements: _, ...rest } = this.params.lines

let point1 = false, point2 = false

for (let index in lines) {
const config = lines[index]

for (let mindex in markers) {
const markerConfig = isRecentlyCreated
? markers[mindex].config
: markers[mindex]
const lineConfig = lines[index]

if (markerConfig.name === config.from) {
for (let { config: markerConfig } of Object.values(markers)) {
if (markerConfig.name === lineConfig.from) {
point1 = this.getMarkerPosition(markerConfig)
}

if (markerConfig.name === config.to) {
if (markerConfig.name === lineConfig.to) {
point2 = this.getMarkerPosition(markerConfig)
}
}

if (point1 !== false && point2 !== false) {
const options = {
index,
map: this,
group: this.linesGroup,
config,
x1: point1.x,
y1: point1.y,
x2: point2.x,
y2: point2.y,
...rest,
}

// Register lines with unique keys
this._lines[getLineUid(config.from, config.to)] = new Line(
options,
merge({ initial: style }, { initial: config.style || {} }, true)
this._lines[getLineUid(lineConfig.from, lineConfig.to)] = new Line(
{
index,
map: this,
group: this._linesGroup,
config: lineConfig,
x1: point1.x,
y1: point1.y,
x2: point2.x,
y2: point2.y,
...rest,
},
merge({ initial: style }, { initial: lineConfig.style || {} }, true)
)
}
}
Expand Down
35 changes: 15 additions & 20 deletions packages/jsvectormap/src/js/core/createMarkers.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,6 @@ import { merge } from '../util'
import Marker from '../components/marker'

export default function createMarkers(markers = {}, isRecentlyCreated = false) {
// Create groups for holding markers and markers labels
// We're checking if `markersGroup` exists or not becuase we may add markers after the map has loaded
// So we will append the futured markers to this group as well.
this._markersGroup = this._markersGroup || this.canvas.createGroup('jvm-markers-group')
this._markerLabelsGroup = this._markerLabelsGroup || this.canvas.createGroup('jvm-markers-labels-group')

for (let index in markers) {
const config = markers[index]
const point = this.getMarkerPosition(config)
Expand All @@ -30,19 +24,20 @@ export default function createMarkers(markers = {}, isRecentlyCreated = false) {
index = Object.keys(this._markers).length
}

const marker = new Marker({
index,
map: this,
// Merge the `markerStyle` object with the marker config `style` if presented.
style: merge(this.params.markerStyle, { ...config.style || {} }, true),
label: this.params.labels && this.params.labels.markers,
labelsGroup: this._markerLabelsGroup,
cx: point.x,
cy: point.y,
group: this._markersGroup,
marker: config,
isRecentlyCreated,
})
const marker = new Marker(
{
index,
map: this,
label: this.params.labels && this.params.labels.markers,
labelsGroup: this._markerLabelsGroup,
cx: point.x,
cy: point.y,
group: this._markersGroup,
config,
isRecentlyCreated,
},
merge(this.params.markerStyle, { ...(config.style || {}) }, true)
)

// Check for marker duplication
// this is useful when for example: a user clicks a button for creating marker two times
Expand All @@ -57,4 +52,4 @@ export default function createMarkers(markers = {}, isRecentlyCreated = false) {
element: marker,
}
}
}
}
30 changes: 25 additions & 5 deletions packages/jsvectormap/src/js/map.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@ import EventHandler from './eventHandler'
import Tooltip from './components/tooltip'
import DataVisualization from './dataVisualization'

const JVM_PREFIX = 'jvm-'
const CONTAINER_CLASS = `${JVM_PREFIX}container`
const MARKERS_GROUP_CLASS = `${JVM_PREFIX}markers-group`
const MARKERS_LABELS_GROUP_CLASS = `${JVM_PREFIX}markers-labels-group`
const LINES_GROUP_CLASS = `${JVM_PREFIX}lines-group`
const SERIES_CONTAINER_CLASS = `${JVM_PREFIX}series-container`
const SERIES_CONTAINER_H_CLASS = `${SERIES_CONTAINER_CLASS} ${JVM_PREFIX}series-h`
const SERIES_CONTAINER_V_CLASS = `${SERIES_CONTAINER_CLASS} ${JVM_PREFIX}series-v`

class Map {
static maps = {}
static defaults = Defaults
Expand Down Expand Up @@ -56,7 +65,7 @@ class Map {
const options = this.params

this.container = getElement(options.selector)
this.container.classList.add('jvm-container')
this.container.classList.add(CONTAINER_CLASS)

// The map canvas element
this.canvas = new SVGCanvasElement(this.container)
Expand All @@ -70,12 +79,23 @@ class Map {
// Update size
this.updateSize()

// Create lines
this._createLines(options.lines.elements || {})
// Lines group must be created before markers
// Otherwise the lines will be drawn on top of the markers.
if (options.lines.elements) {
this._linesGroup = this.canvas.createGroup(LINES_GROUP_CLASS)
}

if (options.markers) {
this._markersGroup = this.canvas.createGroup(MARKERS_GROUP_CLASS)
this._markerLabelsGroup = this.canvas.createGroup(MARKERS_LABELS_GROUP_CLASS)
}

// Create markers
this._createMarkers(options.markers)

// Create lines
this._createLines(options.lines.elements || {})

// Position labels
this._repositionLabels()

Expand Down Expand Up @@ -127,11 +147,11 @@ class Map {
// Create series if any
if (options.series) {
this.container.appendChild(this.legendHorizontal = createElement(
'div', 'jvm-series-container jvm-series-h'
'div', SERIES_CONTAINER_H_CLASS
))

this.container.appendChild(this.legendVertical = createElement(
'div', 'jvm-series-container jvm-series-v'
'div', SERIES_CONTAINER_V_CLASS
))

this._createSeries()
Expand Down