Skip to content

Commit 42ffa62

Browse files
author
Sven Behrens
committed
Add properties Histogram.{yaxis, hovertext}, layout.Axis.{tickformat, fixedrange} and add Demo for Histogram
1 parent 0ad886c commit 42ffa62

File tree

8 files changed

+154
-46
lines changed

8 files changed

+154
-46
lines changed

.git-blame-ignore-revs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# activate meaningful git annotations with:
2+
# git config blame.ignoreRevsFile .git-blame-ignore-revs
3+
4+
# scalafmt
5+
0ad886c35bdf9c8ad2bfb0501070b8b2ce810710

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,10 @@ object Bar {
251251
cumulative: Option[Cumulative] = None,
252252
histfunc: Option[HistFunc] = None,
253253
@since("0.8.2")
254-
hovertemplate: Option[OneOrSeq[String]] = None
254+
hovertemplate: Option[OneOrSeq[String]] = None,
255+
@since("0.8.5")
256+
yaxis: Option[String] = None,
257+
hovertext: Option[OneOrSeq[String]] = None
255258
) extends Trace
256259

257260
object Histogram {

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,10 @@ import plotly.element._
4747
@since("0.8.2")
4848
width: Option[Int] = None,
4949
height: Option[Int] = None,
50-
autosize: Option[Boolean] = None
50+
autosize: Option[Boolean] = None,
51+
@since("0.8.5")
52+
tickformat: Option[String] = None,
53+
fixedrange: Option[Boolean] = None
5154
)
5255

5356
object Axis {

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

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,21 +43,25 @@ import scalatags.JsDom.all.{area => _, _}
4343
heatmaps.CategoricalAxisHeatmap,
4444
heatmaps.CustomColorScaleHeatmap,
4545
heatmaps.AnnotatedHeatmap
46+
),
47+
"Histogram" -> Seq(
48+
histogram.BasicHistogram,
49+
histogram.StyledBasicHistogram
4650
)
4751
)
4852

