-
Notifications
You must be signed in to change notification settings - Fork 221
Upgrading to 1.0.0
This Guide consists of a few sections to help you get started
- Upgrade steps - step by step walk through of the changes you need to make
- Detailed information on the changes - explanations and motivations for changes, as well as any additional details about usage or best practices
The following modules have been renamed:
-
Component
->Components
-
Plot
->Plots
-
Drawer
->Drawers
-
Scale
->Scales
-
Animator
->Animators
-
Axis
->Axes
-
Dispatcher
->Dispatchers
-
Interaction
->Interactions
-
_Util
->Utils
Abstract classes have been renamed as follows:
-
Plottable.Components.AbstractComponent
->Plottable.Component
-
Plottable.Plots.AbstractPlot
->Plottable.Plot
-
Plottable.Plots.AbstractXYPlot
->Plottable.XYPlot
-
Plottable.Drawers.AbstractDrawer
->Plottable.Drawer
-
Plottable.Scales.AbstractScale
->Plottable.Scale
-
Plottable.Axes.AbstractAxis
->Plottable.Axis
-
Plottable.Scales.AbstractQuantitative
->Plottable.QuantitativeScale
-
Plottable.Components.AbstractComponentContainer
->Plottable.ComponentContainer
-
Plottable.Dispatchers.AbstractDispatcher
->Plottable.Dispatcher
-
Plottable.Interactions.AbstractInteraction
->Plottable.Interaction
The way display properties are set on Plot
s has changed: see "Removal of project()
" for a more detailed explanation as to why.
Rename all invocations of project()
to attr()
. With a global find-replace:
-
FIND:
project(
-
REPLACE:
attr(
Previously, a string
passed in as the second argument to project()
would be used as a key into the data (unless it began with "#"), so project("fill", "color")
was the same as project("fill", function(d) { return d.color; })
. This functionality has been removed.
With a global find-replace (with regular expressions):
-
FIND:
\.attr\("([^"]+)",\s*("[^"]+")
-
REPLACE:
.attr("$1", function(d) { return d[$2]; }
project()
calls that did not directly set DOM attributes have been spun off into their own methods:
-
project("x", ...)
-->x(...)
-
project("y", ...)
-->y(...)
-
project("y0", ...)
-->y0(...)
-
project("size", ...)
-->size(...)
-
project("symbol", ...)
-->symbol(...)
-
project("x2", ...)
-->x2(...)
-
project("y2", ...)
-->y2(...)
With a global find-replace (with regular expressions):
-
FIND:
\.attr\("(x|y|y0|size|symbol|x1|y1|x2|y2)",\s*
-
REPLACE:
.$1(
-
project("inner-radius", ...)
-->innerRadius(...)
-
project("outer-radius", ...)
-->outerRadius(...)
-
project("value", ...)
-->sectorValue(...)
With a global find-replace (with regular expressions):
-
FIND:
\.attr\("(inner|outer)-radius",\s*
-
REPLACE:
.$1Radius(
-
FIND:
\.attr\("value",\s*
-
REPLACE:
.sectorValue(
-
_SpaceRequest
->SpaceRequest
. The signature of this type has also changed:
type SpaceRequest = {
minWidth: number;
minHeight: number;
}
-
SelectionArea
type has been removed.SelectionArea
was no longer needed afterDragBoxLayer
was added in v0.54.0, but the type was mistakenly left in. -
_Accessor
-->Accessor
and now takes a generic. The signature has also changed:
export interface Accessor<T> {
(datum: any, index: number, dataset: Dataset): T;
}
- The
Extent
type has been renamed toRange
:
export type Range = {
min: number;
max: number;
}
-
_Projector
has been renamed toProjector
. - The
PlotData
type has been removed. TheEntity
type has been created to represent a visual entity inside aComponent
:
export interface Entity<C extends Component> {
datum: any;
position: Point;
selection: d3.Selection<any>;
component: C;
}
Methods that previously returned PlotData
now use the PlotEntity
type:
interface PlotEntity extends Entity<Plot> {
dataset: Dataset;
index: number;
component: Plot;
}
Unlike PlotData
, an PlotEntity
corresponds to exactly one datum and its visual representation on the screen.
- The type
StringAccessor
has been removed, as there are no Plottable API points that use it.
Since the Scale
s are supplied through the property setters for a Plot
, specifying them in the constructor
is redundant.
With global find-replace (with regular expressions):
-
FIND:
(\.Plots\.[^\(]*\()[^,\)]*(, )?[^\),]*(, )*
-
REPLACE:
$1
-
_anchor()
->anchor()
-
_computeLayout()
->computeLayout()
. The signature of this method has also been changed to:
computeLayout(origin?: Point, availableWidth?: number, availableHeight?: number);
-
_doRender()
->renderImmediately()
-
hitBox()
removed. See "Interaction
changes" for details. -
_isFixedWidth()
->fixedWidth()
-
_isFixedHeight()
->fixedHeight()
-
registerInteraction()
removed. To attach anInteraction
to aComponent
:
// previously: component.registerInteraction(interaction);
interaction.attachTo(component);
See "Interaction
changes" for details.
-
remove()
->destroy()
-
_render()
->render()
-
_requestedSpace()
->requestedSpace()
-
xAlign() / yAlign()
->xAlignment() / yAlignment()
-
.addComponent(Component, boolean)
->append(Component)
- Added
has(Component)
. -
removeComponent(component)
->remove(component)
-
onEvent(key, callback)
->onEvent(callback)
-
onEvent(key, null)
->offEvent(callback)
to removecallback
See "Registering for events" for details.
-
getLastMousePosition()
-->lastMousePosition()
- Constructor takes in a
Dataset
instead of astring
key -
_getPixelPoint()
has been moved toPlot
. -
setClass()
endpoint has been removed. -
_getRenderArea()
andsetup(Selection)
have been combined intorenderArea()
, which functions as a getter-setter. -
_getSelector()
-->selector()
-
_getSelection()
-->selectionForIndex()
-
svgElement()
endpoint has been removed.
Has been renamed to Drawers.Rectangle
.
The label-drawing functionality has been moved to Plots.Bar
. Consequently:
-
drawText()
has been removed -
removeLabels()
has been removed -
_getIfLabelsTooWide()
has been removed
-
.sortFunction()
->.comparator()
-
scale()
-->colorScale()
-
entitiesAt()
replacesgetEntry()
and returnsEntity<Legend>[]
(see the section on type changes for details onEntity
).
Dataset
s are now manipulated by direct references rather than string
keys. See "Working With Datasets" for details.
-
datasetOrder()
removed. Usedatasets()
to set the order of theDataset
s. -
addDataset()
andremoveDataset()
now only acceptDataset
s:
public addDataset(dataset: Dataset);
public removeDataset(dataset: Dataset);
-
getAllSelections()
andgetAllPlotData()
now take inDataset[]
. -
getAllSelections()
no longer takes aboolean
"exclude" parameter. To getSelection
s for a certain subset ofDataset
s:
var datasetsToExclude = [...];
var datasetExclusionFilter = function(dataset) { return datasetsToExclude.indexOf(dataset) === -1; }
var unexcludedDatasets = plot.datasets().filter(datasetExclusionFilter);
plot.getAllSelections(unexcludedDatasets);
-
generateProjectors()
has been removed -- see "Working withDataset
s" for how to useattr()
and property setters instead. -
_Accessor
s now take in theDataset
instead of the metadata from thatDataset
. See "Changes to Types" -
project()
has been removed in favor of property setters; see "Removal ofproject()
". - Attributes set using
attr()
will now be applied directly to the DOM. See "Removal ofproject()
" for more details. -
getAllPlotData()
-->entities()
:
public entities(datasets = this.datasets()): Plots.Entity[];
-
getClosestPlotData()
-->entityNearest()
:
public entityNearest(queryPoint: Point): Plots.Entity;
-
animate()
-->animated()
, and now also functions as a getter.
The methods automaticallyAdjustXScaleOverVisiblePoints()
and automaticallyAdjustYScaleOverVisiblePoints()
have been combined into a single method, autorange()
. The autorange functionality is now set as follows:
xyPlot.autorange("x"); // to adjust the x scale based on the y domain
xyPlot.autorange("y"); // to adjust the y scale based on the x domain
xyPlot.autorange("none"); // to disable autorange functionality.
StackedPlot
was transformed into a set of static
utilities called Plottable.Utils.Stacked
.
- The orientation is now set in the constructor as follows:
new Plots.Bar(Plots.Bar.ORIENTATION_VERTICAL);
new Plots.Bar(Plots.Bar.ORIENTATION_HORIZONTAL);
- The orientation can now be retrieved with
orientation()
. - The
barAlignment()
endpoint has been removed. The original goal for that API point was to allow for histogram-like visualizations, but having a properHistogram
class would be a better way of supporting that goal. -
barLabelFormatter()
->labelFormatter()
-
barLabelsEnabled()
->labelsEnabled()
-
labelFormatter()
-->labelsFormatter()
-
baseline()
->baselineValue()
*baselineValue()
now operates onX|Y
, instead ofnumber
:
baselineValue(): X | Y;
baselineValue(value: X | Y): Bar<X, Y>;
-
getBars
has been split into
public entitiesAt(p: Point): Entity[];
and
public entitiesIn(bounds: Bounds): Entity[];
public entitiesIn(xRange: Range, yRange: Range): Entity[];
-
Plots.Grid
's functionality has been rolled intoPlots.Rectangle
. - The constructor no longer takes in a
Scales.InterpolatedColor
. Instead, theScales.InterpolatedColor
to be used should be set usingattr()
:
var interpolatedColorScale = new Plottable.Scales.InterpolatedColor();
gridPlot.attr("fill", function(d) { return d.value; }, interpolatedColorScale);
- The
x()
/x2()
properties use the sameScale
, as do they()
/y2()
properties. As a result, thex2()
andy2()
property setters do not take in aScale
.
Domainer
s have been removed, and their functionality moved to QuantitativeScale
. See "Replacing Domainer
s" for details.
Scale
s now work with IncludedValuesProvider
s. An IncludedValuesProvider
is a function that returns an array of domain values:
interface IncludedValuesProvider<D> {
(scale: Scale<D, any>): D[];
}
The returned values will be included in the domain of the Scale
when it autoDomain()
s.
IncludedValuesProvider
s are added and removed from a Scale
with the following methods on Scale
:
addIncludedValuesProvider(provider: Scales.IncludedValuesProvider<D>): Scale<D, R>;
removeIncludedValuesProvider(provider: Scales.IncludedValuesProvider<D>): Scale<D, R>;
-
copy()
removed. If this method is important to your use-case, please contact us or file an issue and we'll help you out.
-
clamp()
removed. -
interpolate()
removed. -
rangeRound()
removed. -
numTicks()
has been removed because it didn't actually deliver on its intended functionality:numTicks(count)
did not guarantee exactly count ticks would be drawn. In many cases, setting an exact number of ticks would also lead to non-round numbers. We're working on building out a better API point that better conveys the intended functionality.
If any of the above methods are important to your use-case, please contact us or file an issue and we'll help you out.
*getDefaultTicks()
--> defaultTicks()
-
padProportion(number)
has been added. This method can be used to set the how much padding occurs on aQuantitativeScale
whenautoDomain()
-ing. The method is passed an argument signifying how much larger the padded domain should be, relative to the size of the original domain. For example,padProportion(0.5)
will cause the padded domain to be about 50% larger than the unpadded domain.padProportion(0)
disables padding.QuantitativeScale
s have apadProportion()
of 0.05 by default. -
QuantitativeScale
s now work withPaddingExceptionsProvider
s:
export interface PaddingExceptionsProvider<D> {
(scale: QuantitativeScale<D>): D[];
}
A PaddingExceptionsProvider
is a function that returns an array of domain values. If any of those values are either end of the domain computed when autoDomain()
-ing, that end of the domain will not be padded.
PaddingExceptionsProvider
can be added and removed from the QuantitativeScale
with the following methods:
addPaddingExceptionsProvider(provider: Scales.PaddingExceptionsProvider<D>): QuantitativeScale<D>;
removePaddingExceptionsProvider(provider: Scales.PaddingExceptionsProvider<D>): QuantitativeScale<D>;
Scales.Log
has been deprecated for a while, and has now been removed. ModifiedLog
is recommended as a replacement due to its better behavior when autoDomain()
ing, as well as its better support for negative numbers.
- The
showIntermediateTicks()
endpoint has been removed. To exercise more control over which ticks are displayed, assign a customTickGenerator
to theScale
.
-
addComponent(row, col, component)
->add(component, row, col)
-
_removeComponent(component)
->remove(component)
-
colWeight()
->columnWeight()
-
padding()
has been split intorowPadding()
andcolumnPadding()
-
orientation(orientation: string)
is nowangle(angle: number)
. Supported angles are -90, 0 (horizontal), and 90.
Plottable.Label(displayText = "", angle = 0);
-
orient()
->orientation()
-
showEndTickLabel()
removed; The method didn't actually do anything.
-
.setRenderPolicy()
no longer takes aRenderPolicy
. The followingstring
y enums are available:
export module Policy {
export var IMMEDIATE = "immediate";
export var ANIMATION_FRAME = "animationframe";
export var TIMEOUT = "timeout";
}
-
getTiming()
-->totalTime()
-
Animators.Rect
andAnimators.MovingRect
have been removed. Their logic was very specific towards the use case inPlots.Bar
, which now uses a properly configuredAnimators.Base
instead. If you are interested in the animation logic used in those animators, please contact us.
Plottable.Utils.Methods
has been split into multiple modules. As a result, the module hierarchy (and sometimes the name of the method itself) have been changed changed:
Utils.Methods.inRange() -> Utils.Math.inRange();
Utils.Methods.clamp() -> Utils.Math.clamp();
Utils.Methods.max() -> Utils.Math.max();
Utils.Methods.min() -> Utils.Math.min();
Utils.Methods.isNaN() -> Utils.Math.isNaN();
Utils.Methods.isValidNumber() -> Utils.Math.isValidNumber();
Utils.Methods.range() -> Utils.Math.range();
Utils.Methods.distanceSquared() -> Utils.Math.distanceSquared();
Utils.Methods.addArrays() -> Utils.Array.add();
Utils.Methods.uniq() -> Utils.Array.uniq();
Utils.Methods.createFilledArray() -> Utils.Array.createFilledArray();
Utils.Methods.flatten() -> Utils.Array.flatten();
Utils.Methods.arrayEq() -> DELETED
Utils.Methods.copyMap() -> Utils.Window.copyObject();
Utils.Methods.populateMap() -> DELETED
Utils.Methods.warn() -> Utils.Window.warn();
Utils.Methods.setTimeout() -> Utils.Window.setTimeout();
Utils.Methods.objEq() -> DELETED
Utils.Methods.isIE() -> DELETED
Utils.Methods.parseRange() -> DELETED
Utils.Methods.colorTest() -> Utils.Color.colorTest();
Utils.Methods.lightenColor() -> Utils.Color.lightenColor();
Utils.Methods.intersectsBBox() -> Utils.DOM.intersectsBBox();
The semantics of adding Component
s to Group
s and Table
s has been improved. To add a Component
to a Group
:
// previously: group.addComponent(component);
group.append(component);
To add a Component
to a Table
:
// previously: table.addComponent(rowIndex, columnIndex, component);
table.add(component, rowIndex, columnIndex);
To convert to the new API:
-
FIND:
\.addComponent\((\d+),\s*(\d+),\s*([^)]+)\)
-
REPLACE:
\.add($3, $1, $2)
above()
and below()
had some odd behavior -- combining two non-Group
Component
s would create a Group
out of nowhere, but if the caller or target was a Group
the non-Group
Component
would be added to the existing Group
. If both caller and target were Group
s one would be appended to the other, but it wasn't clear which way that would be.
Consequently, we have removed these API points. A Group
must be explicitly created to group multiple Component
s:
// previously: component1.above(component2);
var group = new Plottable.Components.Group([component2, component1]);
// previously: component1.below(component2);
var group = new Plottable.Components.Group([component1, component2]);
// previously: group.below(component);
group.append(component);
Continuing with the theme of not creating Group
s automatically, adding a Component
to an occupied cell in a Table
will now throw an error. To put multiple Component
s in the same cell of a Table
, add the Component
s to a Group
, then place the Group
in that cell.
Previously, a callback was removed like this:
clickInteraction.onClick(null);
Now, to remove a callback:
clickInteraction.offClick(callback); // === operator is used to decide which callback to remove
where callback
is the callback that was originally passed in to the registration call (onClick()
in this case).
project()
previously performed a lot of magic in the background. For example, calling .project("fill", () => "red")
, would set the "fill"
attribute in the DOM to "red"
, but calling .project("x", ...)
set a variety of DOM attributes depending on what kind of Plot
was used.
Furthermore, if the second argument to project()
was a string
, it would automatically be used as a key into the data (unless the string began with "#"...), meaning that .project("fill", "red")
didn't do what might be expected.
We have decided to remedy this by splitting the functionality of project()
into attr()
and "property setters".
attr()
previously existed as an alias for project()
. Now, it directly sets DOM attributes to the results of an Accessor
and a Scale
:
attr(attr: string, attrValue: number | string | Accessor<number> | Accessor<string>): Plot;
attr<A>(attr: string, attrValue: A | Accessor<A>, scale: Scale<A, number | string>): Plot;
Example invocations:
plot.attr("stroke-width", 2);
plot.attr("fill", "pink");
plot.attr("fill", function(d) { return d.value >= 0 ? "green" : "red"; });
plot.attr("stroke", function(d) { return d.type; }, colorScale);
The Scale
must be passed as the third argument for it to autoDomain()
over the data passing through it.
attr()
can also be invoked at as a getter that returns the AccessorScaleBinding
for a particular attribute:
interface AccessorScaleBinding {
accessor: Accessor;
scale?: Scale;
}
Property setters are methods for setting Plot
properties that are not actual DOM attributes. These have a similar signature to attr()
, taking in an Accessor
and a Scale
. For example:
x(x: number | Accessor<number>): XYPlot<X, Y>;
x(x: X | Accessor<X>, xScale: Scale<X, number>): XYPlot<X, Y>;
x()
is used to set the "x" property on an XYPlot
: the previous invocation would have been something like project("x", function(d) { return d.x; }, xScale)
. Now, instead:
plot.x(function(d) { return d.x; }, xScale);
Invoking a property setter with no arguments will return an AccessorScaleBinding
for that property.
Here is the list of property setters:
- All
XYPlot
s:x()
andy()
-
Plots.Area
:y0()
-
Plots.Grid
:x2()
andy2()
-
Plots.Pie
:innerRadius()
,outerRadius()
, andsectorValue()
-
Plots.Scatter
:size()
andsymbol()
Since keys are no longer used to register Dataset
s, operations involving Dataset
s are now done by using the Dataset
s directly. For example, to loop over all Dataset
s in a Plot
:
var datasets = plot.datasets(); // Dataset[]
datasets.forEach((dataset) => {
...
});
Reversing the order of Dataset
s in a Plot
:
plot.datasets(plot.datasets().reverse());
Methods that previously accepted keys associated with Dataset
s now take an array of Dataset
s. For example, to get the Selection
s associated with a particular Dataset
:
var selectionsOfInterest = plot.getAllSelections([datasetOfInterest]);
Previously generateProjectors()
was used to get the projectors (scaled Accessor
s) associated with particular Dataset
keys. Since the property-setting methods and attr()
now function as getters, they can be used to retrieve the AccessorScaleBinding
instead:
var yBinding = plot.y();
var yAccessor = yBinding.accessor;
var yScale = yBinding.scale;
plot.datasets().forEach((dataset) => {
var yValues = dataset.data().map((datum, index) => yAccessor(datum, index, dataset));
var scaledYValues = yValues.map((value) => yScale.scale(value));
// do something with the y-values
...
});
If a Scale
was not originally set with attr()
or the property setter, no Scale
will be present in the AccessorScaleBinding
:
plot.attr("fill", (datum) => datum.color);
...
...
var fillBinding = plot.attr("fill");
var fillAccessor = fillBinding.accessor;
var fillScale = fillBinding.scale; // will be undefined
Previously, Component
s used a transparent hitbox to detect events; Interaction
s would attach event listeners to the hitbox. However, this mechanism created a problem because the hitboxes of Component
s higher up in a Group
would block the hitboxes of Component
s below them.
All of Plottable's Interaction
s have been changed to use a different event-detecting mechanism that does not require a hitbox, so the hitbox and its associated retrieval call hitBox()
have been removed.
The semantics for attaching Interaction
s has been changed to make it clearer that an Interaction
can only be attached to one Component
at a time:
// previously: component.registerInteraction(interaction);
interaction.attachTo(component);
Interaction
s can now also be detached from Component
s:
interaction.detachFrom(component);
Domainer
s were previously used when autoDomain()
-ing a QuantitativeScale
. However, this functionality more properly belongs on the QuantitativeScale
itself, so it has been moved there:
padProportion(): number;
padProportion(padProportion: number): QuantitativeScale<D>;
addPaddingExceptionsProvider(provider: Scales.PaddingExceptionsProvider<D>): QuantitativeScale<D>;
removePaddingExceptionsProvider(provider: Scales.PaddingExceptionsProvider<D>): QuantitativeScale<D>;
addIncludedValuesProvider(provider: Scales.IncludedValuesProvider<D>): Scale<D, R>;
removeIncludedValuesProvider(provider: Scales.IncludedValuesProvider<D>): Scale<D, R>;
See here and here for details on how to use those methods.
If you were previously extending Domainer
to control the min and max values on the QuantitativeScale
's domain, we have added two methods for setting only one end of the domain on QuantitativeScale
:
-
domainMin()
sets the lower end of the domain. -
domainMax()
sets the upper end of the domain.
If only one is set, the other end of the scale will behave as though it was autoDomain()
-ed.
Calling both domainMin(min)
and domainMax(max) is equivalent to calling
domain([min, max]). Setting both can reverse the domain on
QuantitativeScale`s that support reversal.
Calling autoDomain()
will clear both set values, the same way calling autoDomain()
overrides domain()
.
Example fiddle: http://jsfiddle.net/fv2a2jej/
If you were previously using a Scales.Color
inside an Accessor
:
plot.project("fill", function(d) { return colorScale.scale(d.type); });
The Scale
's domain would have expanded to cover all the data, which was an error. Scale
s must be passed as the third argument to attr()
(or the second argument to the property setters) for the Scale
to autoDomain()
over all the data. Instead, do this:
plot.attr("fill", function(d) { return d.type; }, colorScale);