Skip to content

Releases: palantir/plottable

Typescript Upgrades and Bugfixes

13 Feb 23:10
Compare
Choose a tag to compare
Pre-release

Good Afternoon,

This release took care of a lot of requested bugfixes, cleaned up the visual appearance of Axis.Time further, and contains several Typescript upgrades. It also contains several breaking changes in preparation for v1.0, so please look at the breaking changes section if you were using Axis.Time or are developing in TypeScript.

Features

  • Setting a reversed domain on a Scale.Time will now throw an error.

Bugfixes

  • Components are now hidden when the SVG is hidden in Firefox (#1033).
  • AreaPlot and LinePlot now retain their respective path classes after class is set via a project call (#1286).
  • Interaction.Drag's dragend() call is now constrained within its Component's hitbox (#1445).
  • The end-tick-mark class is now accessible on TimeAxis end ticks (#1575).
  • TimeAxis rendering issues have been fixed (#1609).

API-Breaking Changes

  • As per the migration to use the "type" structure, the TimeAxisConfiguration interface has been converted to just be an aliased type of a TimeAxisTierConfiguration array. Thus the TimeAxisConfiguration no longer has a "tierConfiguration" parameter that holds the array.
  • The listenable field of a Broadcaster has been made private (and renamed to _listenable).

Typescript API Breaks

  • As of now, we are now incorporating features from Typescript 1.4 that did not exist in Typescript 1.3. As a result, our library is now incompatible with Typescript 1.3.
  • Many "interfaces" have been converted to the more simpler "type" structure using the type aliasing feature introduced in Typescript 1.4 (http://blogs.msdn.com/b/typescript/archive/2015/01/16/announcing-typescript-1-4.aspx), and thus cannot be extended or implemented as an interface would be.

Broadcaster changes:

  • The Listenable type has been removed, and Broadcasters can now broadcast about arbitrary types.
  • Broadcasters now use generics to specify what they are broadcasting about; for example, a Broadcaster<Dataset> will pass a Dataset to its callbacks.
  • The listenable field of a Broadcaster has been made private (and renamed to _listenable).

Other notes

Upgrade Instructions

  • If you were using a TimeAxisConfiguration object to store your tier configurations, they no longer have the configurations stored in a "tierConfiguration" parameter. Instead the TimeAxisTierConfigration array is instead itself a TimeAxisConfiguration.
  • Typescript users - Please upgrade to Typescript 1.4
  • Typescript users - Remove any references to the Listenable type. Broadcasters should be initialized with a generic type corresponding to what they are broadcasting about.

Hotfix for Axis.Time

10 Feb 02:13
Compare
Choose a tag to compare
Hotfix for Axis.Time Pre-release
Pre-release

Tick marks showing the ends of the first and last time periods on Axis.Time were not being drawn. This release contains a hotfix for that bug (#1606).

Ordinal Scale Revamp, Origin Methods

06 Feb 23:08
Compare
Choose a tag to compare
Pre-release

Good afternoon,

This release features some major changes to Scale.Ordinal, as well as methods for querying the origin of Components.

Features

Scale.Ordinal revamp

  • Scale.Ordinal used to have two modes for how they map their domain onto the range: "points" and "bands". Not only did this create confusion, but some Plots would render inconsistently if the Scale was in the wrong mode. Scale.Ordinal now has only one mode.
  • The scale() method on Scale.Ordinal now scales to the center of the band, not the start:
    scalechange
  • innerPadding() and outerPadding() are now defined as proportion of the band width.
    • innerPadding is defined as the padding in between bands.
    • outerPadding is defined as the padding between the outer bands and the edge of the scale.
    • fullBandStartAndWidth() has been removed in favor of stepWidth(). stepWidth() method returns the distance between successive values on the scale, in pixels.

Component Origin Methods

Two methods have been added to Components:

  • origin() gets the location of the Component's upper-left-corner relative to its parent.
  • originToSVG() gets the location of the Component's upper-left corner relative to the root <svg> node.

Bugfixes

  • Bar plots now account for the ends of the Scale when automatically computing bar widths.
  • Axis labels are now confined to the Axis's bounding-box within the <svg> (#1501)
  • End ticks are consistently visible on both ends of an Axis.Time (#1509)
  • Tick labels now show up at regular intervals (#1196)

API Breaks

  • innerPadding() and scale() methods on Scale.Ordinal now behave very differently.
  • fullBandStartAndWidth has been renamed and revamped into stepWidth()

Upgrade Instructions

  • The innerPadding() method on Scale.Ordinal used to return the padding in pixels; now it returns the padding as a proportion of the band width. ordinalScale.bandWidth() * ordinalScale.innerPadding() will calculate the padding in pixels.
  • Since scale() now returns the position corresponding to the middle of the band, ordinalScale.scale(value) - ordinalScale.rangeBand() / 2 will yield the position at the start of the band.
  • fullBandStartAndWidth() can be replaced by the above calculation and stepWidth().

Future Changes

  • As we have upgraded our library to use Typescript 1.4, we are moving in the near future to actually use some of its features like union typing. Our library as of the current moment should still be compatible with Typescript 1.3, but we will not be compatible with it in the near future.

InterpolatedColorLegend, getAllSelections()

30 Jan 22:32
Compare
Choose a tag to compare

screen shot 2015-01-30 at 2 12 18 pm

Good afternoon,

Today's release adds a legend for InterpolatedColor scales, as well as an API point for retrieving the DOM nodes forming a Plot's visualization.

Features

InterpolatedColorLegend

InterpolatedColorLegend has been added. This Component visualizes a Scale.InterpolatedColor, providing some context as to what the colors represent. The constructor:

constructor(interpolatedColorScale: Scale.InterpolatedColor, orientation?: string, formatter?: Formatter);

The InterpolatedColorLegend supports three orientations: "horizontal" (default, shown above), "left", and "right":

`"left"``"right"`

It also accepts a Formatter (the same kind passed to an Axis), which can be used to format the labels:
screen shot 2015-01-30 at 2 13 07 pm

As with other Plottable Components, CSS can be used to restyle it:
screen shot 2015-01-30 at 2 30 37 pm

getAllSelections()

The getAllSelections() method has been added to Plots. This method retrieves the DOM nodes associated with a Plot's visualization as a D3.Selection: on a Plot.Line, it will retrieve the <path> elements, on a Plot.Scatter it will retrieve the <circle>s, etc. This API point should open up more possibilities for dynamic styling and interactivity.

Bugfixes

Plot.Pie now displays warnings in the console when if populated with negative data values (1505). As before, console warnings can be suppressed by setting Plottable.Config.SHOW_WARNINGS to false.

API-Breaking Changes

barPlot.getAllBars() has been removed in favor of getAllSelections().

Other notes

The color of text in Legend and InterpolatedColorLegend has been changed to match that used on Axis. See plottable.css for details.

Upgrade Instructions

If you were using barPlot.getAllBars(), please replace that call with barPlot.getAllSelections().

Future Changes

To go with getAllSelections(), we plan to implement methods for retrieving selections associated with specific Datasets, or associated with specific pixel positions / ranges (similar to the existing getBars() API point on Bar plots).

PanZoom and Scale.Color bugfixes

24 Jan 03:45
Compare
Choose a tag to compare
Pre-release

Good evening,

Tonight's release includes fixes for Interaction.Panzoom and Scale.Color:

  • Interaction.Panzoom now properly updates when the domain of either of its Scales changes (#1388).
  • Scale.Color now works with named colors ("blue", "green", etc) in its range (#1527).

Other notes

As of this release, Plottable is now using Typescript 1.4, which introduces union types, amongst other things. Details can be found here: http://blogs.msdn.com/b/typescript/archive/2015/01/16/announcing-typescript-1-4.aspx

Unified Plot.Bar, StackedPlot dataset update

20 Jan 16:33
Compare
Choose a tag to compare

Good morning,

This release includes a bugfix for stacked Plots (StackedArea, StackedBar), as well as the removal of Plot.VerticalBar and Plot.HorizontalBar from the API.

Bugfixes

Scales on stacked Plots now update correctly when Datasets are updated (#1246).

API Breaks

Plot.VerticalBar and Plot.HorizontalBar have been removed from the codebase, as warned in the release notes for v0.40.0. Please use Plot.Bar from this point forward.

Upgrade Instructions

As noted in the previous release, you will need to change references to Plot.VerticalBar and Plot.HorizontalBar as follows:

new Plot.VerticalBar(xScale, yScale)  new Plot.Bar(xScale, yScale, true)
new Plot.HorizontalBar(xScale, yScale)  new Plot.Bar(xScale, yScale, false)

In addition, invocations of barAlignment() on Plot.HorizontalBar also should be updated:

horizontalBarPlot.barAlignment("top")  barPlot.barAlignment("left")
horizontalBarPlot.barAlignment("bottom")  barPlot.barAlignment("right")

Improved Layout, Improved Text, and Unified Bar Plot

20 Dec 02:47
Compare
Choose a tag to compare

Features

Unified Plot.Bar

  • Plot.HorizontalBar and Plot.VerticalBar have been merged into a single class Plot.Bar. In order to choose between the two, an additional parameter has been added to the Plot.Bar constructor specifying if the Plot.Bar should be vertical (default true):
/**
 * Constructs a Bar plot.
 *
 * @constructor
 * @param {Scale} xScale The x scale to use.
 * @param {Scale} yScale The y scale to use.
 * @param {boolean} isVertical if the plot if vertical.
 */
constructor(xScale: Scale.AbstractScale<X, number>,
            yScale: Scale.AbstractScale<Y, number>,
            isVertical = true) {

The classes Plot.HorizontalBar and Plot.VerticalBar have been deprecated.

Bugfixes

svg-typewriter

Writing text in SVG has always been tricky. The svg text spec indicates that "SVG performs no automatic line breaking or word wrapping", meaning that developers have to implement this functionality themselves; In addition, it is difficult to accurately measure the size of text without writing it.

We have switched to using svg-typewriter to resolve these problems. Consequently, a number of issues related to text have been fixed.

SVG Typewriter was developed by @endrjuskr. The library is inlined within Plottable as part of our build process, so there are no changes required to develop using Plottable.

Improved Layout Engine

@endrjuskr has updated our layout engine, which powers the Table Component. In conjunction with the switch to svg-typewriter, this change solves some strange behavior on Axis.Category, as well as other bugs such as #936

API Breaks

Aside from the now-deprecated Plot.HorizontalBar, the barAlignment() method on Bar Plots now only accepts "left", "center", and "right" as alignment choices, regardless of if the Plot is vertical or horizontal.

Typescript API Breaks

Plot.AbstractBar has been renamed to Plot.Bar. References to Plot.AbstractBar should be changed to references to Plot.Bar.

Upgrade Instructions

You will need to change references to Plot.VerticalBar and Plot.HorizontalBar as follows:

new Plot.VerticalBar(xScale, yScale)  new Plot.Bar(xScale, yScale, true)
new Plot.HorizontalBar(xScale, yScale)  new Plot.Bar(xScale, yScale, false)

In addition, invocations of barAlignment() on Plot.HorizontalBar also should be updated:

horizontalBarPlot.barAlignment("top")  barPlot.barAlignment("left")
horizontalBarPlot.barAlignment("bottom")  barPlot.barAlignment("right")

Release Song

Time to Say Goodbye (to layout bugs).

Legend Upgrades

13 Dec 01:43
Compare
Choose a tag to compare
Legend Upgrades Pre-release
Pre-release

Good afternoon,

This release features upgrades to Legend.

Legend upgrades

  • HorizontalLegend and Legend have been merged into a single class, Legend.
  • Legend now features a maxEntriesPerRow(numEntries) API point. The Legend will draw at most numEntries entries per row (default 1), although it may draw fewer if the space is constrained. Setting maxEntriesPerRow(Infinity) on a Legend will replicate the behavior of HorizontalLegend.
  • Legend also features a getEntry(<Point>) method, which can be used to retrieve the Legend entry under a given point. This method should be useful in implementing custom Interaction behavior on Legend; see "API-Breaking changes and Upgrade Instructions", below.
  • The order of entries on a Legend can now be set using the sortFunction() method, which takes a compareFunction similar to that supplied to the native sort function. Example comparators:
function alphabetize(a, b) {
  return (a < b) ? -1 : 1;
}
function reverseDomain(a, b) {
  var domain = colorScale.domain();
  return domain.indexOf(b) - domain.indexOf(a);
}

Other features

  • The foreground, background, and hitBox Selections on Component can now be retrieved with foreground(), background(), and hitBox().
  • A Plottable object's ID can now be retrieved through the getID() API call. The IDs are unique per loading of the Plottable library.

Bugfixes

  • Components in a Group now respect the alignments set using xAlign() and yAlign() (#1255).
  • automaticallyAdjustXScaleOverVisiblePoints and automaticallyAdjustYScaleOverVisiblePoints now work on Plot.StackedBar and Plot.StackedArea.

Typescript Upgrade

One month ago, Typescript 1.3 was released. We have now upgraded to the 1.3 compiler to take advantage of its new features, in particular the protected keyword. We have now changed class fields to the protected scope where appropriate. If you are developing on Plottable, please be sure to upgrade to Typescript 1.3.

API-Breaking changes and Upgrade Instructions

  • HorizontalLegend has been merged into Legend. All uses of HorizontalLegend should be replaced with Legend. You will need to call maxEntriesPerRow(Infinity) on the Legend to get the behavior of HorizontalLegend.
  • Legend no longer has built-in API points for setting click and hover callbacks. While this structure was convenient, the correct way to build click and hover interactivity is using Interactions, not by attaching the logic to Legend. Click interactivity on Legend can be reconstructed as follows:
var click = new Plottable.Interaction.Click();
click.callback(function(point) {
  var entry = legend.getEntry(point);
  if (!entry.empty()) {
    // entry is a D3 selection, so apply classes, etc
    ...
    var data = entry.data()[0]; // retrieve the data
    ...
  }
});
legend.registerInteraction(click);
  • We plan to extend the capabilities of Interaction.Hover to Legend shortly. For details on a workaround, please contact us.

Release Song

The Legend of Zelda Main Theme Medley

Hover Interactivity for Stacked Area, API Changes for Consistency

06 Dec 00:59
Compare
Choose a tag to compare

Good afternoon,

Today's release adds hover interactivity to stacked area plots, and features some updates to improve the consistency of our API. Read on for more details.

Features

Interaction.Hover now works with Plot.StackedArea. Note that, as for Plot.StackedBar, the original data value will be returned, not the stacked value.

Whenever a domain value is scaled with Plottable.Scale.Color and the domain's length is greater than the range length, the returned scale value will be lightened in accordance to how many times the range has looped around to reach the scaled value.

API Breaking Changes

Removal of default accessors

Previously, most Plots were packaged with default accessors that looked for "x" and "y" attributes on the data. Essentially, the following lines were run when a Plot was constructed:

this.project("x", "x", xScale); // default accessor
this.project("y", "y", yScale); // default accessor

While sometimes convenient, the default accessors would sometimes return undefined or invalid data. Their presence made it difficult for the Plottable code to reason about when the user had completed setting up a Plot and it was safe to autodomain the scales or calculate the stacking offsets. Rather than try to reason about if a given projector was valid (a tricky problem if, for instance, the user meant to plot null or undefined values), we now operate under the assumption that if the user calls project(), the supplied accessor is valid.

Similarly, the default value accessor has been removed from Plot.Pie.

deselectAll() removed

The deselectAll() method has been removed from Bar plots. deselectAll() removed the "selected" CSS class from all bars in a bar Plot; With the removal of selectBar() in v0.37.0, deselectAll() no longer made sense.

Typescript API-Breaking Changes

Plot.StackedArea now extends from Plot.Area instead of Plot.AbstractStacked.

Other notes

Plottable has a number of protected/private internal variables and methods. We have now prefixed these fields with an underscore to indicate to the user that they should not be using them. Be warned that using/accessing these fields may result in behavior that you may not expect, as changes to these fields may break your code silently. Please use such variables/methods with extreme caution.

Upgrade Instructions

  • If you were previously relying on the default accessor behavior, as described above, add the following two lines after an XY-Plot is created:
xyPlot.project("x", "x", xScale);
xyPlot.project("y", "y", yScale);
  • Similarly, if you were relying on the default accessor behavior for Plot.Pie, add the following line after creating the Plot.Pie:
piePlot.project("value", "value");
  • If you were using deselectAll(), please replace it with the following line:
barPlot.getAllBars().classed("selected", false);

Future Changes

  • We are planning to lighten up the Plot constructors by having them no longer take Scales as arguments. The xScale and yScale arguments to the Plot are essentially redundant since the scales will be applied during the relevant project() calls, meaning that the constructor arguments are not particularly useful.
  • @endrjuskr has been working on a library for manipulating SVG text. We are looking to start using this library in Plottable, which should improve the behavior of text in Axis, Legend, and other places within Plottable.

Release Song

Katamari on the Rocks

Resizeable Drag Boxes, Bar Selection Improvements, Metadata, Time Axis Configuration

19 Nov 01:51
Compare
Choose a tag to compare

Good evening,

Tonight's release features improvements to bar selection, metadata in accessors, and configurable time axes.

Features

Resizeable Dragboxes

Drag boxes created with Interaction.DragBox, Interaction.XDragBox, and Interaction.YDragBox can be resized by dragging the sides or the corners of the box.
This feature can be enabled by calling resizeEnabled(true). Here is an example:
http://jsfiddle.net/2q1kojwn/

Bar Selection

  • getBars() has been added to Bar Plots. The function takes in x and y pixel values or extents ({min: number, max: number}) and returns a D3.Selection consisting of any bars under the point/line/area. Unlike selectBar(), the bars will not receive the selected class.
  • getAllBars() has been added to Bar Plots. When called, getAllBars() will return a D3.Selection that contains all the bars in that plot.

These two methods should make it easier to write Interaction callbacks.

Plot Metadata

Accessors passed to the project() call on Plots can now take up to four arguments:

(datum: any, index?: number, userMetadata?: any, plotMetadata?: Plot.PlotMetadata) => any;

The third argument, userMetadata, consists of metadata that has been added to a Dataset object; see the "Bugfixes" section for more details.
The fourth argument, plotMetadata, contains plot-specific information. Currently, it contains only datasetKey, the key associated with the Dataset being plotted. This feature can be used to differentiate datasets in a Plot:

var colorScale = new Plottable.Scale.Color("Category20b");
var dataset = new Plottable.Dataset(data);
var plot = new Plottable.Plot.Scatter(xScale, yScale)
      .addDataset(dataset)
      .project("fill", function (d, i, u, m) { return m.datasetKey; }, colorScale);

screen shot 2014-11-17 at 4 51 25 pm

Time Axis Intervals

We've been meaning for a while to provide more control over the ticks on the multi-tiered Axis.Time.

axisConfigurations() can be used to get or set the current configurations of the axis. Currently, a TimeAxisConfiguration consists of an array of TimeAxisTierConfigurations, one for each tier of the Axis:

interface TimeAxisConfiguration {
  tierConfigurations: TimeAxisTierConfiguration[];
}

Currently, up to two tiers are supported. A TimeAxisTierConfiguration specifies how the Axis should generate ticks and how to format the corresponding labels. A TimeAxisTierConfiguration consists of an interval (a time unit), a step (the number of units), and a formatter:

interface TimeAxisTierConfiguration {
  interval: D3.Time.Interval;
  step: number;
  formatter: Formatter;
};

For example, the following TimeAxisTierConfiguration:

{interval: d3.time.hour, step: 3, formatter: Formatters.time("%I %p")}

will produce a tier with ticks every three hours, formatted as 12-hour time: 12 AM, 3AM, 6AM, etc.

Given an array of TimeAxisConfigurations, the Axis.Time will iterate through the array to find the first TimeAxisConfiguration until it finds one where the first generated tick will fit. It will then draw using that configuration, hiding any tick labels that do not fit.

For more on how ticks are generated please refer to D3 Time Scales.

Bugfixes

  • Dataset metadata is now correctly passed to accessors (see "Plot Metadata", above). Thus, an alternative way of coloring a series in a plot is:
var dataset = new Plottable.Dataset(data, { color: red } );
var plot = new Plottable.Plot.Scatter(xScale, yScale)
      .addDataset(dataset)
      .project("fill", function (d, i, u, m) { return u.color; });

screen shot 2014-11-17 at 5 00 58 pm

API Breaks

  • BarHoverInteraction has been removed, as per the warning in v0.34.0's release notes.
  • Formatters.time() has been moved to Formatters.multiTime(). Formatters.time() now pipes through to d3.time.format. For more on specifiers, please see https://github.com/mbostock/d3/wiki/Time-Formatting#format.
  • 'selectBar()' has been removed from AbstractBarPlot and has been restructured into 'getBars()'.

Other notes

We're bringing back release songs.

Upgrade Instructions

If you were using Interaction.BarHover, you should instead attach an Interaction.Hover onto an Bar Plot like so:

var hoverInteraction = new Plottable.Interaction.Hover();
hoverInteraction.onHoverOver(hoverOverCallback);
hoverInteraction.onHoverOut(hoverOutCallback);
barPlot.hoverMode("point"); // or "line"; "point" by default
barPlot.registerInteraction(hoverInteraction);
  • Replace all previous uses of Formatters.time() with Formatters.multiTime().
  • The old behavior of 'selectBar()' can be replicated by using the new 'getBars()' API and then applying the selected class as appropriate:
var barToSelect = barPlot.getBars(x, y);
barToSelect.classed("selected", true);

Release Song

Balkanica