Skip to content

Commit

Permalink
Merge pull request #2787 from palantir/2125fix
Browse files Browse the repository at this point in the history
Support Formatter on Legend
  • Loading branch information
yunhaolucky committed Sep 24, 2015
2 parents 76929b3 + d00943a commit 5f6be11
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 13 deletions.
11 changes: 11 additions & 0 deletions plottable.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2159,6 +2159,17 @@ declare module Plottable {
*/
constructor(colorScale: Scales.Color);
protected _setup(): void;
/**
* Gets the Formatter for the entry texts.
*/
formatter(): Formatter;
/**
* Sets the Formatter for the entry texts.
*
* @param {Formatter} formatter
* @returns {Legend} The calling Legend.
*/
formatter(formatter: Formatter): Legend;
/**
* Gets the maximum number of entries per row.
*
Expand Down
18 changes: 13 additions & 5 deletions plottable.js
Original file line number Diff line number Diff line change
Expand Up @@ -5417,8 +5417,9 @@ var Plottable;
this._colorScale = colorScale;
this._redrawCallback = function (scale) { return _this.redraw(); };
this._colorScale.onUpdate(this._redrawCallback);
this._formatter = Plottable.Formatters.identity();
this.xAlignment("right").yAlignment("top");
this.comparator(function (a, b) { return _this._colorScale.domain().indexOf(a) - _this._colorScale.domain().indexOf(b); });
this.comparator(function (a, b) { return 0; });
this._symbolFactoryAccessor = function () { return Plottable.SymbolFactories.circle(); };
this._symbolOpacityAccessor = function () { return 1; };
}
Expand All @@ -5431,6 +5432,14 @@ var Plottable;
this._wrapper = new SVGTypewriter.Wrappers.Wrapper().maxLines(1);
this._writer = new SVGTypewriter.Writers.Writer(this._measurer, this._wrapper).addTitleElement(Plottable.Configs.ADD_TITLE_ELEMENTS);
};
Legend.prototype.formatter = function (formatter) {
if (formatter == null) {
return this._formatter;
}
this._formatter = formatter;
this.redraw();
return this;
};
Legend.prototype.maxEntriesPerRow = function (maxEntriesPerRow) {
if (maxEntriesPerRow == null) {
return this._maxEntriesPerRow;
Expand Down Expand Up @@ -5471,12 +5480,11 @@ var Plottable;
var _this = this;
var textHeight = this._measurer.measure().height;
var availableWidthForEntries = Math.max(0, (availableWidth - this._padding));
var entryNames = this._colorScale.domain().slice();
entryNames.sort(this.comparator());
var entryNames = this._colorScale.domain().slice().sort(function (a, b) { return _this._comparator(_this._formatter(a), _this._formatter(b)); });
var entryLengths = d3.map();
var untruncatedEntryLengths = d3.map();
entryNames.forEach(function (entryName) {
var untruncatedEntryLength = textHeight + _this._measurer.measure(entryName).width + _this._padding;
var untruncatedEntryLength = textHeight + _this._measurer.measure(_this._formatter(entryName)).width + _this._padding;
var entryLength = Math.min(untruncatedEntryLength, availableWidthForEntries);
entryLengths.set(entryName, entryLength);
untruncatedEntryLengths.set(entryName, untruncatedEntryLength);
Expand Down Expand Up @@ -5608,7 +5616,7 @@ var Plottable;
yAlign: "top",
textRotation: 0
};
self._writer.write(value, maxTextLength, self.height(), writeOptions);
self._writer.write(self._formatter(value), maxTextLength, self.height(), writeOptions);
});
return this;
};
Expand Down
33 changes: 25 additions & 8 deletions src/components/legend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export module Components {

private _padding = 5;
private _colorScale: Scales.Color;
private _formatter: Formatter;
private _maxEntriesPerRow: number;
private _comparator: (a: string, b: string) => number;
private _measurer: SVGTypewriter.Measurers.Measurer;
Expand Down Expand Up @@ -45,9 +46,9 @@ export module Components {
this._colorScale = colorScale;
this._redrawCallback = (scale) => this.redraw();
this._colorScale.onUpdate(this._redrawCallback);

this._formatter = Formatters.identity();
this.xAlignment("right").yAlignment("top");
this.comparator((a: string, b: string) => this._colorScale.domain().indexOf(a) - this._colorScale.domain().indexOf(b));
this.comparator((a: string, b: string) => 0);
this._symbolFactoryAccessor = () => SymbolFactories.circle();
this._symbolOpacityAccessor = () => 1;
}
Expand All @@ -62,6 +63,25 @@ export module Components {
this._writer = new SVGTypewriter.Writers.Writer(this._measurer, this._wrapper).addTitleElement(Configs.ADD_TITLE_ELEMENTS);
}

/**
* Gets the Formatter for the entry texts.
*/
public formatter(): Formatter;
/**
* Sets the Formatter for the entry texts.
*
* @param {Formatter} formatter
* @returns {Legend} The calling Legend.
*/
public formatter(formatter: Formatter): Legend;
public formatter(formatter?: Formatter): any {
if (formatter == null) {
return this._formatter;
}
this._formatter = formatter;
this.redraw();
return this;
}
/**
* Gets the maximum number of entries per row.
*
Expand Down Expand Up @@ -144,13 +164,11 @@ export module Components {

let availableWidthForEntries = Math.max(0, (availableWidth - this._padding));

let entryNames = this._colorScale.domain().slice();
entryNames.sort(this.comparator());

let entryNames = this._colorScale.domain().slice().sort((a, b) => this._comparator(this._formatter(a), this._formatter(b)));
let entryLengths: d3.Map<number> = d3.map<number>();
let untruncatedEntryLengths: d3.Map<number> = d3.map<number>();
entryNames.forEach((entryName) => {
let untruncatedEntryLength = textHeight + this._measurer.measure(entryName).width + this._padding;
let untruncatedEntryLength = textHeight + this._measurer.measure(this._formatter(entryName)).width + this._padding;
let entryLength = Math.min(untruncatedEntryLength, availableWidthForEntries);
entryLengths.set(entryName, entryLength);
untruncatedEntryLengths.set(entryName, untruncatedEntryLength);
Expand Down Expand Up @@ -299,8 +317,7 @@ export module Components {
yAlign: "top",
textRotation: 0
};

self._writer.write(value, maxTextLength, self.height(), writeOptions);
self._writer.write(self._formatter(value), maxTextLength, self.height(), writeOptions);
});
return this;
}
Expand Down
37 changes: 37 additions & 0 deletions test/components/legendTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,43 @@ describe("Legend", () => {
svg.remove();
});

it("can set formatter to change how entry labels are displayed", () => {
color.domain(["A", "B", "C"]);
let formatter = (id: string) => `${id}foo`;
legend.formatter(formatter);
legend.renderTo(svg);
let legendRows = svg.selectAll(entrySelector);
assert.operator(legendRows.size(), ">=", 1, "There is at least one entry in the test");
legendRows.each(function(d, i){
let expectedText = formatter(legend.colorScale().domain()[i]);
assert.strictEqual(d3.select(this).select("text").text(), expectedText,
`formatter output ${expectedText} should be displayed`);
});
svg.remove();
});

it("can get formatter of the legend using formatter()", () => {
let formatter = (id: string) => `${id}foo`;
legend.formatter(formatter);
assert.strictEqual(legend.formatter(), formatter, "formatter() returns the formatter of legend correctly");
svg.remove();
});

it("can sort displayed texts using comparator()", () => {
let colorDomain = ["A", "B", "C"];
color.domain(colorDomain);
let expectedTexts = ["Z", "Y", "X"];
let formatter = (d: string) => expectedTexts[colorDomain.indexOf(d)];
legend.formatter(formatter);
let comparator = (a: string, b: string) => a.charCodeAt(0) - b.charCodeAt(0);
legend.comparator(comparator);
legend.renderTo(svg);
let entryTexts = svg.selectAll(entrySelector)[0].map((node: Element) => d3.select(node).select("text").text());
expectedTexts.sort(comparator);
assert.deepEqual(expectedTexts, entryTexts, "displayed texts should be sorted in alphabetic order");
svg.remove();
});

describe("entitiesAt()", () => {
function computeExpectedSymbolPosition(legend: Plottable.Components.Legend, rowIndex: number, entryIndexWithinRow: number) {
let row = d3.select(legend.content().selectAll(rowSelector)[0][rowIndex]);
Expand Down

0 comments on commit 5f6be11

Please sign in to comment.