diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8404cc39..e8069d0e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,10 @@
## [Changes since last release]
+## [0.5.x] - 2018-??-??
+- added a low priority default Theme so this cumbersome import is only necessary when desired
+- added a ExplicitImplicit trait to help library authors catch unintentional implicit theme's
+
## [0.5.0] - 2018-09-21
### Added
- `ComponentGroup` for combining plot components
diff --git a/docs/src/main/tut/getting-started.md b/docs/src/main/tut/getting-started.md
index e04fb53d..9a74da50 100644
--- a/docs/src/main/tut/getting-started.md
+++ b/docs/src/main/tut/getting-started.md
@@ -43,7 +43,6 @@ and take a look at it.
```scala
import com.cibo.evilplot._
import com.cibo.evilplot.plot._
-import com.cibo.evilplot.plot.aesthetics.DefaultTheme._
import com.cibo.evilplot.numeric.Point
val data = Seq.tabulate(100) { i =>
@@ -77,7 +76,6 @@ some labels, so our audience knows what we're talking about. That's easy as well
```scala
import com.cibo.evilplot.plot._
-import com.cibo.evilplot.plot.aesthetics.DefaultTheme._
import com.cibo.evilplot.numeric.Point
val data = Seq.tabulate(100) { i =>
diff --git a/docs/src/main/tut/plot-catalog.md b/docs/src/main/tut/plot-catalog.md
index dbad2885..53a1ca58 100644
--- a/docs/src/main/tut/plot-catalog.md
+++ b/docs/src/main/tut/plot-catalog.md
@@ -293,7 +293,6 @@ A pairs plot can be built by combining `ScatterPlot` and `Histogram` plots with
```scala
import com.cibo.evilplot.numeric.Point
import com.cibo.evilplot.plot._
-import com.cibo.evilplot.plot.aesthetics.DefaultTheme._
import scala.util.Random
val labels = Vector("a", "b", "c", "d")
@@ -332,7 +331,6 @@ A `FunctionPlot` can be used to build density plots.
import com.cibo.evilplot.colors.Color
import com.cibo.evilplot.numeric.Bounds
import com.cibo.evilplot.plot._
-import com.cibo.evilplot.plot.aesthetics.DefaultTheme._
import com.cibo.evilplot.plot.renderers.PathRenderer
import scala.util.Random
@@ -379,7 +377,6 @@ Overlay(
import com.cibo.evilplot.colors.HTMLNamedColors.{green, red}
import com.cibo.evilplot.geometry.Extent
import com.cibo.evilplot.plot._
-import com.cibo.evilplot.plot.aesthetics.DefaultTheme._
import com.cibo.evilplot.plot.renderers.BarRenderer
import scala.util.Random
@@ -408,7 +405,6 @@ Overlay(
```scala
import com.cibo.evilplot.numeric.Point
import com.cibo.evilplot.plot._
-import com.cibo.evilplot.plot.aesthetics.DefaultTheme._
import scala.util.Random
val data = Seq.fill(100) {
diff --git a/docs/src/main/tut/plots.md b/docs/src/main/tut/plots.md
index 349a267f..d71a8661 100644
--- a/docs/src/main/tut/plots.md
+++ b/docs/src/main/tut/plots.md
@@ -37,7 +37,6 @@ A `PointRenderer` tells your plot how to draw the data. When we don't pass one i
import com.cibo.evilplot.numeric.Point
import com.cibo.evilplot.plot._
import com.cibo.evilplot.plot.renderers.PointRenderer
-import com.cibo.evilplot.plot.aesthetics.DefaultTheme._
import scala.util.Random
val qualities = Seq("good", "bad")
diff --git a/docs/src/main/tut/render-context.md b/docs/src/main/tut/render-context.md
index 5454e441..63f5f10c 100644
--- a/docs/src/main/tut/render-context.md
+++ b/docs/src/main/tut/render-context.md
@@ -18,7 +18,6 @@ Started page using `CanvasRenderContext`.
```scala
import com.cibo.evilplot.geometry.{CanvasRenderContext, Extent}
import com.cibo.evilplot.plot._
-import com.cibo.evilplot.plot.aesthetics.DefaultTheme._
import com.cibo.evilplot.numeric.Point
import org.scalajs.dom
diff --git a/shared/src/main/scala/com/cibo/evilplot/plot/BarChart.scala b/shared/src/main/scala/com/cibo/evilplot/plot/BarChart.scala
index 37b4e1fe..378150cc 100644
--- a/shared/src/main/scala/com/cibo/evilplot/plot/BarChart.scala
+++ b/shared/src/main/scala/com/cibo/evilplot/plot/BarChart.scala
@@ -61,13 +61,13 @@ final case class Bar(
)
}
-object Bar {
+object Bar extends ExplicitImplicits{
def apply(value: Double)(implicit theme: Theme): Bar = Bar(Seq(value), 0, theme.colors.stream)
def apply(value: Double, cluster: Int)(implicit theme: Theme): Bar =
Bar(Seq(value), cluster = cluster, theme.colors.stream)
}
-object BarChart {
+object BarChart extends ExplicitImplicits{
val defaultBoundBuffer: Double = 0.1
@@ -151,9 +151,9 @@ object BarChart {
spacing: Option[Double] = None,
boundBuffer: Option[Double] = None
)(implicit theme: Theme): Plot = {
- val barRenderer = BarRenderer.default(color)
- val bars = values.map(Bar(_))
- custom(bars, Some(barRenderer), spacing, None, boundBuffer)
+ val barRenderer = BarRenderer.default(color)(theme)
+ val bars = values.map(Bar(_)(theme))
+ custom(bars, Some(barRenderer), spacing, None, boundBuffer)(theme)
}
/** Create a bar chart where bars are divided into clusters. */
@@ -195,7 +195,7 @@ object BarChart {
Some(barRenderer),
spacing,
Some(clusterSpacing.getOrElse(theme.elements.clusterSpacing)),
- boundBuffer)
+ boundBuffer)(theme)
}
/** Create a stacked bar chart.
@@ -220,7 +220,7 @@ object BarChart {
val bars = values.map { stack =>
Bar(stack, colors = colorStream, labels = barLabels, cluster = 0)
}
- custom(bars, Some(barRenderer), spacing, None, boundBuffer)
+ custom(bars, Some(barRenderer), spacing, None, boundBuffer)(theme)
}
/** Create a clustered bar chart of stacked bars.
@@ -261,7 +261,7 @@ object BarChart {
Some(barRenderer),
spacing,
Some(clusterSpacing.getOrElse(theme.elements.clusterSpacing)),
- boundBuffer)
+ boundBuffer)(theme)
}
/** Create a custom bar chart.
@@ -292,7 +292,7 @@ object BarChart {
ybounds,
BarChartRenderer(
bars,
- barRenderer.getOrElse(BarRenderer.default()),
+ barRenderer.getOrElse(BarRenderer.default()(theme)),
spacing.getOrElse(theme.elements.barSpacing),
clusterSpacing
)
diff --git a/shared/src/main/scala/com/cibo/evilplot/plot/BoxPlot.scala b/shared/src/main/scala/com/cibo/evilplot/plot/BoxPlot.scala
index e213d85e..d02131dc 100644
--- a/shared/src/main/scala/com/cibo/evilplot/plot/BoxPlot.scala
+++ b/shared/src/main/scala/com/cibo/evilplot/plot/BoxPlot.scala
@@ -42,7 +42,7 @@ final case class BoxPlotRenderer(
pointRenderer: PointRenderer,
spacing: Double,
clusterSpacing: Option[Double]
-) extends PlotRenderer {
+) extends PlotRenderer with ExplicitImplicits{
private val isClustered = clusterSpacing.isDefined
private val clusterPadding = clusterSpacing.getOrElse(spacing)
@@ -106,7 +106,7 @@ final case class BoxPlotRenderer(
override def legendContext: LegendContext = boxRenderer.legendContext
}
-object BoxPlot {
+object BoxPlot extends ExplicitImplicits{
/** Create box plots for a sequence of distributions.
*
@@ -141,7 +141,7 @@ object BoxPlot {
boundBuffer,
boxRenderer,
pointRenderer
- )
+ )(theme)
}
@@ -185,7 +185,7 @@ object BoxPlot {
boundBuffer,
boxRenderer,
pointRenderer
- )
+ )(theme)
}
private def makePlot(
@@ -210,8 +210,8 @@ object BoxPlot {
ybounds,
BoxPlotRenderer(
boxContexts,
- boxRenderer.getOrElse(BoxRenderer.default()),
- pointRenderer.getOrElse(PointRenderer.default()),
+ boxRenderer.getOrElse(BoxRenderer.default()(theme)),
+ pointRenderer.getOrElse(PointRenderer.default()(theme)),
spacing.getOrElse(theme.elements.boxSpacing),
clusterSpacing
)
@@ -236,6 +236,6 @@ object BoxPlot {
spacing: Option[Double] = None,
boundBuffer: Option[Double] = None
)(implicit theme: Theme): Plot = {
- apply(data, quantiles, spacing, boundBuffer, Some(boxRenderer), Some(pointRenderer))
+ apply(data, quantiles, spacing, boundBuffer, Some(boxRenderer), Some(pointRenderer))(theme)
}
}
diff --git a/shared/src/main/scala/com/cibo/evilplot/plot/ExplicitImplicits.scala b/shared/src/main/scala/com/cibo/evilplot/plot/ExplicitImplicits.scala
new file mode 100644
index 00000000..97fc372b
--- /dev/null
+++ b/shared/src/main/scala/com/cibo/evilplot/plot/ExplicitImplicits.scala
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2018, CiBO Technologies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.cibo.evilplot.plot
+
+import com.cibo.evilplot.plot.aesthetics.{Theme, DefaultTheme}
+
+trait ExplicitImplicits{
+ implicit val defaultTheme: Theme = DefaultTheme.defaultTheme
+}
diff --git a/shared/src/main/scala/com/cibo/evilplot/plot/Facets.scala b/shared/src/main/scala/com/cibo/evilplot/plot/Facets.scala
index 8fb0aec1..e3b08858 100644
--- a/shared/src/main/scala/com/cibo/evilplot/plot/Facets.scala
+++ b/shared/src/main/scala/com/cibo/evilplot/plot/Facets.scala
@@ -77,7 +77,7 @@ object Facets {
row.zipWithIndex.map {
case (subplot, xIndex) =>
val x = xIndex * innerExtent.width
- subplot.render(innerExtent).translate(x = x, y = y)
+ subplot.render(innerExtent)(theme).translate(x = x, y = y)
}.group
}.group
}
diff --git a/shared/src/main/scala/com/cibo/evilplot/plot/FunctionPlot.scala b/shared/src/main/scala/com/cibo/evilplot/plot/FunctionPlot.scala
index fb16f82e..c26bc3eb 100644
--- a/shared/src/main/scala/com/cibo/evilplot/plot/FunctionPlot.scala
+++ b/shared/src/main/scala/com/cibo/evilplot/plot/FunctionPlot.scala
@@ -37,7 +37,7 @@ import com.cibo.evilplot.plot.aesthetics.Theme
import com.cibo.evilplot.plot.components.FunctionPlotLine
import com.cibo.evilplot.plot.renderers.{PathRenderer, PointRenderer}
-object FunctionPlot {
+object FunctionPlot extends ExplicitImplicits{
val defaultBounds: Bounds = Bounds(0, 1)
val defaultNumPoints: Int = 800
@@ -66,7 +66,7 @@ object FunctionPlot {
pointRenderer.orElse(Some(PointRenderer.empty())),
pathRenderer,
xBoundBuffer,
- yBoundBuffer)
+ yBoundBuffer)(theme)
}
/** Plot a function using a name for the legend.
@@ -85,8 +85,8 @@ object FunctionPlot {
xBoundBuffer: Option[Double] = None,
yBoundBuffer: Option[Double] = None
)(implicit theme: Theme): Plot = {
- val renderer = Some(PathRenderer.named(name, color, strokeWidth))
- apply(function, xbounds, numPoints, renderer, None, xBoundBuffer, yBoundBuffer)
+ val renderer = Some(PathRenderer.named(name, color, strokeWidth)(theme))
+ apply(function, xbounds, numPoints, renderer, None, xBoundBuffer, yBoundBuffer)(theme)
}
/** Plot a function using a name for the legend.
@@ -104,7 +104,7 @@ object FunctionPlot {
strokeWidth: Option[Double],
xBoundBuffer: Option[Double],
yBoundBuffer: Option[Double])(implicit theme: Theme): Plot = {
- val renderer = Some(PathRenderer.default(strokeWidth, Some(color), label))
- apply(function, xbounds, numPoints, renderer, None, xBoundBuffer, yBoundBuffer)
+ val renderer = Some(PathRenderer.default(strokeWidth, Some(color), label)(theme))
+ apply(function, xbounds, numPoints, renderer, None, xBoundBuffer, yBoundBuffer)(theme)
}
}
diff --git a/shared/src/main/scala/com/cibo/evilplot/plot/Heatmap.scala b/shared/src/main/scala/com/cibo/evilplot/plot/Heatmap.scala
index c79159c2..de617e94 100644
--- a/shared/src/main/scala/com/cibo/evilplot/plot/Heatmap.scala
+++ b/shared/src/main/scala/com/cibo/evilplot/plot/Heatmap.scala
@@ -36,7 +36,7 @@ import com.cibo.evilplot.numeric.Bounds
import com.cibo.evilplot.plot.aesthetics.Theme
import com.cibo.evilplot.plot.renderers.PlotRenderer
-object Heatmap {
+object Heatmap extends ExplicitImplicits{
val defaultColorCount: Int = 10
@@ -80,7 +80,7 @@ object Heatmap {
ybounds = ybounds,
xfixed = true,
yfixed = true,
- renderer = HeatmapRenderer(data, colorBar)
+ renderer = HeatmapRenderer(data, colorBar)(theme)
)
}
@@ -99,7 +99,7 @@ object Heatmap {
val minValue = flattenedData.reduceOption[Double](math.min).getOrElse(0.0)
val maxValue = flattenedData.reduceOption[Double](math.max).getOrElse(0.0)
val colorBar = ScaledColorBar(colorStream.take(colorCount), minValue, maxValue)
- apply(data, colorBar)
+ apply(data, colorBar)(theme)
}
def apply(data: Seq[Seq[Double]],
@@ -108,9 +108,9 @@ object Heatmap {
val minValue = flattenedData.reduceOption[Double](math.min).getOrElse(0.0)
val maxValue = flattenedData.reduceOption[Double](math.max).getOrElse(0.0)
val useColoring = coloring.getOrElse(theme.colors.continuousColoring)
- val colorFunc = useColoring(flattenedData)
+ val colorFunc = useColoring(flattenedData)(theme)
val colorBar = ScaledColorBar(flattenedData.map(point => colorFunc.apply(point)), minValue, maxValue)
- apply(data, colorBar)
+ apply(data, colorBar)(theme)
}
}
diff --git a/shared/src/main/scala/com/cibo/evilplot/plot/Histogram.scala b/shared/src/main/scala/com/cibo/evilplot/plot/Histogram.scala
index 2589181b..6fa845ec 100644
--- a/shared/src/main/scala/com/cibo/evilplot/plot/Histogram.scala
+++ b/shared/src/main/scala/com/cibo/evilplot/plot/Histogram.scala
@@ -35,7 +35,7 @@ import com.cibo.evilplot.numeric.{Bounds, Point}
import com.cibo.evilplot.plot.aesthetics.Theme
import com.cibo.evilplot.plot.renderers.{BarRenderer, PlotRenderer}
-object Histogram {
+object Histogram extends ExplicitImplicits{
val defaultBinCount: Int = 20
@@ -128,7 +128,7 @@ object Histogram {
val clippedY = math.min(point.y * yscale, plot.ybounds.max)
val y = ytransformer(clippedY)
val barWidth = math.max(xtransformer(point.x + binWidth) - x - spacing, 0)
- val bar = Bar(clippedY)
+ val bar = Bar(clippedY)(theme)
val barHeight = yintercept - y
barRenderer.render(plot, Extent(barWidth, barHeight), bar).translate(x = x, y = y)
}.group
@@ -173,7 +173,7 @@ object Histogram {
ybounds = Bounds(0, maxY * (1.0 + boundBuffer.getOrElse(theme.elements.boundBuffer))),
renderer = HistogramRenderer(
values,
- barRenderer.getOrElse(BarRenderer.default()),
+ barRenderer.getOrElse(BarRenderer.default()(theme)),
bins,
spacing.getOrElse(theme.elements.barSpacing),
boundBuffer.getOrElse(theme.elements.boundBuffer),
diff --git a/shared/src/main/scala/com/cibo/evilplot/plot/LegendContext.scala b/shared/src/main/scala/com/cibo/evilplot/plot/LegendContext.scala
index a0217537..c791baad 100644
--- a/shared/src/main/scala/com/cibo/evilplot/plot/LegendContext.scala
+++ b/shared/src/main/scala/com/cibo/evilplot/plot/LegendContext.scala
@@ -68,7 +68,7 @@ case class LegendContext(
}
}
-object LegendContext {
+object LegendContext extends ExplicitImplicits{
def empty: LegendContext = LegendContext()
def single(
diff --git a/shared/src/main/scala/com/cibo/evilplot/plot/LinePlot.scala b/shared/src/main/scala/com/cibo/evilplot/plot/LinePlot.scala
index ae45ed8f..f904e506 100644
--- a/shared/src/main/scala/com/cibo/evilplot/plot/LinePlot.scala
+++ b/shared/src/main/scala/com/cibo/evilplot/plot/LinePlot.scala
@@ -36,7 +36,7 @@ import com.cibo.evilplot.numeric.Point
import com.cibo.evilplot.plot.aesthetics.Theme
import com.cibo.evilplot.plot.renderers.{PathRenderer, PointRenderer}
-object LinePlot {
+object LinePlot extends ExplicitImplicits{
/** Create a line plot from some data. Convenience method on top of XyPlot
*
@@ -56,10 +56,10 @@ object LinePlot {
XyPlot(
data,
pointRenderer = Some(pointRenderer.getOrElse(PointRenderer.empty())),
- pathRenderer = Some(pathRenderer.getOrElse(PathRenderer.default())),
+ pathRenderer = Some(pathRenderer.getOrElse(PathRenderer.default()(theme))),
xboundBuffer.orElse(Some(0)),
yboundBuffer
- )
+ )(theme)
}
/** Create a line plot from some data. Convenience method on top of XyPlot
@@ -78,7 +78,7 @@ object LinePlot {
xboundBuffer: Double,
yboundBuffer: Double
)(implicit theme: Theme): Plot = {
- XyPlot(data, Some(pointRenderer), Some(pathRenderer), Some(xboundBuffer), Some(yboundBuffer))
+ XyPlot(data, Some(pointRenderer), Some(pathRenderer), Some(xboundBuffer), Some(yboundBuffer))(theme)
}
/** Create a line plot with the specified name and color.
@@ -98,14 +98,14 @@ object LinePlot {
yboundBuffer: Option[Double] = None
)(implicit theme: Theme): Plot = {
val pointRenderer = PointRenderer.empty()
- val pathRenderer = PathRenderer.named(name, color, strokeWidth)
+ val pathRenderer = PathRenderer.named(name, color, strokeWidth)(theme)
XyPlot(
data,
Some(pointRenderer),
Some(pathRenderer),
xboundBuffer,
yboundBuffer
- )
+ )(theme)
}
/** Create a line plot with the specified name and color.
@@ -125,7 +125,7 @@ object LinePlot {
yboundBuffer: Option[Double]
)(implicit theme: Theme): Plot = {
val pointRenderer = PointRenderer.empty()
- val pathRenderer = PathRenderer.default(strokeWidth, Some(color), label)
- XyPlot(data, Some(pointRenderer), Some(pathRenderer), xboundBuffer, yboundBuffer)
+ val pathRenderer = PathRenderer.default(strokeWidth, Some(color), label)(theme)
+ XyPlot(data, Some(pointRenderer), Some(pathRenderer), xboundBuffer, yboundBuffer)(theme)
}
}
diff --git a/shared/src/main/scala/com/cibo/evilplot/plot/MixedBoundsOverlay.scala b/shared/src/main/scala/com/cibo/evilplot/plot/MixedBoundsOverlay.scala
index 12d49828..c348b091 100644
--- a/shared/src/main/scala/com/cibo/evilplot/plot/MixedBoundsOverlay.scala
+++ b/shared/src/main/scala/com/cibo/evilplot/plot/MixedBoundsOverlay.scala
@@ -41,7 +41,7 @@ object MixedBoundsOverlay {
override def legendContext: LegendContext =
LegendContext.combine(subplots.map(_.renderer.legendContext))
def render(plot: Plot, plotExtent: Extent)(implicit theme: Theme): Drawable =
- Plot.padPlots(Seq(subplots), plotExtent, 0, 0).head.map(_.render(plotExtent)).group
+ Plot.padPlots(Seq(subplots), plotExtent, 0, 0).head.map(_.render(plotExtent)(theme)).group
}
/** Overlay plots without updating bounds or transforms for individual plots.
diff --git a/shared/src/main/scala/com/cibo/evilplot/plot/Overlay.scala b/shared/src/main/scala/com/cibo/evilplot/plot/Overlay.scala
index b3d2cb48..751e8a8d 100644
--- a/shared/src/main/scala/com/cibo/evilplot/plot/Overlay.scala
+++ b/shared/src/main/scala/com/cibo/evilplot/plot/Overlay.scala
@@ -35,7 +35,7 @@ import com.cibo.evilplot.numeric.Bounds
import com.cibo.evilplot.plot.aesthetics.Theme
import com.cibo.evilplot.plot.renderers.PlotRenderer
-object Overlay {
+object Overlay extends ExplicitImplicits{
// Update subplots to have the specified bounds (if not already fixed).
private def updateSubplotBounds(
@@ -71,7 +71,7 @@ object Overlay {
xbounds = plot.xbounds,
ybounds = plot.ybounds
)
- updatedPlots.map(_.render(plotExtent)).group
+ updatedPlots.map(_.render(plotExtent)(theme)).group
}
}
diff --git a/shared/src/main/scala/com/cibo/evilplot/plot/PieChart.scala b/shared/src/main/scala/com/cibo/evilplot/plot/PieChart.scala
index dd64ca0e..354fa958 100644
--- a/shared/src/main/scala/com/cibo/evilplot/plot/PieChart.scala
+++ b/shared/src/main/scala/com/cibo/evilplot/plot/PieChart.scala
@@ -36,7 +36,7 @@ import com.cibo.evilplot.numeric.Bounds
import com.cibo.evilplot.plot.aesthetics.Theme
import com.cibo.evilplot.plot.renderers.PlotRenderer
-object PieChart {
+object PieChart extends ExplicitImplicits{
case class PieChartRenderer(
data: Seq[(Drawable, Double)],
diff --git a/shared/src/main/scala/com/cibo/evilplot/plot/Plot.scala b/shared/src/main/scala/com/cibo/evilplot/plot/Plot.scala
index 059c2931..df821593 100644
--- a/shared/src/main/scala/com/cibo/evilplot/plot/Plot.scala
+++ b/shared/src/main/scala/com/cibo/evilplot/plot/Plot.scala
@@ -57,7 +57,7 @@ final case class Plot(
xfixed: Boolean = false,
yfixed: Boolean = false,
components: Seq[FacetedPlotComponent] = Seq.empty
-) {
+) extends ExplicitImplicits{
private[plot] def inBounds(point: Point): Boolean =
xbounds.isInBounds(point.x) && ybounds.isInBounds(point.y)
@@ -135,11 +135,11 @@ final case class Plot(
* @param extent the desired size of the resulting Drawable
*/
def render(extent: Extent = Plot.defaultExtent)(implicit theme: Theme): Drawable = {
- val overlays = componentRenderer.renderFront(this, extent)
- val backgrounds = componentRenderer.renderBack(this, extent)
+ val overlays = componentRenderer.renderFront(this, extent)(theme)
+ val backgrounds = componentRenderer.renderBack(this, extent)(theme)
val pextent = plotExtent(extent)
val renderedPlot =
- renderer.render(this, pextent).resize(pextent).translate(x = plotOffset.x, y = plotOffset.y)
+ renderer.render(this, pextent)(theme).resize(pextent).translate(x = plotOffset.x, y = plotOffset.y)
backgrounds behind renderedPlot behind overlays
}
}
diff --git a/shared/src/main/scala/com/cibo/evilplot/plot/ScatterPlot.scala b/shared/src/main/scala/com/cibo/evilplot/plot/ScatterPlot.scala
index 1bc3a804..a5068857 100644
--- a/shared/src/main/scala/com/cibo/evilplot/plot/ScatterPlot.scala
+++ b/shared/src/main/scala/com/cibo/evilplot/plot/ScatterPlot.scala
@@ -36,7 +36,7 @@ import com.cibo.evilplot.numeric.Point
import com.cibo.evilplot.plot.aesthetics.Theme
import com.cibo.evilplot.plot.renderers.{PathRenderer, PointRenderer}
-object ScatterPlot {
+object ScatterPlot extends ExplicitImplicits{
/** Create a scatter plot from some data.
* @param data The points to plot.
@@ -49,7 +49,7 @@ object ScatterPlot {
pointRenderer: Option[PointRenderer] = None,
boundBuffer: Option[Double] = None
)(implicit theme: Theme): Plot = {
- XyPlot(data, pointRenderer, Some(PathRenderer.empty()), boundBuffer, boundBuffer)
+ XyPlot(data, pointRenderer, Some(PathRenderer.empty()), boundBuffer, boundBuffer)(theme)
}
/** Create a scatter plot with the specified name and color.
@@ -74,7 +74,7 @@ object ScatterPlot {
color,
pointSize,
boundBuffer
- )
+ )(theme)
/** Create a scatter plot with the specified name and color.
* @param data The points to plot.
@@ -90,8 +90,8 @@ object ScatterPlot {
pointSize: Option[Double],
boundBuffer: Option[Double]
)(implicit theme: Theme): Plot = {
- val pointRenderer = PointRenderer.default(Some(color), pointSize, name)
+ val pointRenderer = PointRenderer.default(Some(color), pointSize, name)(theme)
val pathRenderer = PathRenderer.empty()
- XyPlot(data, Some(pointRenderer), Some(pathRenderer), boundBuffer, boundBuffer)
+ XyPlot(data, Some(pointRenderer), Some(pathRenderer), boundBuffer, boundBuffer)(theme)
}
}
diff --git a/shared/src/main/scala/com/cibo/evilplot/plot/SurfacePlot.scala b/shared/src/main/scala/com/cibo/evilplot/plot/SurfacePlot.scala
index 370e24ea..028b7e94 100644
--- a/shared/src/main/scala/com/cibo/evilplot/plot/SurfacePlot.scala
+++ b/shared/src/main/scala/com/cibo/evilplot/plot/SurfacePlot.scala
@@ -36,7 +36,7 @@ import com.cibo.evilplot.plot.aesthetics.Theme
import com.cibo.evilplot.plot.renderers.SurfaceRenderer.SurfaceRenderContext
import com.cibo.evilplot.plot.renderers.{PlotRenderer, SurfaceRenderer}
-object SurfacePlot {
+object SurfacePlot extends ExplicitImplicits{
private[plot] case class SurfacePlotRenderer(
data: Seq[Seq[Seq[Point3]]],
surfaceRenderer: SurfaceRenderer
@@ -72,7 +72,7 @@ object SurfacePlot {
}
}
-object ContourPlot {
+object ContourPlot extends ExplicitImplicits{
import SurfacePlot._
val defaultGridDimensions: (Int, Int) = (100, 100)
@@ -120,7 +120,7 @@ object ContourPlot {
}
}
- val sr = surfaceRenderer.getOrElse(SurfaceRenderer.densityColorContours())
+ val sr = surfaceRenderer.getOrElse(SurfaceRenderer.densityColorContours()(theme))
Plot(
xbounds,
ybounds,
diff --git a/shared/src/main/scala/com/cibo/evilplot/plot/XyPlot.scala b/shared/src/main/scala/com/cibo/evilplot/plot/XyPlot.scala
index 1bfd21ba..44640026 100644
--- a/shared/src/main/scala/com/cibo/evilplot/plot/XyPlot.scala
+++ b/shared/src/main/scala/com/cibo/evilplot/plot/XyPlot.scala
@@ -35,7 +35,7 @@ import com.cibo.evilplot.numeric.{Bounds, Point}
import com.cibo.evilplot.plot.aesthetics.Theme
import com.cibo.evilplot.plot.renderers.{PathRenderer, PlotRenderer, PointRenderer}
-object XyPlot {
+object XyPlot extends ExplicitImplicits{
final case class XyPlotRenderer(
data: Seq[Point],
@@ -104,8 +104,8 @@ object XyPlot {
ybounds,
XyPlotRenderer(
data,
- pointRenderer.getOrElse(PointRenderer.default()),
- pathRenderer.getOrElse(PathRenderer.default()))
+ pointRenderer.getOrElse(PointRenderer.default()(theme)),
+ pathRenderer.getOrElse(PathRenderer.default()(theme)))
)
}
}
diff --git a/shared/src/main/scala/com/cibo/evilplot/plot/aesthetics/DefaultTheme.scala b/shared/src/main/scala/com/cibo/evilplot/plot/aesthetics/DefaultTheme.scala
index 2ea23641..5b9efaa5 100644
--- a/shared/src/main/scala/com/cibo/evilplot/plot/aesthetics/DefaultTheme.scala
+++ b/shared/src/main/scala/com/cibo/evilplot/plot/aesthetics/DefaultTheme.scala
@@ -34,7 +34,7 @@ import com.cibo.evilplot.colors._
import com.cibo.evilplot.colors.ContinuousColoring.gradient
import com.cibo.evilplot.geometry.LineStyle
-object DefaultTheme {
+object DefaultTheme{
private val darkGray: HSLA = HSLA(0, 0, 12, 1.0)
private val lightGray: HSLA = HSLA(0, 0, 65, 0.8)
private val darkBlue: HSLA = HSLA(211, 38, 48, 1.0)
@@ -108,6 +108,5 @@ object DefaultTheme {
elements = DefaultElements
)
- implicit val defaultTheme: Theme = DefaultTheme
-
+ implicit val defaultTheme: Theme = this.DefaultTheme
}
diff --git a/shared/src/main/scala/com/cibo/evilplot/plot/aesthetics/Theme.scala b/shared/src/main/scala/com/cibo/evilplot/plot/aesthetics/Theme.scala
index 7060b143..74a42cf6 100644
--- a/shared/src/main/scala/com/cibo/evilplot/plot/aesthetics/Theme.scala
+++ b/shared/src/main/scala/com/cibo/evilplot/plot/aesthetics/Theme.scala
@@ -44,3 +44,14 @@ final case class Theme(
colors: Colors,
elements: Elements
)
+
+object Theme {
+
+ /**An automatic default theme at a low priority precedence*/
+ implicit val default:Theme = DefaultTheme.defaultTheme
+ // /**An automatic default theme at a low priority precedence*/
+ // implicit val default:Theme = Default.theme
+
+ /**A simpler constructor for a classic Theme without requiring the entire Classic import */
+ val classic:Theme = ClassicTheme.classicTheme
+}
diff --git a/shared/src/main/scala/com/cibo/evilplot/plot/components/Background.scala b/shared/src/main/scala/com/cibo/evilplot/plot/components/Background.scala
index b8d0ea9d..51d428d5 100644
--- a/shared/src/main/scala/com/cibo/evilplot/plot/components/Background.scala
+++ b/shared/src/main/scala/com/cibo/evilplot/plot/components/Background.scala
@@ -34,6 +34,7 @@ import com.cibo.evilplot.colors.Color
import com.cibo.evilplot.geometry.{Drawable, Extent, Line, Rect, StrokeStyle}
import com.cibo.evilplot.plot.Plot
import com.cibo.evilplot.plot.aesthetics.Theme
+import com.cibo.evilplot.plot.ExplicitImplicits
final case class Background(
f: (Plot, Extent) => Drawable
@@ -43,7 +44,7 @@ final case class Background(
def render(plot: Plot, extent: Extent)(implicit theme: Theme): Drawable = f(plot, extent)
}
-trait BackgroundImplicits {
+trait BackgroundImplicits extends ExplicitImplicits{
protected val plot: Plot
/** Set the background (this will replace any existing background).
diff --git a/shared/src/main/scala/com/cibo/evilplot/plot/components/BorderPlot.scala b/shared/src/main/scala/com/cibo/evilplot/plot/components/BorderPlot.scala
index f47a1780..8cb52730 100644
--- a/shared/src/main/scala/com/cibo/evilplot/plot/components/BorderPlot.scala
+++ b/shared/src/main/scala/com/cibo/evilplot/plot/components/BorderPlot.scala
@@ -46,13 +46,13 @@ case class BorderPlot(
border
.xbounds(plot.xbounds)
.copy(xtransform = plot.xtransform)
- .render(extent.copy(height = borderSize))
+ .render(extent.copy(height = borderSize))(theme)
case Position.Bottom =>
val borderExent = extent.copy(height = borderSize)
border
.xbounds(plot.xbounds)
.copy(xtransform = plot.xtransform)
- .render(borderExent)
+ .render(borderExent)(theme)
.rotated(180)
.flipX
case Position.Left =>
@@ -60,7 +60,7 @@ case class BorderPlot(
border
.xbounds(plot.ybounds)
.copy(xtransform = plot.xtransform)
- .render(borderExtent)
+ .render(borderExtent)(theme)
.resize(borderExtent)
.rotated(270)
case Position.Right =>
@@ -68,12 +68,12 @@ case class BorderPlot(
border
.xbounds(plot.ybounds)
.copy(xtransform = plot.xtransform)
- .render(borderExtent)
+ .render(borderExtent)(theme)
.resize(borderExtent)
.rotated(90)
.flipY
case _ =>
- border.render(extent)
+ border.render(extent)(theme)
}
}
}
diff --git a/shared/src/main/scala/com/cibo/evilplot/plot/components/FacetedPlotComponent.scala b/shared/src/main/scala/com/cibo/evilplot/plot/components/FacetedPlotComponent.scala
index 1a08fa4e..bc188940 100644
--- a/shared/src/main/scala/com/cibo/evilplot/plot/components/FacetedPlotComponent.scala
+++ b/shared/src/main/scala/com/cibo/evilplot/plot/components/FacetedPlotComponent.scala
@@ -33,9 +33,10 @@ package com.cibo.evilplot.plot.components
import com.cibo.evilplot.geometry.{Drawable, Extent}
import com.cibo.evilplot.plot.Plot
import com.cibo.evilplot.plot.aesthetics.Theme
+import com.cibo.evilplot.plot.ExplicitImplicits
/** A component that is aligned with the data of a plot. */
-trait FacetedPlotComponent {
+trait FacetedPlotComponent extends ExplicitImplicits{
/** The position of this component. */
val position: Position
diff --git a/shared/src/main/scala/com/cibo/evilplot/plot/components/Label.scala b/shared/src/main/scala/com/cibo/evilplot/plot/components/Label.scala
index b0f84347..e0ebc2cb 100644
--- a/shared/src/main/scala/com/cibo/evilplot/plot/components/Label.scala
+++ b/shared/src/main/scala/com/cibo/evilplot/plot/components/Label.scala
@@ -34,6 +34,7 @@ import com.cibo.evilplot.colors.{Color, HTMLNamedColors}
import com.cibo.evilplot.geometry.{Drawable, Extent, StrokeStyle, Style, Text}
import com.cibo.evilplot.plot.aesthetics.Theme
import com.cibo.evilplot.plot.Plot
+import com.cibo.evilplot.plot.ExplicitImplicits
/** A plot label.
* @param position The position of this component.
@@ -44,7 +45,7 @@ case class Label(
position: Position,
f: Extent => Drawable,
minExtent: Extent
-) extends PlotComponent {
+) extends PlotComponent with ExplicitImplicits{
override def size(plot: Plot): Extent = minExtent
def render(plot: Plot, extent: Extent)(implicit theme: Theme): Drawable = position match {
case Position.Top => f(extent).center(extent.width)
@@ -59,7 +60,7 @@ object Label {
def apply(position: Position, d: Drawable): Label = Label(position, _ => d, d.extent)
}
-trait LabelImplicits {
+trait LabelImplicits extends ExplicitImplicits{
protected val plot: Plot
def title(d: Drawable): Plot = plot :+ Label(Position.Top, d)
@@ -138,12 +139,12 @@ trait LabelImplicits {
label: String,
size: Option[Double] = None,
color: Option[Color] = None
- )(implicit theme: Theme): Plot = bottomLabel(label, size, color)
+ )(implicit theme: Theme): Plot = bottomLabel(label, size, color)(theme)
def yLabel(d: Drawable): Plot = leftLabel(d)
def yLabel(
label: String,
size: Option[Double] = None,
color: Option[Color] = None
- )(implicit theme: Theme): Plot = leftLabel(label, size, color)
+ )(implicit theme: Theme): Plot = leftLabel(label, size, color)(theme)
}
diff --git a/shared/src/main/scala/com/cibo/evilplot/plot/components/Legend.scala b/shared/src/main/scala/com/cibo/evilplot/plot/components/Legend.scala
index cdcda9a2..936440a6 100644
--- a/shared/src/main/scala/com/cibo/evilplot/plot/components/Legend.scala
+++ b/shared/src/main/scala/com/cibo/evilplot/plot/components/Legend.scala
@@ -34,6 +34,7 @@ import com.cibo.evilplot.geometry._
import com.cibo.evilplot.plot.aesthetics.Theme
import com.cibo.evilplot.plot.renderers.LegendRenderer
import com.cibo.evilplot.plot.{LegendContext, Plot}
+import com.cibo.evilplot.plot.ExplicitImplicits
case class Legend(
position: Position,
@@ -55,7 +56,7 @@ case class Legend(
}
}
-trait LegendImplicits {
+trait LegendImplicits extends ExplicitImplicits{
protected val plot: Plot
private def setLegend(
@@ -87,25 +88,25 @@ trait LegendImplicits {
def rightLegend(
renderer: LegendRenderer = LegendRenderer.vertical(),
labels: Option[Seq[String]] = None
- )(implicit theme: Theme): Plot = setLegend(Position.Right, renderer, 0, 0.5, labels)
+ )(implicit theme: Theme): Plot = setLegend(Position.Right, renderer, 0, 0.5, labels)(theme)
/** Place a legend on the left side of the plot. */
def leftLegend(
renderer: LegendRenderer = LegendRenderer.vertical(),
labels: Option[Seq[String]] = None
- )(implicit theme: Theme): Plot = setLegend(Position.Left, renderer, 0, 0.5, labels)
+ )(implicit theme: Theme): Plot = setLegend(Position.Left, renderer, 0, 0.5, labels)(theme)
/** Place a legend on the top of the plot. */
def topLegend(
renderer: LegendRenderer = LegendRenderer.horizontal(),
labels: Option[Seq[String]] = None
- )(implicit theme: Theme): Plot = setLegend(Position.Top, renderer, 0.5, 0, labels)
+ )(implicit theme: Theme): Plot = setLegend(Position.Top, renderer, 0.5, 0, labels)(theme)
/** Place a legend on the bottom of the plot. */
def bottomLegend(
renderer: LegendRenderer = LegendRenderer.horizontal(),
labels: Option[Seq[String]] = None
- )(implicit theme: Theme): Plot = setLegend(Position.Bottom, renderer, 0.5, 0, labels)
+ )(implicit theme: Theme): Plot = setLegend(Position.Bottom, renderer, 0.5, 0, labels)(theme)
/** Overlay a legend on the plot.
* @param x The relative X position (0 to 1).
@@ -117,7 +118,7 @@ trait LegendImplicits {
y: Double = 0.0,
renderer: LegendRenderer = LegendRenderer.vertical(),
labels: Option[Seq[String]] = None
- )(implicit theme: Theme): Plot = setLegend(Position.Overlay, renderer, x, y, labels)
+ )(implicit theme: Theme): Plot = setLegend(Position.Overlay, renderer, x, y, labels)(theme)
/** Get the legend as a drawable. */
def renderLegend(
@@ -125,6 +126,6 @@ trait LegendImplicits {
)(implicit theme: Theme): Option[Drawable] =
if (plot.renderer.legendContext.nonEmpty) {
val legend = Legend(Position.Right, plot.renderer.legendContext, renderer, 0, 0)
- Some(legend.render(plot, legend.size(plot)))
+ Some(legend.render(plot, legend.size(plot))(theme))
} else None
}
diff --git a/shared/src/main/scala/com/cibo/evilplot/plot/components/PlotComponent.scala b/shared/src/main/scala/com/cibo/evilplot/plot/components/PlotComponent.scala
index e197d5bd..5ae38992 100644
--- a/shared/src/main/scala/com/cibo/evilplot/plot/components/PlotComponent.scala
+++ b/shared/src/main/scala/com/cibo/evilplot/plot/components/PlotComponent.scala
@@ -35,7 +35,7 @@ import com.cibo.evilplot.plot.Plot
import com.cibo.evilplot.plot.aesthetics.Theme
/** A component that is aligned with the data of a plot (used when all facets are treated identically). */
-trait PlotComponent extends FacetedPlotComponent {
+trait PlotComponent extends FacetedPlotComponent{
// Render the component (assumes all facets are handled the same way).
def render(plot: Plot, extent: Extent)(implicit theme: Theme): Drawable
@@ -44,5 +44,5 @@ trait PlotComponent extends FacetedPlotComponent {
// This this calls the implementation that ignores facet information.
final def render(plot: Plot, extent: Extent, row: Int, column: Int)(
implicit theme: Theme): Drawable =
- render(plot, extent)
+ render(plot, extent)(theme)
}
diff --git a/shared/src/main/scala/com/cibo/evilplot/plot/components/PlotLine.scala b/shared/src/main/scala/com/cibo/evilplot/plot/components/PlotLine.scala
index 2a0fd439..ad4207d4 100644
--- a/shared/src/main/scala/com/cibo/evilplot/plot/components/PlotLine.scala
+++ b/shared/src/main/scala/com/cibo/evilplot/plot/components/PlotLine.scala
@@ -35,6 +35,7 @@ import com.cibo.evilplot.geometry.{Drawable, EmptyDrawable, Extent, Line, LineSt
import com.cibo.evilplot.numeric.{Bounds, Point}
import com.cibo.evilplot.plot.Plot
import com.cibo.evilplot.plot.aesthetics.Theme
+import com.cibo.evilplot.plot.ExplicitImplicits
import scala.annotation.tailrec
@@ -167,7 +168,7 @@ object FunctionPlotLine {
}
}
-trait PlotLineImplicits {
+trait PlotLineImplicits extends ExplicitImplicits{
protected val plot: Plot
val defaultThickness: Double = 2.0
diff --git a/shared/src/main/scala/com/cibo/evilplot/plot/renderers/BarRenderer.scala b/shared/src/main/scala/com/cibo/evilplot/plot/renderers/BarRenderer.scala
index 465908a1..aab03334 100644
--- a/shared/src/main/scala/com/cibo/evilplot/plot/renderers/BarRenderer.scala
+++ b/shared/src/main/scala/com/cibo/evilplot/plot/renderers/BarRenderer.scala
@@ -34,13 +34,14 @@ import com.cibo.evilplot.colors.Color
import com.cibo.evilplot.geometry._
import com.cibo.evilplot.plot.aesthetics.Theme
import com.cibo.evilplot.plot.{Bar, LegendContext, Plot}
+import com.cibo.evilplot.plot.ExplicitImplicits
trait BarRenderer extends PlotElementRenderer[Bar] {
def render(plot: Plot, extent: Extent, category: Bar): Drawable
def legendContext: Option[LegendContext] = None
}
-object BarRenderer {
+object BarRenderer extends ExplicitImplicits{
/** Default bar renderer. */
def default(
@@ -68,7 +69,7 @@ object BarRenderer {
Rect(legSize, legSize).filled(color.getOrElse(theme.colors.bar))
},
label = n
- )
+ )(theme)
}
}
diff --git a/shared/src/main/scala/com/cibo/evilplot/plot/renderers/BoxRenderer.scala b/shared/src/main/scala/com/cibo/evilplot/plot/renderers/BoxRenderer.scala
index 75b137d8..d3c915a9 100644
--- a/shared/src/main/scala/com/cibo/evilplot/plot/renderers/BoxRenderer.scala
+++ b/shared/src/main/scala/com/cibo/evilplot/plot/renderers/BoxRenderer.scala
@@ -47,8 +47,9 @@ import com.cibo.evilplot.numeric.BoxPlotSummaryStatistics
import com.cibo.evilplot.plot.aesthetics.Theme
import com.cibo.evilplot.plot.renderers.BoxRenderer.BoxRendererContext
import com.cibo.evilplot.plot.{LegendContext, Plot}
+import com.cibo.evilplot.plot.ExplicitImplicits
-trait BoxRenderer extends PlotElementRenderer[BoxRendererContext] { br =>
+trait BoxRenderer extends PlotElementRenderer[BoxRendererContext] with ExplicitImplicits{ br =>
def render(plot: Plot, extent: Extent, summary: BoxRendererContext): Drawable
def legendContext: LegendContext = LegendContext.empty
@@ -76,7 +77,7 @@ trait BoxRenderer extends PlotElementRenderer[BoxRendererContext] { br =>
}
}
-object BoxRenderer {
+object BoxRenderer extends ExplicitImplicits {
final case class BoxRendererContext(
summaryStatistics: BoxPlotSummaryStatistics,
index: Int,
@@ -173,16 +174,16 @@ object BoxRenderer {
strokeWidth: Option[Double] = None
)(implicit theme: Theme): BoxRenderer = new BoxRenderer {
private val useColoring = fillColoring.getOrElse(CategoricalColoring.themed[A])
- private val colorFunc = useColoring(colorDimension)
+ private val colorFunc = useColoring(colorDimension)(theme)
def render(plot: Plot, extent: Extent, context: BoxRendererContext): Drawable = {
BoxRenderer
- .default(fillColor = Some(colorFunc(colorDimension(context.index))))
+ .default(fillColor = Some(colorFunc(colorDimension(context.index))))(theme)
.render(plot, extent, context)
}
override def legendContext: LegendContext = {
- useColoring.legendContext(colorDimension, legendGlyph = d => Rect(d))
+ useColoring.legendContext(colorDimension, legendGlyph = d => Rect(d))(theme)
}
}
}
diff --git a/shared/src/main/scala/com/cibo/evilplot/plot/renderers/ComponentRenderer.scala b/shared/src/main/scala/com/cibo/evilplot/plot/renderers/ComponentRenderer.scala
index 1fc542b8..9737cff3 100644
--- a/shared/src/main/scala/com/cibo/evilplot/plot/renderers/ComponentRenderer.scala
+++ b/shared/src/main/scala/com/cibo/evilplot/plot/renderers/ComponentRenderer.scala
@@ -34,6 +34,7 @@ import com.cibo.evilplot.geometry.{Drawable, EmptyDrawable, Extent}
import com.cibo.evilplot.numeric.Point
import com.cibo.evilplot.plot.Plot
import com.cibo.evilplot.plot.aesthetics.Theme
+import com.cibo.evilplot.plot.ExplicitImplicits
/** Renderer for non-plot area components of a plot (labels, etc.). */
trait ComponentRenderer {
@@ -48,7 +49,7 @@ trait ComponentRenderer {
def plotOffset(plot: Plot): Point
}
-object ComponentRenderer {
+object ComponentRenderer extends ExplicitImplicits{
case class Default() extends ComponentRenderer {
@@ -58,7 +59,7 @@ object ComponentRenderer {
val plotExtent = plot.plotExtent(extent)
plot.topComponents.reverse.foldLeft(empty) { (d, c) =>
val componentExtent = plotExtent.copy(height = c.size(plot).height)
- c.render(plot, componentExtent, 0, 0)
+ c.render(plot, componentExtent, 0, 0)(theme)
.translate(x = plot.plotOffset.x, y = d.extent.height) behind d
}
}
@@ -69,7 +70,7 @@ object ComponentRenderer {
.foldLeft((extent.height, empty)) {
case ((y, d), c) =>
val componentExtent = plotExtent.copy(height = c.size(plot).height)
- val rendered = c.render(plot, plotExtent, 0, 0)
+ val rendered = c.render(plot, plotExtent, 0, 0)(theme)
val newY = y - rendered.extent.height
(newY, rendered.translate(x = plot.plotOffset.x, y = newY) behind d)
}
@@ -80,7 +81,7 @@ object ComponentRenderer {
val plotExtent = plot.plotExtent(extent)
plot.leftComponents.foldLeft(empty) { (d, c) =>
val componentExtent = plotExtent.copy(width = c.size(plot).width)
- c.render(plot, componentExtent, 0, 0).translate(y = plot.plotOffset.y) beside d
+ c.render(plot, componentExtent, 0, 0)(theme).translate(y = plot.plotOffset.y) beside d
}
}
@@ -90,7 +91,7 @@ object ComponentRenderer {
.foldLeft((extent.width, empty)) {
case ((x, d), c) =>
val componentExtent = plotExtent.copy(width = c.size(plot).width)
- val rendered = c.render(plot, componentExtent, 0, 0)
+ val rendered = c.render(plot, componentExtent, 0, 0)(theme)
val newX = x - rendered.extent.width
(newX, rendered.translate(x = newX, y = plot.plotOffset.y) behind d)
}
@@ -100,22 +101,22 @@ object ComponentRenderer {
private def renderOverlay(plot: Plot, extent: Extent)(implicit theme: Theme): Drawable = {
val plotExtent = plot.plotExtent(extent)
plot.overlayComponents.map { a =>
- a.render(plot, plotExtent, 0, 0).translate(x = plot.plotOffset.x, y = plot.plotOffset.y)
+ a.render(plot, plotExtent, 0, 0)(theme).translate(x = plot.plotOffset.x, y = plot.plotOffset.y)
}.group
}
def renderFront(plot: Plot, extent: Extent)(implicit theme: Theme): Drawable = {
- renderOverlay(plot, extent)
- .behind(renderLeft(plot, extent))
- .behind(renderRight(plot, extent))
- .behind(renderBottom(plot, extent))
- .behind(renderTop(plot, extent))
+ renderOverlay(plot, extent)(theme)
+ .behind(renderLeft(plot, extent)(theme))
+ .behind(renderRight(plot, extent)(theme))
+ .behind(renderBottom(plot, extent)(theme))
+ .behind(renderTop(plot, extent)(theme))
}
def renderBack(plot: Plot, extent: Extent)(implicit theme: Theme): Drawable = {
val plotExtent = plot.plotExtent(extent)
plot.backgroundComponents.map { a =>
- a.render(plot, plotExtent, 0, 0).translate(x = plot.plotOffset.x, y = plot.plotOffset.y)
+ a.render(plot, plotExtent, 0, 0)(theme).translate(x = plot.plotOffset.x, y = plot.plotOffset.y)
}.group
}
diff --git a/shared/src/main/scala/com/cibo/evilplot/plot/renderers/PathRenderer.scala b/shared/src/main/scala/com/cibo/evilplot/plot/renderers/PathRenderer.scala
index 9c14639a..77af103b 100644
--- a/shared/src/main/scala/com/cibo/evilplot/plot/renderers/PathRenderer.scala
+++ b/shared/src/main/scala/com/cibo/evilplot/plot/renderers/PathRenderer.scala
@@ -46,13 +46,14 @@ import com.cibo.evilplot.geometry.{
import com.cibo.evilplot.numeric.Point
import com.cibo.evilplot.plot.aesthetics.Theme
import com.cibo.evilplot.plot.{LegendContext, Plot}
+import com.cibo.evilplot.plot.ExplicitImplicits
trait PathRenderer extends PlotElementRenderer[Seq[Point]] {
def legendContext: LegendContext = LegendContext.empty
def render(plot: Plot, extent: Extent, path: Seq[Point]): Drawable
}
-object PathRenderer {
+object PathRenderer extends ExplicitImplicits{
private[renderers] val baseLegendStrokeLength: Double = 8.0
/** The default path renderer.
@@ -90,13 +91,13 @@ object PathRenderer {
Text(name, theme.fonts.legendLabelSize, theme.fonts.fontFace),
theme.colors.legendLabel),
lineStyle
- )
+ )(theme)
/** Path renderer for closed paths. The first point is connected to the last point.
* @param color the color of this path.
*/
@deprecated("Use the overload taking a strokeWidth, color, label and lineStyle", "2 April 2018")
- def closed(color: Color)(implicit theme: Theme): PathRenderer = closed(color = Some(color))
+ def closed(color: Color)(implicit theme: Theme): PathRenderer = closed(color = Some(color))(theme)
/** Path renderer for closed paths. The first point is connected to the last point.
* @param strokeWidth the stroke width
@@ -111,7 +112,7 @@ object PathRenderer {
)(implicit theme: Theme): PathRenderer = new PathRenderer {
def render(plot: Plot, extent: Extent, path: Seq[Point]): Drawable = {
path.headOption.fold(EmptyDrawable(): Drawable) { head =>
- default(strokeWidth, color, label, lineStyle).render(plot, extent, path :+ head)
+ default(strokeWidth, color, label, lineStyle)(theme).render(plot, extent, path :+ head)
}
}
}
@@ -175,4 +176,4 @@ class DefaultPathRenderer (strokeWidth: Double,
)
.group
}
-}
\ No newline at end of file
+}
diff --git a/shared/src/main/scala/com/cibo/evilplot/plot/renderers/PlotRenderer.scala b/shared/src/main/scala/com/cibo/evilplot/plot/renderers/PlotRenderer.scala
index 2e12ef03..6a2a076c 100644
--- a/shared/src/main/scala/com/cibo/evilplot/plot/renderers/PlotRenderer.scala
+++ b/shared/src/main/scala/com/cibo/evilplot/plot/renderers/PlotRenderer.scala
@@ -33,9 +33,10 @@ package com.cibo.evilplot.plot.renderers
import com.cibo.evilplot.geometry.{Drawable, Extent}
import com.cibo.evilplot.plot.aesthetics.Theme
import com.cibo.evilplot.plot.{LegendContext, Plot}
+import com.cibo.evilplot.plot.ExplicitImplicits
/** Renderer for the plot area. */
-trait PlotRenderer {
+trait PlotRenderer extends ExplicitImplicits{
def legendContext: LegendContext = LegendContext.empty
def render(plot: Plot, plotExtent: Extent)(implicit theme: Theme): Drawable
}
diff --git a/shared/src/main/scala/com/cibo/evilplot/plot/renderers/PointRenderer.scala b/shared/src/main/scala/com/cibo/evilplot/plot/renderers/PointRenderer.scala
index 956f32b5..916b2aab 100644
--- a/shared/src/main/scala/com/cibo/evilplot/plot/renderers/PointRenderer.scala
+++ b/shared/src/main/scala/com/cibo/evilplot/plot/renderers/PointRenderer.scala
@@ -34,13 +34,14 @@ import com.cibo.evilplot.colors._
import com.cibo.evilplot.geometry.{Disc, Drawable, EmptyDrawable, Extent, Style, Text}
import com.cibo.evilplot.plot.aesthetics.Theme
import com.cibo.evilplot.plot.{LegendContext, LegendStyle, Plot}
+import com.cibo.evilplot.plot.ExplicitImplicits
trait PointRenderer extends PlotElementRenderer[Int] {
def legendContext: LegendContext = LegendContext()
def render(plot: Plot, extent: Extent, index: Int): Drawable
}
-object PointRenderer {
+object PointRenderer extends ExplicitImplicits{
val defaultColorCount: Int = 10
@@ -78,7 +79,7 @@ object PointRenderer {
size: Option[Double] = None
)(implicit theme: Theme): PointRenderer = new PointRenderer {
private val useColoring = coloring.getOrElse(theme.colors.continuousColoring)
- private val colorFunc = useColoring(depths)
+ private val colorFunc = useColoring(depths)(theme)
private val radius = size.getOrElse(theme.elements.pointSize)
def render(plot: Plot, extent: Extent, index: Int): Drawable = {
@@ -86,7 +87,7 @@ object PointRenderer {
}
override def legendContext: LegendContext =
- useColoring.legendContext(depths)
+ useColoring.legendContext(depths)(theme)
}
/**
@@ -103,14 +104,14 @@ object PointRenderer {
size: Option[Double] = None
)(implicit theme: Theme): PointRenderer = new PointRenderer {
private val useColoring = coloring.getOrElse(CategoricalColoring.themed[A])
- private val colorFunc = useColoring(colorDimension)
+ private val colorFunc = useColoring(colorDimension)(theme)
private val radius = size.getOrElse(theme.elements.pointSize)
def render(plot: Plot, extent: Extent, index: Int): Drawable = {
Disc.centered(radius).filled(colorFunc(colorDimension(index)))
}
- override def legendContext: LegendContext = useColoring.legendContext(colorDimension)
+ override def legendContext: LegendContext = useColoring.legendContext(colorDimension)(theme)
}
/**
@@ -138,7 +139,7 @@ object PointRenderer {
theme.fonts.fontFace),
theme.colors.legendLabel)
}
- oldDepthColor(depths, labels, bar, None)
+ oldDepthColor(depths, labels, bar, None)(theme)
}
/** Render points with colors based on depth.
@@ -154,7 +155,7 @@ object PointRenderer {
bar: ScaledColorBar,
size: Option[Double]
)(implicit theme: Theme): PointRenderer = {
- oldDepthColor(depths, labels, bar, size)
+ oldDepthColor(depths, labels, bar, size)(theme)
}
/** Render points with colors based on depth.
@@ -167,7 +168,7 @@ object PointRenderer {
depths: Seq[Double],
labels: Seq[Drawable],
bar: ScaledColorBar
- )(implicit theme: Theme): PointRenderer = oldDepthColor(depths, labels, bar, None)
+ )(implicit theme: Theme): PointRenderer = oldDepthColor(depths, labels, bar, None)(theme)
/** Render points with colors based on depth.
* @param depths The depths.
@@ -186,7 +187,7 @@ object PointRenderer {
theme.fonts.fontFace),
theme.colors.legendLabel)
}
- oldDepthColor(depths, labels, bar, None)
+ oldDepthColor(depths, labels, bar, None)(theme)
}
// Old `depthColor` implementation, called to by all deprecated `depthColor`
diff --git a/shared/src/main/scala/com/cibo/evilplot/plot/renderers/SurfaceRenderer.scala b/shared/src/main/scala/com/cibo/evilplot/plot/renderers/SurfaceRenderer.scala
index 38922b48..4433d6dd 100644
--- a/shared/src/main/scala/com/cibo/evilplot/plot/renderers/SurfaceRenderer.scala
+++ b/shared/src/main/scala/com/cibo/evilplot/plot/renderers/SurfaceRenderer.scala
@@ -36,13 +36,14 @@ import com.cibo.evilplot.numeric.{Bounds, Point, Point3}
import com.cibo.evilplot.plot.aesthetics.Theme
import com.cibo.evilplot.plot.renderers.SurfaceRenderer.SurfaceRenderContext
import com.cibo.evilplot.plot.{LegendContext, Plot}
+import com.cibo.evilplot.plot.ExplicitImplicits
trait SurfaceRenderer extends PlotElementRenderer[SurfaceRenderContext] {
def legendContext(levels: Seq[Double]): LegendContext = LegendContext.empty
def render(plot: Plot, extent: Extent, surface: SurfaceRenderContext): Drawable
}
-object SurfaceRenderer {
+object SurfaceRenderer extends ExplicitImplicits{
/** The element renderer context for surface renderers. */
case class SurfaceRenderContext(
@@ -91,9 +92,9 @@ object SurfaceRenderer {
val surfaceRenderer = getBySafe(points)(_.headOption.flatMap(_.headOption.map(_.z)))
.map { bs =>
val bar = ScaledColorBar(getColorSeq(points.length), bs.min, bs.max)
- densityColorContours(bar)(points)
+ densityColorContours(bar)(points)(theme)
}
- .getOrElse(contours())
+ .getOrElse(contours()(theme))
surfaceRenderer.render(plot, extent, surface)
}
}
@@ -105,7 +106,7 @@ object SurfaceRenderer {
surface.currentLevelPaths.headOption
.map(pts =>
contours(Some(pts.headOption.fold(theme.colors.path)(_ =>
- bar.getColor(surface.currentLevel))))
+ bar.getColor(surface.currentLevel))))(theme)
.render(plot, extent, surface))
.getOrElse(EmptyDrawable())
}
@@ -120,17 +121,17 @@ object SurfaceRenderer {
coloring.getOrElse(theme.colors.continuousColoring)
def render(plot: Plot, extent: Extent, surface: SurfaceRenderContext): Drawable = {
- val color = useColoring(surface.levels).apply(surface.currentLevel)
+ val color = useColoring(surface.levels)(theme).apply(surface.currentLevel)
surface.currentLevelPaths
.map(
pts =>
- contours(Some(color), strokeWidth, dashPattern)
+ contours(Some(color), strokeWidth, dashPattern)(theme)
.render(plot, extent, surface))
.group
}
override def legendContext(levels: Seq[Double]): LegendContext = {
- useColoring.legendContext(levels)
+ useColoring.legendContext(levels)(theme)
}
}
}
diff --git a/shared/src/test/scala/com/cibo/evilplot/colors/ColoringSpec.scala b/shared/src/test/scala/com/cibo/evilplot/colors/ColoringSpec.scala
index ea08857f..071d02a7 100644
--- a/shared/src/test/scala/com/cibo/evilplot/colors/ColoringSpec.scala
+++ b/shared/src/test/scala/com/cibo/evilplot/colors/ColoringSpec.scala
@@ -30,13 +30,12 @@
package com.cibo.evilplot.colors
-import com.cibo.evilplot.plot.aesthetics.DefaultTheme.{DefaultElements, DefaultFonts}
import com.cibo.evilplot.plot.aesthetics.{Colors, Elements, Fonts, Theme}
import org.scalatest.{FunSpec, Matchers}
class ColoringSpec extends FunSpec with Matchers {
+
describe("multi color gradient construction") {
- import com.cibo.evilplot.plot.aesthetics.DefaultTheme._
it("should return a function when Colors has only one element") {
val min: Double = 0
val max: Double = 100
@@ -77,8 +76,8 @@ class ColoringSpec extends FunSpec with Matchers {
coloring(6.0) shouldBe HTMLNamedColors.blue
}
}
- describe("coloring from the theme") {
- import com.cibo.evilplot.plot.aesthetics.DefaultTheme.{DefaultColors => AesColors}
+ describe("overriding the default color from the theme") {
+ import com.cibo.evilplot.plot.aesthetics.DefaultTheme.{DefaultElements,DefaultFonts,DefaultColors => AesColors}
implicit val overriddenTheme: Theme = Theme(
fonts = DefaultFonts,
elements = DefaultElements,
@@ -90,7 +89,6 @@ class ColoringSpec extends FunSpec with Matchers {
}
}
describe("making a coloring out of a custom mapping") {
- import com.cibo.evilplot.plot.aesthetics.DefaultTheme._
it("should actually use the mapping") {
val f = (s: String) => if (s == "hello") HTMLNamedColors.blue else HTMLNamedColors.red
val coloring = CategoricalColoring.fromFunction(Seq("hello", "world"), f)
diff --git a/shared/src/test/scala/com/cibo/evilplot/geometry/AffineTransformSpec.scala b/shared/src/test/scala/com/cibo/evilplot/geometry/AffineTransformSpec.scala
index cda1457c..4b8ea53b 100644
--- a/shared/src/test/scala/com/cibo/evilplot/geometry/AffineTransformSpec.scala
+++ b/shared/src/test/scala/com/cibo/evilplot/geometry/AffineTransformSpec.scala
@@ -34,8 +34,6 @@ import org.scalatest.{FunSpec, Matchers}
class AffineTransformSpec extends FunSpec with Matchers {
- import com.cibo.evilplot.plot.aesthetics.DefaultTheme._
-
describe("The AffineTransform") {
it("should translate a point") {
AffineTransform.identity.translate(1.0, 0.0)(1.0, 1.0) should be((2.0, 1.0))
diff --git a/shared/src/test/scala/com/cibo/evilplot/geometry/DrawableSpec.scala b/shared/src/test/scala/com/cibo/evilplot/geometry/DrawableSpec.scala
index c5e916e0..4541501a 100644
--- a/shared/src/test/scala/com/cibo/evilplot/geometry/DrawableSpec.scala
+++ b/shared/src/test/scala/com/cibo/evilplot/geometry/DrawableSpec.scala
@@ -34,8 +34,6 @@ import org.scalatest.{FunSpec, Matchers}
class DrawableSpec extends FunSpec with Matchers {
- import com.cibo.evilplot.plot.aesthetics.DefaultTheme._
-
describe("EmptyDrawable") {
it("has zero size") {
EmptyDrawable().extent shouldBe Extent(0, 0)
diff --git a/shared/src/test/scala/com/cibo/evilplot/plot/BarChartSpec.scala b/shared/src/test/scala/com/cibo/evilplot/plot/BarChartSpec.scala
index 1a61a7ca..06ffc9bd 100644
--- a/shared/src/test/scala/com/cibo/evilplot/plot/BarChartSpec.scala
+++ b/shared/src/test/scala/com/cibo/evilplot/plot/BarChartSpec.scala
@@ -36,8 +36,6 @@ import org.scalatest.{FunSpec, Matchers}
class BarChartSpec extends FunSpec with Matchers {
- import com.cibo.evilplot.plot.aesthetics.DefaultTheme._
-
describe("BarChart") {
it("should have the right bounds without buffer") {
val plot = BarChart(Seq[Double](10, 20, 15))
diff --git a/shared/src/test/scala/com/cibo/evilplot/plot/BoxPlotSpec.scala b/shared/src/test/scala/com/cibo/evilplot/plot/BoxPlotSpec.scala
index ffcb3ed8..2aa58277 100644
--- a/shared/src/test/scala/com/cibo/evilplot/plot/BoxPlotSpec.scala
+++ b/shared/src/test/scala/com/cibo/evilplot/plot/BoxPlotSpec.scala
@@ -36,8 +36,6 @@ import org.scalatest.{FunSpec, Matchers}
class BoxPlotSpec extends FunSpec with Matchers {
- import com.cibo.evilplot.plot.aesthetics.DefaultTheme._
-
describe("BoxPlot") {
it("should have the right extents") {
val plot = BoxPlot(Seq(Seq(1.0, 2.0)))
diff --git a/shared/src/test/scala/com/cibo/evilplot/plot/ContourPlotSpec.scala b/shared/src/test/scala/com/cibo/evilplot/plot/ContourPlotSpec.scala
index 57d97f60..1759cb62 100644
--- a/shared/src/test/scala/com/cibo/evilplot/plot/ContourPlotSpec.scala
+++ b/shared/src/test/scala/com/cibo/evilplot/plot/ContourPlotSpec.scala
@@ -36,8 +36,6 @@ import org.scalatest.{FunSpec, Matchers}
class ContourPlotSpec extends FunSpec with Matchers {
- import com.cibo.evilplot.plot.aesthetics.DefaultTheme._
-
describe("ContourPlot") {
it("it has the right bounds") {
val plot = ContourPlot(Seq(Point(1, 2), Point(3, 4)), boundBuffer = Some(0.0))
diff --git a/shared/src/test/scala/com/cibo/evilplot/plot/ExplicitImplicitsSpec.scala b/shared/src/test/scala/com/cibo/evilplot/plot/ExplicitImplicitsSpec.scala
new file mode 100644
index 00000000..e34de83d
--- /dev/null
+++ b/shared/src/test/scala/com/cibo/evilplot/plot/ExplicitImplicitsSpec.scala
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2018, CiBO Technologies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.cibo.evilplot.plot
+
+import org.scalatest.{FunSpec, Matchers}
+
+class ExplcitImplicitsSpec extends FunSpec with Matchers {
+ describe("ExplicitImplicit") {
+ it("allows default implicit themes"){
+ val hist = Histogram(Seq(1, 2, 2))
+ hist.render().extent shouldBe Plot.defaultExtent
+ }
+
+ it("Provides a mechansim to *require* explicit themes at compile time"){
+ import com.cibo.evilplot.plot.aesthetics.Theme
+ object CustomHistogram extends ExplicitImplicits{
+ def hist(xs:Seq[Double])(implicit theme:Theme) = Histogram(xs)(theme).render()(theme)
+ }
+ CustomHistogram.hist( Seq(1,2,2) ).extent shouldBe Plot.defaultExtent
+ }
+
+ it("still provides a mechansim to catch accidental default themes at compile time with a type Error"){
+
+ assertTypeError("""
+ import com.cibo.evilplot.plot.aesthetics.Theme
+ object CustomHistogram extends ExplicitImplicits{
+ def hist(xs:Seq[Double])(implicit theme:Theme) = Histogram(xs).render() // both implicit
+ }
+ """)
+ assertTypeError("""
+ import com.cibo.evilplot.plot.aesthetics.Theme
+ object CustomHistogram extends ExplicitImplicits{
+ def hist(xs:Seq[Double])(implicit theme:Theme) = Histogram(xs)(theme).render() // first explicit
+ }
+ """)
+ assertTypeError("""
+ import com.cibo.evilplot.plot.aesthetics.Theme
+ object CustomHistogram extends ExplicitImplicits{
+ def hist(xs:Seq[Double])(implicit theme:Theme) = Histogram(xs)().render()(theme) //second explicit
+ }
+ """)
+ assertCompiles("""
+ import com.cibo.evilplot.plot.aesthetics.Theme
+ object CustomHistogram extends ExplicitImplicits{
+ def hist(xs:Seq[Double])(implicit theme:Theme) = Histogram(xs)(theme).render()(theme) //both explicit
+ }
+ """)
+ }
+ }
+}
diff --git a/shared/src/test/scala/com/cibo/evilplot/plot/FacetsSpec.scala b/shared/src/test/scala/com/cibo/evilplot/plot/FacetsSpec.scala
index 7e05630b..deee8504 100644
--- a/shared/src/test/scala/com/cibo/evilplot/plot/FacetsSpec.scala
+++ b/shared/src/test/scala/com/cibo/evilplot/plot/FacetsSpec.scala
@@ -38,8 +38,6 @@ import com.cibo.evilplot.plot.components.{FacetedPlotComponent, Position}
class FacetsSpec extends FunSpec with Matchers {
- import com.cibo.evilplot.plot.aesthetics.DefaultTheme._
-
describe("Facets") {
it("is the correct size with one facet") {
val inner = ScatterPlot(Seq(Point(1, 1), Point(2, 2)))
diff --git a/shared/src/test/scala/com/cibo/evilplot/plot/HeatmapSpec.scala b/shared/src/test/scala/com/cibo/evilplot/plot/HeatmapSpec.scala
index b2ce77a1..c961d5c1 100644
--- a/shared/src/test/scala/com/cibo/evilplot/plot/HeatmapSpec.scala
+++ b/shared/src/test/scala/com/cibo/evilplot/plot/HeatmapSpec.scala
@@ -36,8 +36,6 @@ import org.scalatest.{FunSpec, Matchers}
class HeatmapSpec extends FunSpec with Matchers {
- import com.cibo.evilplot.plot.aesthetics.DefaultTheme._
-
describe("Heatmap") {
it("has the right bounds") {
val plot = Heatmap(Seq(Seq(1), Seq(2)))
diff --git a/shared/src/test/scala/com/cibo/evilplot/plot/HistogramSpec.scala b/shared/src/test/scala/com/cibo/evilplot/plot/HistogramSpec.scala
index 1c921480..cadf5555 100644
--- a/shared/src/test/scala/com/cibo/evilplot/plot/HistogramSpec.scala
+++ b/shared/src/test/scala/com/cibo/evilplot/plot/HistogramSpec.scala
@@ -36,8 +36,6 @@ import org.scalatest.{FunSpec, Matchers}
class HistogramSpec extends FunSpec with Matchers {
- import com.cibo.evilplot.plot.aesthetics.DefaultTheme._
-
describe("Histogram") {
val plot = Histogram(Seq(1.0, 1, 1, 2, 3, 4, 4, 5), boundBuffer = Some(0))
diff --git a/shared/src/test/scala/com/cibo/evilplot/plot/MixedBoundsOverlaySpec.scala b/shared/src/test/scala/com/cibo/evilplot/plot/MixedBoundsOverlaySpec.scala
index 3c04a391..ace4bf75 100644
--- a/shared/src/test/scala/com/cibo/evilplot/plot/MixedBoundsOverlaySpec.scala
+++ b/shared/src/test/scala/com/cibo/evilplot/plot/MixedBoundsOverlaySpec.scala
@@ -38,8 +38,6 @@ import org.scalatest.{FunSpec, Matchers}
class MixedBoundsOverlaySpec extends FunSpec with Matchers {
- import com.cibo.evilplot.plot.aesthetics.DefaultTheme._
-
describe("MixedBoundsOverlay") {
it("it has the bounds that are set for it") {
diff --git a/shared/src/test/scala/com/cibo/evilplot/plot/OverlaySpec.scala b/shared/src/test/scala/com/cibo/evilplot/plot/OverlaySpec.scala
index 0866bc8f..c2d3da91 100644
--- a/shared/src/test/scala/com/cibo/evilplot/plot/OverlaySpec.scala
+++ b/shared/src/test/scala/com/cibo/evilplot/plot/OverlaySpec.scala
@@ -38,8 +38,6 @@ import org.scalatest.{FunSpec, Matchers}
class OverlaySpec extends FunSpec with Matchers {
- import com.cibo.evilplot.plot.aesthetics.DefaultTheme._
-
describe("Overlay") {
it("it gets the bounds right for a single plot") {
val inner = ScatterPlot(Seq(Point(1.0, 10.0), Point(2.0, 20.0)))
diff --git a/shared/src/test/scala/com/cibo/evilplot/plot/PlotSpec.scala b/shared/src/test/scala/com/cibo/evilplot/plot/PlotSpec.scala
index 3f847a77..2a277b99 100644
--- a/shared/src/test/scala/com/cibo/evilplot/plot/PlotSpec.scala
+++ b/shared/src/test/scala/com/cibo/evilplot/plot/PlotSpec.scala
@@ -39,8 +39,6 @@ import org.scalatest.{FunSpec, Matchers}
class PlotSpec extends FunSpec with Matchers {
- import com.cibo.evilplot.plot.aesthetics.DefaultTheme._
-
DOMInitializer.init()
// Renderer to do nothing.
diff --git a/shared/src/test/scala/com/cibo/evilplot/plot/ScatterPlotSpec.scala b/shared/src/test/scala/com/cibo/evilplot/plot/ScatterPlotSpec.scala
index 52c7166a..6ee1866b 100644
--- a/shared/src/test/scala/com/cibo/evilplot/plot/ScatterPlotSpec.scala
+++ b/shared/src/test/scala/com/cibo/evilplot/plot/ScatterPlotSpec.scala
@@ -35,8 +35,6 @@ import org.scalatest.{FunSpec, Matchers}
class ScatterPlotSpec extends FunSpec with Matchers {
- import com.cibo.evilplot.plot.aesthetics.DefaultTheme._
-
describe("ScatterPlot") {
it("sets adheres to bound buffers") {
val data = Seq(Point(-1, 10), Point(20, -5))
diff --git a/shared/src/test/scala/com/cibo/evilplot/plot/XyPlotSpec.scala b/shared/src/test/scala/com/cibo/evilplot/plot/XyPlotSpec.scala
index 1ca0d725..7a24b351 100644
--- a/shared/src/test/scala/com/cibo/evilplot/plot/XyPlotSpec.scala
+++ b/shared/src/test/scala/com/cibo/evilplot/plot/XyPlotSpec.scala
@@ -36,8 +36,6 @@ import org.scalatest.{FunSpec, Matchers}
class XyPlotSpec extends FunSpec with Matchers {
- import com.cibo.evilplot.plot.aesthetics.DefaultTheme._
-
describe("XyPlot") {
it("has the right bounds") {
val plot =
diff --git a/shared/src/test/scala/com/cibo/evilplot/plot/components/AxesSpec.scala b/shared/src/test/scala/com/cibo/evilplot/plot/components/AxesSpec.scala
index 40e02e4a..6987a3a0 100644
--- a/shared/src/test/scala/com/cibo/evilplot/plot/components/AxesSpec.scala
+++ b/shared/src/test/scala/com/cibo/evilplot/plot/components/AxesSpec.scala
@@ -36,8 +36,6 @@ import org.scalatest.{FunSpec, Matchers}
class AxesSpec extends FunSpec with Matchers {
- import com.cibo.evilplot.plot.aesthetics.DefaultTheme._
-
describe("discrete X") {
it("should set the default bounds") {
val plot = BarChart(Seq(3.0, 4)).xAxis()
diff --git a/shared/src/test/scala/com/cibo/evilplot/plot/components/ComponentGroupSpec.scala b/shared/src/test/scala/com/cibo/evilplot/plot/components/ComponentGroupSpec.scala
index 2c965ad9..ce8f20bb 100644
--- a/shared/src/test/scala/com/cibo/evilplot/plot/components/ComponentGroupSpec.scala
+++ b/shared/src/test/scala/com/cibo/evilplot/plot/components/ComponentGroupSpec.scala
@@ -35,9 +35,7 @@ import com.cibo.evilplot.plot.aesthetics.Theme
import com.cibo.evilplot.plot.{Plot, XyPlot}
import org.scalatest.{FunSpec, Matchers}
-class ComponentGroupSpec extends FunSpec with Matchers {
-
- import com.cibo.evilplot.plot.aesthetics.DefaultTheme._
+class ComponentGroupSpec extends FunSpec with Matchers{
abstract class MockComponent(val position: Position) extends FacetedPlotComponent
abstract class LeftComponent extends MockComponent(Position.Left)