4953
def unindent(source: String): String = {
5054

51-
val lines = source.linesIterator.toVector
52-
val nonEmptyLines = lines.filter(_.exists(!_.isSpaceChar))
55+
val lines = source.linesIterator.toVector
56+
val nonEmptyLines: Vector[String] = lines.filter(_.exists(!_.isSpaceChar))
5357

5458
if (nonEmptyLines.isEmpty)
5559
source
5660
else {
5761

58-
val dropCount = Stream
62+
val dropCount = LazyList
5963
.from(0)
60-
.takeWhile(idx => nonEmptyLines.forall(_(idx) == nonEmptyLines.head(idx)))
64+
.takeWhile(idx => nonEmptyLines.forall(str => str(idx) == nonEmptyLines.head(idx)))
6165
.lastOption
6266
.fold(0)(_ + 1)
6367

@@ -102,7 +106,7 @@ import scalatags.JsDom.all.{area => _, _}
102106
mainDiv.appendChild(chartTypeElem.render)
103107

104108
for (demo <- chartDemos) {
105-
Console.println(s"Rendering demo ${demo.id}")
109+
Console.println(s" Rendering demo ${demo.id}")
106110

107111
val divId = s"demo-${demo.id}"
108112

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package plotly.demo.histogram
2+
3+
import plotly.Histogram
4+
import plotly.demo.DemoChart
5+
import plotly.layout.Layout
6+
7+
object BasicHistogram extends DemoChart {
8+
9+
def plotlyDocUrl = "https://plotly.com/javascript/histograms/#basic-histogram"
10+
def id = this.getClass.getSimpleName.dropRight(1)
11+
def source = BasicHistogramSource.source
12+
13+
// demo source start
14+
15+
private val categoryCount = 50
16+
17+
private val indices = LazyList.from(0).take(categoryCount)
18+
private val categories = indices.map(i => s"name-$i")
19+
private val values = indices.map(_ => math.random())
20+
21+
val data = Seq(Histogram(values, categories))
22+
23+
val layout = new Layout()
24+
.withTitle(id)
25+
.withShowlegend(false)
26+
.withHeight(400)
27+
.withWidth(600)
28+
29+
// demo source end
30+
31+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package plotly.demo.histogram
2+
3+
import plotly.Histogram
4+
import plotly.demo.DemoChart
5+
import plotly.layout.{Axis, Layout, RangeSlider}
6+
import plotly.element._
7+
8+
object StyledBasicHistogram extends DemoChart {
9+
10+
def plotlyDocUrl = "https://plotly.com/javascript/histograms/#basic-histogram"
11+
def id = this.getClass.getSimpleName.dropRight(1)
12+
def source = StyledBasicHistogramSource.source
13+
14+
// demo source start
15+
16+
private val categoryCount = 50
17+
18+
private val indices = LazyList.from(0).take(categoryCount)
19+
private val categories = indices.map(i => s"name-$i for $id")
20+
private val values = indices.map(_ => math.random())
21+
22+
val data = Seq(
23+
Histogram(values, categories)
24+
.withMarker(new Marker().withColor(Color.StringColor("#004A72")))
25+
.withHovertext(categories.map(c => s"$c with hover text"))
26+
)
27+
28+
val xAxis = new Axis()
29+
.withRange((0d, 2d))
30+
.withRangeslider(RangeSlider())
31+
32+
val yAxis = new Axis()
33+
.withTitle("Count")
34+
.withFixedrange(true)
35+
.withTickformat(".1f")
36+
37+
val layout = new Layout()
38+
.withXaxis(xAxis)
39+
.withYaxis(yAxis)
40+
.withTitle(id)
41+
.withShowlegend(false)
42+
.withHeight(400)
43+
.withWidth(600)
44+
45+
// demo source end
46+
}

project/Deps.scala

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
import sbt._
32

43
import org.portablescala.sbtplatformdeps.PlatformDepsPlugin.autoImport._
@@ -7,15 +6,13 @@ object Deps {
76

87
import Def.setting
98

10-
def almondScalaApi = "sh.almond" %% "jupyter-api" % "0.13.14"
9+
def almondScalaApi = "sh.almond" %% "jupyter-api" % "0.13.14"
1110
def argonautShapeless = setting("com.github.alexarchambault" %%% "argonaut-shapeless_6.3" % "1.3.1")
12-
def dataClass = "io.github.alexarchambault" %% "data-class" % "0.2.6"
13-
def jodaTime = "joda-time" % "joda-time" % "2.12.7"
14-
def rhino = "org.mozilla" % "rhino" % "1.7.14"
15-
def shapeless = setting("com.chuusai" %%% "shapeless" % "2.3.7")
16-
def scalacheckShapeless = setting("com.github.alexarchambault" %%% "scalacheck-shapeless_1.15" % "1.3.0")
17-
def scalajsDom = setting("org.scala-js" %%% "scalajs-dom" % "2.8.0")
18-
def scalatags = setting("com.lihaoyi" %%% "scalatags" % "0.13.1")
19-
def scalaTest = "org.scalatest" %% "scalatest" % "3.2.18"
11+
def dataClass = "io.github.alexarchambault" %% "data-class" % "0.2.6"
12+
def jodaTime = "joda-time" % "joda-time" % "2.12.7"
13+
def rhino = "org.mozilla" % "rhino" % "1.7.15"
14+
def scalajsDom = setting("org.scala-js" %%% "scalajs-dom" % "2.8.0")
15+
def scalatags = setting("com.lihaoyi" %%% "scalatags" % "0.13.1")
16+
def scalaTest = "org.scalatest" %% "scalatest" % "3.2.18"
2017

2118
}

render/js/src/main/scala/plotly/Plotly.scala

Lines changed: 48 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,72 @@
11
package plotly
22

3-
import java.lang.{Boolean => JBoolean, Double => JDouble, Integer => JInt}
4-
53
import argonaut.Argonaut._
6-
import argonaut.{Json, PrettyParams}
4+
import argonaut.{EncodeJson, PrettyParams}
75
import plotly.Codecs._
86
import plotly.element.Color
97
import plotly.internals.BetterPrinter
108
import plotly.layout._
119

10+
import java.lang.{Boolean => JBoolean, Double => JDouble, Integer => JInt}
1211
import scala.scalajs.js
1312
import scala.scalajs.js.Dynamic.{global => g}
1413
import scala.scalajs.js.JSON
1514

1615
object Plotly {
1716

1817
private val printer = BetterPrinter(PrettyParams.nospace.copy(dropNullKeys = true))
19-
private def stripNulls(json: Json): js.Any = {
20-
// Remove empty objects
21-
JSON.parse(printer.render(json))
18+
19+
// Remove empty objects
20+
private def stripNulls[J: EncodeJson](value: J): js.Any = JSON.parse(printer.render(value.asJson))
21+
22+
trait PlotlyDyn {
23+
def plotFn: js.Dynamic
24+
25+
def apply(div: String, data: Seq[Trace], layout: Layout, config: Config): Unit =
26+
plotFn(
27+
div,
28+
stripNulls(data),
29+
stripNulls(layout),
30+
stripNulls(config)
31+
)
32+
33+
def apply(div: String, data: Seq[Trace], layout: Layout): Unit =
34+
plotFn(
35+
div,
36+
stripNulls(data),
37+
stripNulls(layout)
38+
)
39+
40+
def apply(div: String, data: Seq[Trace]): Unit =
41+
plotFn(div, stripNulls(data))
42+
43+
def apply(div: String, data: Trace, layout: Layout): Unit =
44+
plotFn(div, stripNulls(data), stripNulls(layout))
45+
46+
def apply(div: String, data: Trace): Unit =
47+
plotFn(div, stripNulls(data))
2248
}
2349

24-
def plot(div: String, data: Seq[Trace], layout: Layout): Unit = {
25-
g.Plotly.plot(
26-
div,
27-
stripNulls(data.asJson),
28-
stripNulls(layout.asJson)
29-
)
50+
object newPlot extends PlotlyDyn {
51+
val plotFn: js.Dynamic = g.Plotly.newPlot
3052
}
3153

32-
def plot(div: String, data: Seq[Trace]): Unit = {
33-
g.Plotly.plot(
34-
div,
35-
stripNulls(data.asJson)
36-
)
54+
object plot extends PlotlyDyn {
55+
val plotFn: js.Dynamic = g.Plotly.newPlot
3756
}
3857

39-
def plot(div: String, data: Trace, layout: Layout): Unit =
40-
g.Plotly.plot(
41-
div,
42-
stripNulls(data.asJson),
43-
stripNulls(layout.asJson)
44-
)
45-
46-
def plot(div: String, data: Trace): Unit =
47-
g.Plotly.plot(
48-
div,
49-
stripNulls(data.asJson)
50-
)
58+
object react extends PlotlyDyn {
59+
val plotFn: js.Dynamic = g.Plotly.react
60+
}
61+
62+
def relayout(div: String, layout: Layout): Unit =
63+
g.Plotly.relayout(div, stripNulls(layout))
64+
65+
def purge(div: String): Unit =
66+
g.Plotly.purge(div)
67+
68+
def validate(data: Seq[Trace], layout: Layout, config: Config): Unit =
69+
g.Plotly.validate(stripNulls(data), stripNulls(layout))
5170

5271
implicit class TraceOps(val trace: Trace) extends AnyVal {
5372
def plot(div: String, layout: Layout): Unit =

0 commit comments

Comments
 (0)