Skip to content

Commit 288a318

Browse files
novakov-alexeyalexarchambault
authored andcommitted
add Image support
1 parent 29c09f7 commit 288a318

File tree

8 files changed

+120
-1
lines changed

8 files changed

+120
-1
lines changed

core/shared/src/main/scala/plotly/Trace.scala

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,29 @@ object Box {
156156
)
157157
}
158158

159+
@data(optionSetters = true) class Image(
160+
z: Seq[Seq[Seq[Double]]],
161+
x0: Option[Element] = None,
162+
y0: Option[Element] = None,
163+
name: Option[String] = None,
164+
text: Option[Seq[String]] = None,
165+
opacity: Option[Double] = None,
166+
ids: Option[Seq[String]] = None,
167+
dx: Option[Double] = None,
168+
dy: Option[Double] = None,
169+
source: Option[String] = None,
170+
hoverinfo: Option[HoverInfo] = None,
171+
hovertemplate: Option[Seq[String]] = None,
172+
meta: Option[String] = None,
173+
customdata: Option[Seq[String]] = None,
174+
xaxis: Option[AxisReference] = None,
175+
yaxis: Option[AxisReference] = None,
176+
colormodel: Option[ColorModel] = None,
177+
zmax: Option[Seq[Double]] = None,
178+
zmin: Option[Seq[Double]] = None,
179+
hoverlabel: Option[HoverLabel] = None
180+
) extends Trace
181+
159182
@data(optionSetters = true) class Bar(
160183
x: Sequence,
161184
y: Sequence,
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package plotly.element
2+
3+
sealed abstract class Alignment(val label: String) extends Product with Serializable
4+
5+
object Alignment {
6+
case object Left extends Alignment("left")
7+
case object Right extends Alignment("right")
8+
case object Auto extends Alignment("auto")
9+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package plotly.element
2+
3+
sealed abstract class ColorModel(val label: String) extends Product with Serializable
4+
5+
object ColorModel {
6+
case object RGB extends ColorModel("rgb")
7+
case object RGBA extends ColorModel("rgba")
8+
case object RGBA256 extends ColorModel("rgba256")
9+
case object HSL extends ColorModel("hsl")
10+
case object HSLA extends ColorModel("hsla")
11+
}

core/shared/src/main/scala/plotly/element/HoverInfo.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ object HoverInfo {
2020
case object Z extends Element("z")
2121
case object Text extends Element("text")
2222
case object Name extends Element("name")
23+
case object Color extends Element("color")
2324

2425

2526
case object All extends HoverInfo {
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package plotly.element
2+
3+
import dataclass.data
4+
5+
@data(optionSetters = true) class HoverLabel(
6+
bgcolor: Option[OneOrSeq[Color]] = None,
7+
bordercolor: Option[OneOrSeq[Color]] = None,
8+
font: Option[HoverLabelFont] = None,
9+
align: Option[OneOrSeq[Alignment]] = None,
10+
namelength: Option[OneOrSeq[Int]] = None,
11+
uirevision: Option[Element] = None
12+
)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package plotly.element
2+
3+
import dataclass.data
4+
5+
@data(optionSetters = true) class HoverLabelFont(
6+
family: Option[OneOrSeq[String]] = None,
7+
size: Option[OneOrSeq[Double]] = None,
8+
color: Option[OneOrSeq[Color]] = None
9+
)

render/shared/src/main/scala/plotly/internals/ArgonautCodecsInternals.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ object ArgonautCodecsInternals extends ArgonautCodecsExtra {
149149
implicit val tickModeIsEnum = IsEnum.instance[TickMode](_.mode)
150150
implicit val patternIsEnum = IsEnum.instance[Pattern](_.label)
151151
implicit val rowOrderIsEnum = IsEnum.instance[RowOrder](_.label)
152+
implicit val alignmentIsEnum = IsEnum.instance[Alignment](_.label)
153+
implicit val colorModelIsEnum = IsEnum.instance[ColorModel](_.label)
152154

153155
def jsonSumDirectCodecFor(name: String): JsonSumCodec = new JsonSumCodec {
154156
def encodeEmpty: Nothing =
@@ -225,6 +227,7 @@ object ArgonautCodecsInternals extends ArgonautCodecsExtra {
225227
case "x" => Right(HoverInfo.X)
226228
case "y" => Right(HoverInfo.Y)
227229
case "z" => Right(HoverInfo.Z)
230+
case "color" => Right(HoverInfo.Color)
228231
case "text" => Right(HoverInfo.Text)
229232
case "name" => Right(HoverInfo.Name)
230233
case other => Left(s"Unrecognized hover info element: $other")

tests/src/test/scala/plotly/doc/DocumentationTests.scala

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@ package doc
44
import java.io.{ByteArrayOutputStream, File, InputStream}
55
import java.lang.{Double => JDouble}
66
import java.nio.file.Files
7-
87
import argonaut.Argonaut._
98
import argonaut.{Json, Parse}
109
import plotly.layout.Layout
1110
import org.mozilla.javascript._
1211
import org.scalatest.flatspec.AnyFlatSpec
1312
import org.scalatest.matchers.should.Matchers
13+
import plotly.element.HoverInfo
14+
import plotly.element.HoverInfo.{X,Y,Z}
15+
import plotly.element.ColorModel._
1416

1517
import scala.util.matching.Regex
1618

@@ -308,4 +310,53 @@ class DocumentationTests extends AnyFlatSpec with Matchers {
308310
}
309311
}
310312

313+
it should "demo Image Trace" in {
314+
val js =
315+
"""
316+
|var data = [
317+
| {
318+
| type: "image",
319+
| opacity: 0.1,
320+
| x0: 0.05,
321+
| y0: 0.05,
322+
| colormodel: "rgb",
323+
| hoverinfo: "x+y+z+color",
324+
| z: [[[255, 0, 0], [0, 255, 0], [0, 0, 255]]]
325+
| }
326+
|];
327+
|
328+
|var layout = {
329+
| width: 400,
330+
| height: 400,
331+
| title: "image with opacity 0.1"
332+
|};
333+
|
334+
|Plotly.newPlot('myDiv', data, layout);
335+
|""".stripMargin
336+
val (data, maybeLayout) = plotlyDemoElements(js)
337+
maybeLayout should ===(Some(
338+
Layout()
339+
.withWidth(400)
340+
.withHeight(400)
341+
.withTitle("image with opacity 0.1")
342+
))
343+
344+
data.headOption match {
345+
case Some(image) =>
346+
val colors = Seq(
347+
Seq(Seq(255d, 0d, 0d), Seq(0d, 255, 0), Seq(0d, 0, 255)),
348+
)
349+
val expected = Image(z = colors)
350+
.withOpacity(0.1)
351+
.withX0(0.05)
352+
.withY0(0.05)
353+
.withHoverinfo(HoverInfo(X, Y, Z, HoverInfo.Color))
354+
.withColormodel(RGB)
355+
356+
image should ===(expected)
357+
case None =>
358+
fail("data must contain an image trace")
359+
}
360+
}
361+
311362
}

0 commit comments

Comments
 (0)