-
Notifications
You must be signed in to change notification settings - Fork 227
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 Plots 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; }
-
SelectionAreatype has been removed.SelectionAreawas no longer needed afterDragBoxLayerwas added in v0.54.0, but the type was mistakenly left in. -
_Accessor-->Accessorand now takes a generic. The signature has also changed:export interface Accessor<T> { (datum: any, index: number, dataset: Dataset): T; }
-
The
Extenttype has been renamed toRange:export type Range = { min: number; max: number; }
-
_Projectorhas been renamed toProjector. -
The
PlotDatatype has been removed. TheEntitytype 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:
```Typescript
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
StringAccessorhas been removed, as there are no Plottable API points that use it. - The type
Animators.Plothas been renamed toAnimator.
Since the Scales 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 "Interactionchanges" for details. -
_isFixedWidth()->fixedWidth() -
_isFixedHeight()->fixedHeight() -
registerInteraction()removed. To attach anInteractionto aComponent:// previously: component.registerInteraction(interaction); interaction.attachTo(component);
See "Interaction changes" for details.
-
remove()->destroy() -
_render()->render() -
_requestedSpace()->requestedSpace() -
xAlign() / yAlign()->xAlignment() / yAlignment() -
classed()has been split into three methods:hasClass(cssClass: string): boolean; addClass(cssClass: string): Component; removeClass(cssClass: string): Component;
-
.addComponent(Component, boolean)->append(Component) - Added
has(Component). -
removeComponent(component)->remove(component)
-
onEvent(key, callback)->onEvent(callback) -
onEvent(key, null)->offEvent(callback)to removecallbackSee "Registering for events" for details.
-
getLastMousePosition()-->lastMousePosition()
- Constructor takes in a
Datasetinstead of astringkey -
_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() - added
totalTime(), which returns the total time that would be spent drawing (in milliseconds). -
draw()now returns the callingDrawer, instead of the total time that would be spent drawing.
- No longer extends
Drawer.Line.
- This class has been removed and its functionality folded into the parent
Drawerclass.
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
-
constrainToComponent()-->constrainedToComponent()
-
scale()-->colorScale() -
sortFunction()->comparator() -
symbolFactoryAccessor()->symbol() -
entitiesAt()replacesgetEntry()and returnsEntity<Legend>[](see the section on type changes for details onEntity).
Datasets are now manipulated by direct references rather than string keys. See "Working With Datasets" for details.
-
datasetOrder()removed. Usedatasets()to set the order of theDatasets. -
addDataset()andremoveDataset()now only acceptDatasets:public addDataset(dataset: Dataset); public removeDataset(dataset: Dataset);
-
getAllSelections()-->selections(). -
getAllPlotData()-->entities():public entities(datasets = this.datasets()): Plots.Entity[];
-
getClosestPlotData()-->entityNearest():public entityNearest(queryPoint: Point): Plots.Entity;
-
selections()andentities()now take inDataset[]. -
selections()no longer takes aboolean"exclude" parameter. To getSelections for a certain subset ofDatasets:var datasetsToExclude = [...]; var datasetExclusionFilter = function(dataset) { return datasetsToExclude.indexOf(dataset) === -1; } var unexcludedDatasets = plot.datasets().filter(datasetExclusionFilter); plot.selections(unexcludedDatasets);
-
generateProjectors()has been removed -- see "Working withDatasets" for how to useattr()and property setters instead. -
_Accessors now take in theDatasetinstead 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. -
animate()-->animated(), and now also functions as a getter.
The methods automaticallyAdjustXScaleOverVisiblePoints() and automaticallyAdjustYScaleOverVisiblePoints() have been combined into a single method, autorangeMode(). The autorange functionality is now set as follows:
```Typescript
xyPlot.autorangeMode("x"); // to adjust the x scale based on the y domain
xyPlot.autorangeMode("y"); // to adjust the y scale based on the x domain
xyPlot.autorangeMode("none"); // to disable autorange functionality.
```
StackedPlot was transformed into a set of static utilities called Plottable.Utils.Stacking.
-
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 properHistogramclass would be a better way of supporting that goal. -
barLabelFormatter()->labelFormatter() -
barLabelsEnabled()->labelsEnabled() -
baseline()->baselineValue()*baselineValue()now operates onX|Y, instead ofnumber:baselineValue(): X | Y; baselineValue(value: X | Y): Bar<X, Y>;
-
getBarshas been split intopublic entitiesAt(p: Point): Entity[];
and
```Typescript
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.InterpolatedColorto 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.
Domainers have been removed, and their functionality moved to QuantitativeScale. See "Replacing Domainers" for details.
Scales now work with IncludedValuesProviders. An IncludedValuesProvider is a function that returns an array of domain values:
```Typescript
interface IncludedValuesProvider<D> {
(scale: Scale<D, any>): D[];
}
```
The returned values will be included in the domain of the Scale when it autoDomain()s.
IncludedValuesProviders are added and removed from a Scale with the following methods on Scale:
```Typescript
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 aQuantitativeScalewhenautoDomain()-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.QuantitativeScales have apadProportion()of 0.05 by default. -
QuantitativeScales now work withPaddingExceptionsProviders: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:
```Typescript
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 customTickGeneratorto theScale.
-
colorRange()->range() -
The
constructorno longer takes in the color range, bringing it more in line with the constructor onScales.Color:constructor(scaleType?: string);
To set the color range, call range() after construction.
-
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);
-
gutter()->margin() -
orient()->orientation() - No longer accepts a
Formatterin the constructor. Useformatter()to set theFormatterafter construction.
-
showEndTickLabel()removed; The method didn't actually do anything.
-
setRenderPolicy()-->renderPolicy(), and now also functions as a getter. -
.renderPolicy()no longer takes aRenderPolicy. The followingstringy enums are available:export module Policy { export var IMMEDIATE = "immediate"; export var ANIMATION_FRAME = "animationframe"; export var TIMEOUT = "timeout"; }
-
getTiming()-->totalTime()
A number of renames for clarity:
-
delay()->startDelay() -
duration()->stepDuration() -
easing()->easingMode() -
maxIterativeDelay->stepDelay() -
maxTotalDuration()now defaults toInfinity. The maximum total duration of animations onPlots remains at the old default of 600ms. -
staticfieldsDEFAULT_START_DELAY_MILLISECONDS,DEFAULT_STEP_DURATION_MILLISECONDS,DEFAULT_ITERATIVE_DELAY_MILLISECONDS,DEFAULT_MAX_TOTAL_DURATION_MILLISECONDS, andDEFAULT_EASINGhave been removed. The default values can be queried by creating a newAnimators.Easingand calling the appropriate getters.
-
Animators.RectandAnimators.MovingRecthave been removed. Their logic was very specific towards the use case inPlots.Bar, which now uses a properly configuredAnimators.Baseinstead. 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() -> DELETED
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();
-
getBBox()->elementBBox() -
getElementWidth()->elementWidth() -
getElementHeight()->elementHeight() -
getBoundingSVG()->boundingSVG() -
getUniqueClipPathId()->generateUniqueClipPathId() -
getSVGPixelWidth()-> REMOVED -
getParsedStyleValue()-> REMOVED -
isSelectionRemovedFromSVG()-> REMOVED If you were using the removed methods, please contact us.
The semantics of adding Components to Groups and Tables 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 Components 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 Groups 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 Components:
// 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 Groups automatically, adding a Component to an occupied cell in a Table will now throw an error. To put multiple Components in the same cell of a Table, add the Components 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 removewhere 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
XYPlots: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 Datasets, operations involving Datasets are now done by using the Datasets directly. For example, to loop over all Datasets in a Plot:
var datasets = plot.datasets(); // Dataset[]
datasets.forEach((dataset) => {
...
});Reversing the order of Datasets in a Plot:
plot.datasets(plot.datasets().reverse());Methods that previously accepted keys associated with Datasets now take an array of Datasets. For example, to get the Selections associated with a particular Dataset:
var selectionsOfInterest = plot.getAllSelections([datasetOfInterest]);Previously generateProjectors() was used to get the projectors (scaled Accessors) 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 undefinedPreviously, Components used a transparent hitbox to detect events; Interactions would attach event listeners to the hitbox. However, this mechanism created a problem because the hitboxes of Components higher up in a Group would block the hitboxes of Components below them.
All of Plottable's Interactions 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 Interactions 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);Interactions can now also be detached from Components:
interaction.detachFrom(component);Domainers 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. Scales 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);