Skip to content

Commit 1d82e3b

Browse files
eric-czechalexarchambault
authored andcommitted
Adding Heatmap trace implementation (#148)
1 parent f7dd66d commit 1d82e3b

File tree

14 files changed

+240
-8
lines changed

14 files changed

+240
-8
lines changed

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

100644100755
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ sealed abstract class Sequence extends Product with Serializable
77
object Sequence {
88
final case class Doubles(seq: Seq[Double]) extends Sequence
99
final case class NestedDoubles(seq: Seq[Seq[Double]]) extends Sequence
10+
final case class NestedInts(seq: Seq[Seq[Int]]) extends Sequence
1011
final case class Strings(seq: Seq[String]) extends Sequence
1112
final case class DateTimes(seq: Seq[LocalDateTime]) extends Sequence
1213

@@ -20,6 +21,8 @@ object Sequence {
2021
Doubles(s.map(_.toDouble))
2122
implicit def fromNestedDoubleSeq(s: Seq[Seq[Double]]): Sequence =
2223
NestedDoubles(s)
24+
implicit def fromNestedIntSeq(s: Seq[Seq[Int]]): Sequence =
25+
NestedInts(s)
2326
implicit def fromStringSeq(s: Seq[String]): Sequence =
2427
Strings(s)
2528
implicit def fromDateTimes(seq: Seq[LocalDateTime]): Sequence =

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

100644100755
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,3 +260,34 @@ object Surface {
260260
Option(opacity) .map(d => d: Double)
261261
)
262262
}
263+
264+
@data class Heatmap(
265+
y: Option[Sequence],
266+
x: Option[Sequence],
267+
z: Option[Sequence],
268+
autocolorscale: Option[Boolean],
269+
colorscale: Option[ColorScale],
270+
showscale: Option[Boolean],
271+
name: Option[String]
272+
) extends Trace
273+
274+
object Heatmap {
275+
def apply(
276+
y: Sequence = null,
277+
x: Sequence = null,
278+
z: Sequence = null,
279+
autocolorscale: JBoolean = null,
280+
colorscale: ColorScale = null,
281+
showscale: JBoolean = null,
282+
name: String = null
283+
): Heatmap =
284+
Heatmap(
285+
Option(y),
286+
Option(x),
287+
Option(z),
288+
Option(autocolorscale).map(b => b: Boolean),
289+
Option(colorscale),
290+
Option(showscale).map(b => b: Boolean),
291+
Option(name)
292+
)
293+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package plotly.element
2+
import dataclass.data
3+
4+
sealed abstract class ColorScale extends Product with Serializable
5+
6+
object ColorScale {
7+
@data class CustomScale(values: Seq[(Double, Color)]) extends ColorScale
8+
@data class NamedScale(name: String) extends ColorScale
9+
}

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

100644100755
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,6 @@ sealed abstract class Ticks(val label: String) extends Product with Serializable
55

66
object Ticks {
77
case object Outside extends Ticks("outside")
8+
case object Inside extends Ticks("inside")
9+
case object Empty extends Ticks("")
810
}

core/shared/src/main/scala/plotly/layout/Axis.scala

100644100755
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ import plotly.element._
2323
dtick: Option[Double],
2424
ticklen: Option[Int],
2525
tickfont: Option[Font],
26+
tickprefix: Option[String],
27+
ticksuffix: Option[String],
2628
zeroline: Option[Boolean],
2729
zerolinewidth: Option[Double],
2830
zerolinecolor: Option[Color],
@@ -60,6 +62,8 @@ object Axis {
6062
dtick: JDouble = null,
6163
ticklen: JInt = null,
6264
tickfont: Font = null,
65+
tickprefix: String = null,
66+
ticksuffix: String = null,
6367
zeroline: JBoolean = null,
6468
zerolinewidth: JDouble = null,
6569
zerolinecolor: Color = null,
@@ -95,6 +99,8 @@ object Axis {
9599
Option(dtick) .map(x => x: Double),
96100
Option(ticklen) .map(x => x: Int),
97101
Option(tickfont),
102+
Option(tickprefix),
103+
Option(ticksuffix),
98104
Option(zeroline) .map(x => x: Boolean),
99105
Option(zerolinewidth) .map(x => x: Double),
100106
Option(zerolinecolor),

demo/src/main/scala/plotly/demo/Demo.scala

100644100755
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ import scalatags.JsDom.all.{area => _, _}
3737
),
3838
"Filled Area Plots" -> Seq(
3939
area.BasicOverlaidAreaChart
40+
),
41+
"Heatmaps" -> Seq(
42+
heatmaps.BasicHeatmap,
43+
heatmaps.CategoricalAxisHeatmap,
44+
heatmaps.CustomColorScaleHeatmap,
45+
heatmaps.AnnotatedHeatmap
4046
)
4147
)
4248

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package plotly.demo.heatmaps
2+
3+
import plotly._
4+
import plotly.demo.DemoChart
5+
import plotly.element._
6+
import plotly.layout._
7+
8+
object AnnotatedHeatmap extends DemoChart {
9+
10+
def plotlyDocUrl = "https://plot.ly/javascript/heatmaps/#annotated-heatmap"
11+
def id = "annotated-heatmap"
12+
def source = AnnotatedHeatmapSource.source
13+
14+
// demo source start
15+
16+
val x = Seq("A", "B", "C", "D", "E");
17+
val y = Seq("W", "X", "Y", "Z");
18+
val z = Seq(
19+
Seq(0.00, 0.00, 0.75, 0.75, 0.00),
20+
Seq(0.00, 0.00, 0.75, 0.75, 0.00),
21+
Seq(0.75, 0.75, 0.75, 0.75, 0.75),
22+
Seq(0.00, 0.00, 0.00, 0.75, 0.00)
23+
)
24+
25+
val data = Seq(
26+
Heatmap(
27+
z=z, x=x, y=y, showscale=false,
28+
colorscale = ColorScale.CustomScale(Seq(
29+
(0, Color.StringColor("#3D9970")),
30+
(1, Color.StringColor("#001f3f"))
31+
))
32+
)
33+
)
34+
35+
val layout = Layout(
36+
title = "Annotated Heatmap",
37+
xaxis = Axis(ticks=Ticks.Empty, side=Side.Top),
38+
yaxis = Axis(ticks=Ticks.Empty, ticksuffix=" "),
39+
annotations = for {
40+
(xv, xi) <- x.zipWithIndex;
41+
(yv, yi) <- y.zipWithIndex
42+
} yield Annotation(
43+
x=xv,
44+
y=yv,
45+
xref=Ref.Axis(AxisReference.X1),
46+
yref=Ref.Axis(AxisReference.Y1),
47+
showarrow=false,
48+
text=z(yi)(xi).toString,
49+
font=Font(color=Color.StringColor("white"))
50+
)
51+
)
52+
53+
// demo source end
54+
55+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package plotly.demo.heatmaps
2+
3+
import plotly._
4+
import plotly.demo.NoLayoutDemoChart
5+
import plotly.element._
6+
7+
object BasicHeatmap extends NoLayoutDemoChart {
8+
9+
def plotlyDocUrl = "https://plot.ly/javascript/heatmaps/#basic-heatmap"
10+
def id = "basic-heatmap"
11+
def source = BasicHeatmapSource.source
12+
13+
// demo source start
14+
15+
val data = Seq(
16+
Heatmap(
17+
z=Seq(
18+
Seq(1, 20, 30),
19+
Seq(20, 1, 60),
20+
Seq(30, 60, 1)
21+
),
22+
colorscale=ColorScale.NamedScale("Portland")
23+
)
24+
)
25+
26+
// demo source end
27+
28+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package plotly.demo.heatmaps
2+
3+
import plotly._
4+
import plotly.demo.NoLayoutDemoChart
5+
import plotly.element._
6+
7+
object CategoricalAxisHeatmap extends NoLayoutDemoChart {
8+
9+
def plotlyDocUrl = "https://plot.ly/javascript/heatmaps/#heatmap-with-categorical-axis-labels"
10+
def id = "categorical-axis-heatmap"
11+
def source = CategoricalAxisHeatmapSource.source
12+
13+
// demo source start
14+
15+
val data = Seq(
16+
Heatmap(
17+
z=Seq(
18+
Seq(1, null.asInstanceOf[Int], 30, 50, 1),
19+
Seq(20, 1, 60, 80, 30),
20+
Seq(30, 60, 1, -10, 20)
21+
),
22+
x=Seq("Monday", "Tuesday", "Wednesday", "Thursday", "Friday"),
23+
y=Seq("Morning", "Afternoon", "Evening"),
24+
)
25+
)
26+
27+
// demo source end
28+
29+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package plotly.demo.heatmaps
2+
3+
import plotly._
4+
import plotly.demo.NoLayoutDemoChart
5+
import plotly.element._
6+
7+
object CustomColorScaleHeatmap extends NoLayoutDemoChart {
8+
9+
def plotlyDocUrl = "https://plot.ly/javascript/colorscales/#custom-colorscale-for-contour-plot"
10+
def id = "custom-colorscale-heatmap"
11+
def source = CustomColorScaleHeatmapSource.source
12+
13+
// demo source start
14+
15+
val data = Seq(
16+
Heatmap(
17+
z=Seq(
18+
Seq(10.0, 10.625, 12.5, 15.625, 20.0),
19+
Seq(5.625, 6.25, 8.125, 11.25, 15.625),
20+
Seq(2.5, 3.125, 5.0, 8.125, 12.5),
21+
Seq(0.625, 1.25, 3.125, 6.25, 10.625),
22+
Seq(0.0, 0.625, 2.5, 5.625, 10.0)
23+
),
24+
colorscale=ColorScale.CustomScale(Seq(
25+
(0, Color.RGB(166,206,227)),
26+
(0.25, Color.RGB(31,120,180)),
27+
(0.45, Color.RGB(178,223,138)),
28+
(0.65, Color.RGB(51,160,44)),
29+
(0.85, Color.RGB(251,154,153)),
30+
(1, Color.RGB(227,26,28))
31+
))
32+
)
33+
)
34+
35+
// demo source end
36+
37+
}

0 commit comments

Comments
 (0)