Skip to content

Commit

Permalink
Merge pull request #112 from jpmorganchase/sunburst
Browse files Browse the repository at this point in the history
Sunburst charts
  • Loading branch information
texodus authored May 17, 2018
2 parents 420e223 + 3a7bbf8 commit b1e9b3d
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 91 deletions.
13 changes: 2 additions & 11 deletions packages/perspective-jupyterlab/src/ts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ const PSP_CONTAINER_CLASS = 'jp-PSPContainer';

interface PerspectiveSpec {
data: string,
schema: string,
layout: string,
config: string;
}
Expand All @@ -47,7 +46,6 @@ export class RenderedPSP extends Widget implements IRenderMime.IRenderer {
let psp = (<any>(this.node.querySelector('perspective-viewer')));

let layout = JSON.parse(this._lyt);

for(let key in layout){
if(layout[key]){
if(key !== 'view'){
Expand All @@ -58,13 +56,8 @@ export class RenderedPSP extends Widget implements IRenderMime.IRenderer {
}
}

if (this._schema !== '') {
let schema = JSON.parse(this._schema);
psp.load(schema);
}

if (this._datatype === 'static') {
psp.update(this._data);
psp.load(this._data);
} else if (this._datatype === 'ws' || this._datatype === 'wss') {
let config = JSON.parse(this._config);
let send = config.send || '';
Expand Down Expand Up @@ -118,9 +111,8 @@ export class RenderedPSP extends Widget implements IRenderMime.IRenderer {
}

renderModel(model: IRenderMime.IMimeModel): Promise<void> {
const {data, schema, layout, config} = model.data[MIME_TYPE] as any | PerspectiveSpec;
const {data, layout, config} = model.data[MIME_TYPE] as any | PerspectiveSpec;
this._lyt = layout;
this._schema = schema;

try {
this._data = JSON.parse(data) as object;
Expand Down Expand Up @@ -164,7 +156,6 @@ export class RenderedPSP extends Widget implements IRenderMime.IRenderer {
private _data: object;
private _datatype: string;
private _datasrc: string;
private _schema: string;
private _lyt: string; // not widget layout
private _config: string;
private _loaded: boolean;
Expand Down
36 changes: 36 additions & 0 deletions packages/perspective-viewer-highcharts/src/js/heatmap.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import highchartsMore from 'highcharts-more';
import heatmap from 'highcharts/modules/heatmap';
import boost from 'highcharts/modules/boost';
import treemap from 'highcharts/modules/treemap';
import sunburst from 'highcharts/modules/sunburst';
import grouped_categories from 'highcharts-grouped-categories';
import chroma from 'chroma-js';

Expand All @@ -29,6 +30,7 @@ let axisProto = Highcharts.Axis.prototype,
highchartsMore(highcharts);
heatmap(highcharts);
treemap(highcharts);
sunburst(highcharts);
grouped_categories(highcharts);
boost(highcharts);

Expand Down Expand Up @@ -75,6 +77,40 @@ Highcharts.setOptions({
axisTypes: ['xAxis', 'yAxis', 'colorAxis']
}));

// draw points and add setting colors
H.wrap(H.seriesTypes.sunburst.prototype, "translate", function(p, positions) {
p.call(this, positions);
this.translateColors();
});

// copy method from heatmap for color mixin
H.seriesTypes.sunburst.prototype.translateColors = function() {
var series = this,
nullColor = this.options.nullColor,
colorAxis = this.colorAxis,
colorKey = this.colorKey;

H.each(this.data, function(point) {
var value = point[colorKey],
color;

color = point.options.color ||
(!point.value ? // LINE CHANGED
nullColor :
(colorAxis && value !== undefined) ?
colorAxis.toColor(value, point) :
point.color || series.color
);

if (color) {
point.color = color;
}
});
}

// use "colorValue" to calculate color
H.seriesTypes.sunburst.prototype.colorKey = 'colorValue';

// Pushes part of grid to path
function addGridPart(path, d, width) {
// Based on crispLine from HC (#65)
Expand Down
16 changes: 15 additions & 1 deletion packages/perspective-viewer-highcharts/src/js/highcharts.js
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,8 @@ export function draw(mode) {
type = 'column';
} else if (mode == 'treemap') {
type = 'treemap';
} else if (mode == 'sunburst') {
type = 'sunburst';
} else if (mode === 'scatter') {
if (aggregates.length <= 3) {
type = 'scatter';
Expand Down Expand Up @@ -589,7 +591,7 @@ export function draw(mode) {

color_axis.bind(this)(config, colorRange)
config.legend.floating = false;
} else if (mode === "treemap") {
} else if (mode === "treemap" || mode === "sunburst") {
let data = [];
let size = aggregates[0]['column'];
let color, colorAxis, colorRange;
Expand Down Expand Up @@ -868,6 +870,18 @@ global.registerPlugin("treemap", {
delete: function () {}
});

global.registerPlugin("sunburst", {
name: "Sunburst",
create: draw('sunburst'),
resize: resize,
initial: {
"type": "number",
"count": 2
},
selectMode: "toggle",
delete: function () {}
});

global.registerPlugin("heatmap", {
name: "Heatmap",
create: draw("heatmap"),
Expand Down
12 changes: 3 additions & 9 deletions packages/perspective/src/cpp/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -503,8 +503,7 @@ make_table(
val j_data,
t_uint32 offset,
t_str index,
t_bool is_arrow,
t_bool is_delete
t_bool is_arrow
) {
// Create the input and port schemas
t_svec colnames = vecFromJSArray<std::string>(j_colnames);
Expand All @@ -519,13 +518,8 @@ make_table(
_fill_data(tbl, colnames, j_data, dtypes, offset, is_arrow);

// Set up pkey and op columns
if (is_delete) {
auto op_col = tbl->add_column("psp_op", DTYPE_UINT8, false);
op_col->raw_fill<t_uint8>(OP_DELETE);
} else {
auto op_col = tbl->add_column("psp_op", DTYPE_UINT8, false);
op_col->raw_fill<t_uint8>(OP_INSERT);
}
auto op_col = tbl->add_column("psp_op", DTYPE_UINT8, false);
op_col->raw_fill<t_uint8>(OP_INSERT);

if (index == "")
{
Expand Down
46 changes: 2 additions & 44 deletions packages/perspective/src/js/perspective.js
Original file line number Diff line number Diff line change
Expand Up @@ -1071,7 +1071,7 @@ table.prototype.update = function (data) {
try {
tbl = __MODULE__.make_table(pdata.row_count || 0,
pdata.names, pdata.types, pdata.cdata,
this.gnode.get_table().size(), this.index || "", pdata.is_arrow, false);
this.gnode.get_table().size(), this.index || "", pdata.is_arrow);

// Add any computed columns
this._calculate_computed(tbl, this.computed);
Expand All @@ -1089,48 +1089,6 @@ table.prototype.update = function (data) {
}
}

/**
* Removes the rows of a {@link table}. Removed rows are pushed down to any
* derived {@link view} objects.
*
* @param {Array<Object>} data An array of primary keys to remove.
*
* @see {@link table}
*/
table.prototype.remove = function (data) {
let pdata;
let cols = this._columns();
let schema = this.gnode.get_tblschema();
let types = schema.types();

data = data.map(idx => ({[this.index]: idx}));

if (data instanceof ArrayBuffer) {
pdata = load_arrow_buffer(data, [this.index], types);
}
else {
pdata = parse_data(data, [this.index], types);
}

let tbl;
try {
tbl = __MODULE__.make_table(pdata.row_count || 0,
pdata.names, pdata.types, pdata.cdata,
this.gnode.get_table().size(), this.index || "", pdata.is_arrow, true);

__MODULE__.fill(this.pool, this.gnode, tbl);
this.initialized = true;
} catch (e) {
console.error(e);
} finally {
if (tbl) {
tbl.delete();
}
schema.delete();
types.delete();
}
}

/**
* Create a new table with the addition of new computed columns (defined as javascript functions)
*/
Expand Down Expand Up @@ -1445,7 +1403,7 @@ const perspective = {
// Fill t_table with data
tbl = __MODULE__.make_table(pdata.row_count || 0,
pdata.names, pdata.types, pdata.cdata,
0, options.index, pdata.is_arrow, false);
0, options.index, pdata.is_arrow);

gnode = __MODULE__.make_gnode(tbl);
pool.register_gnode(gnode);
Expand Down
2 changes: 0 additions & 2 deletions packages/perspective/src/js/perspective.parallel.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,6 @@ table.prototype.delete = async_queue('delete', "table_method");

table.prototype.on_delete = subscribe('on_delete', 'table_method', true);

table.prototype.remove = async_queue('remove', "table_method");

table.prototype.update = function(data) {
return new Promise( (resolve, reject) => {
this._worker.handlers[++this._worker.msg_id] = {resolve, reject};
Expand Down
24 changes: 0 additions & 24 deletions packages/perspective/test/js/updates.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,30 +50,6 @@ var arrow_indexed_result = [

module.exports = (perspective) => {


describe("Removes", function() {

it("after an `update()`", async function () {
var table = perspective.table(meta, {index: "x"});
table.update(data);
var view = table.view();
table.remove([1, 2]);
let result = await view.to_json();
expect(result.length).toEqual(2);
expect(data.slice(2, 4)).toEqual(result);
});

it("after an regular data load`", async function () {
var table = perspective.table(data, {index: "x"});
var view = table.view();
table.remove([1, 2]);
let result = await view.to_json();
expect(result.length).toEqual(2);
expect(data.slice(2, 4)).toEqual(result);
});

});

describe("Updates", function() {

it("Meta constructor then `update()`", async function () {
Expand Down

0 comments on commit b1e9b3d

Please sign in to comment.