forked from JetBrains/lets-plot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
PointGeom.kt
101 lines (84 loc) · 3.7 KB
/
PointGeom.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/*
* Copyright (c) 2020. JetBrains s.r.o.
* Use of this source code is governed by the MIT license that can be found in the LICENSE file.
*/
package jetbrains.datalore.plot.base.geom
import jetbrains.datalore.base.geometry.DoubleVector
import jetbrains.datalore.base.values.Color
import jetbrains.datalore.plot.base.Aesthetics
import jetbrains.datalore.plot.base.CoordinateSystem
import jetbrains.datalore.plot.base.DataPointAesthetics
import jetbrains.datalore.plot.base.GeomContext
import jetbrains.datalore.plot.base.PositionAdjustment
import jetbrains.datalore.plot.base.aes.AesScaling
import jetbrains.datalore.plot.base.aes.AestheticsUtil
import jetbrains.datalore.plot.base.geom.util.GeomHelper
import jetbrains.datalore.plot.base.geom.util.GeomHelper.Companion.getUnitResBySizeUnit
import jetbrains.datalore.plot.base.geom.util.HintColorUtil.fromColorValue
import jetbrains.datalore.plot.base.interact.GeomTargetCollector.TooltipParams
import jetbrains.datalore.plot.base.interact.GeomTargetCollector.TooltipParams.Companion.params
import jetbrains.datalore.plot.base.render.LegendKeyElementFactory
import jetbrains.datalore.plot.base.render.SvgRoot
import jetbrains.datalore.plot.base.render.point.NamedShape
import jetbrains.datalore.plot.base.render.point.PointShapeSvg
import jetbrains.datalore.plot.base.render.point.TinyPointShape
import jetbrains.datalore.plot.common.data.SeriesUtil
import jetbrains.datalore.vis.svg.slim.SvgSlimElements
open class PointGeom : GeomBase() {
var animation: Any? = null
var sizeUnit: String? = null
override val legendKeyElementFactory: LegendKeyElementFactory
get() = PointLegendKeyElementFactory()
public override fun buildIntern(
root: SvgRoot,
aesthetics: Aesthetics,
pos: PositionAdjustment,
coord: CoordinateSystem,
ctx: GeomContext
) {
val helper = GeomHelper(pos, coord, ctx)
val targetCollector = getGeomTargetCollector(ctx)
val count = aesthetics.dataPointCount()
val slimGroup = SvgSlimElements.g(count)
val sizeUnitRatio = getSizeUnitRatio(ctx)
for (i in 0 until count) {
val p = aesthetics.dataPointAt(i)
val x = p.x()
val y = p.y()
if (SeriesUtil.allFinite(x, y)) {
val location = helper.toClient(DoubleVector(x!!, y!!), p)
val shape = p.shape()!!
targetCollector.addPoint(
i, location, sizeUnitRatio * shape.size(p) / 2,
tooltipParams(p)
)
val o = PointShapeSvg.create(shape, location, p, sizeUnitRatio)
o.appendTo(slimGroup)
}
}
root.add(wrap(slimGroup))
}
private fun getSizeUnitRatio(ctx: GeomContext): Double {
sizeUnit?.let { sizeUnitValue ->
val unitRes = getUnitResBySizeUnit(ctx, sizeUnitValue)
// TODO: Need refactoring: It's better to use NamedShape.FILLED_CIRCLE.size(1.0)
// but AesScaling.circleDiameter is used because Shape.size() takes DataPointAesthetics
val unitShapeSize = 2.2
return unitRes / unitShapeSize
}
return 1.0
}
companion object {
const val HANDLES_GROUPS = false
fun tooltipParams(p: DataPointAesthetics): TooltipParams {
var color = Color.TRANSPARENT
if (p.shape() == TinyPointShape) {
color = p.color()!!
} else if (p.shape() is NamedShape) {
val shape = p.shape() as NamedShape
color = AestheticsUtil.fill(shape.isFilled, shape.isSolid, p)
}
return params().setColor(fromColorValue(color, p.alpha()!!))
}
}
}