Skip to content

Commit

Permalink
feat(radar): Intent to ship radar type (#453)
Browse files Browse the repository at this point in the history
- Implementation of the initial support of 'radar' type
- Updated internal cache interface

Fix #59
Close #453
  • Loading branch information
netil committed Jun 20, 2018
1 parent 46ebf35 commit 7d0da65
Show file tree
Hide file tree
Showing 22 changed files with 778 additions and 121 deletions.
95 changes: 95 additions & 0 deletions demo/demo.js
Expand Up @@ -592,6 +592,29 @@ var demos = {
];
}
},
RadarChart: {
options: {
data: {
x: "x",
columns: [
["x", "Data A", "Data B", "Data C", "Data D", "Data E"],
["data1", 330, 350, 200, 380, 150],
["data2", 130, 100, 30, 200, 80],
["data3", 230, 153, 85, 300, 250]
],
type: "radar",
labels: true
},
radar: {
axis: {
max: 400
},
level: {
depth: 4
}
}
}
},
CombinationChart: {
options: {
data: {
Expand Down Expand Up @@ -2408,6 +2431,78 @@ d3.select(".chart_area")
}
}
},
RadarChartOptions: {
RadarAxis: {
options: {
data: {
x: "x",
columns: [
["x", "Data A", "Data B", "Data C", "Data D", "Data E", "Data F", "Data G"],
["data1", 330, 350, 200, 380, 150, 100, 230],
["data2", 130, 100, 30, 200, 80, 200, 130]
],
type: "radar",
labels: true
},
radar: {
axis: {
max: 330,
line: {
show: false
},
text: {
show: false
}
},
level: {
text: {
show: false
}
}
}
},
style: [
"#RadarAxis .bb-levels polygon { stroke-dasharray: 1 3; stroke-width: 1px; }"
]
},
RadarLevel: {
options: {
data: {
x: "x",
columns: [
["x", "Data A", "Data B", "Data C", "Data D", "Data E", "Data F", "Data G", "Data H", "Data I"],
["data1", 330, 350, 200, 400, 150, 100, 230, 30, 95],
["data2", 130, 100, 30, 200, 80, 200, 130, 210, 195]
],
type: "radar"
},
radar: {
level: {
depth: 4,
show: false,
text: {
format: function(x) { return x + "%"; }
}
}
}
}
},
RadarSize: {
options: {
data: {
columns: [
["data1", 330, 350, 220, 400, 150, 330, 230, 390, 95, 195, 220]
],
type: "radar"
},
radar: {
size: {
ratio: 0.75
}
}
}
}
},
API: {
Flow: {
options: {
Expand Down
5 changes: 4 additions & 1 deletion demo/simple-sidebar.css
Expand Up @@ -213,4 +213,7 @@ div.row {

/* Style For Lines */
#StyleForLines .line-class-data1 { stroke-dasharray: 3 4; stroke-width: 3px; }
#StyleForLines .line-class-data2 { stroke-dasharray: 2 4; stroke-width: 2px; }
#StyleForLines .line-class-data2 { stroke-dasharray: 2 4; stroke-width: 2px; }

/* Style For Radars */
#RadarAxis .bb-levels polygon { stroke-dasharray: 1 3; stroke-width: 1px; }
79 changes: 50 additions & 29 deletions spec/internals/arc-spec.js
Expand Up @@ -7,6 +7,12 @@ import CLASS from "../../src/config/classes";
import util from "../assets/util";

describe("ARC", () => {
const selector = {
arc: `.${CLASS.chartArc}.${CLASS.target}.${CLASS.target}`,
shapes: `g.${CLASS.shapes}.${CLASS.arcs}.${CLASS.arcs}`,
shape: `path.${CLASS.shape}.${CLASS.arc}.${CLASS.arc}`
};

describe("show pie chart", () => {
const chart = util.generate({
data: {
Expand All @@ -21,16 +27,22 @@ describe("ARC", () => {

it("should have correct classes", () => {
const chartArc = chart.internal.main.select(`.${CLASS.chartArcs}`);
const selector = {
arc: `.${CLASS.chartArc}.${CLASS.target}.${CLASS.target}`,
shapes: `g.${CLASS.shapes}.${CLASS.arcs}.${CLASS.arcs}`,
shape: `path.${CLASS.shape}.${CLASS.arc}.${CLASS.arc}`
}

const arcs = {
data1: chartArc.select(`.${CLASS.chartArc}.${CLASS.target}.${CLASS.target}-data1`)
.select(`g.${CLASS.shapes}.${CLASS.shapes}-data1.${CLASS.arcs}.${CLASS.arcs}-data1`)
.select(`path.${CLASS.shape}.${CLASS.arc}.${CLASS.arc}-data1`),
data2: chartArc.select(`.${CLASS.chartArc}.${CLASS.target}.${CLASS.target}-data2`)
.select(`g.${CLASS.shapes}.${CLASS.shapes}-data2.${CLASS.arcs}.${CLASS.arcs}-data2`)
.select(`path.${CLASS.shape}.${CLASS.arc}.${CLASS.arc}-data2`),
data3: chartArc.select(`.${CLASS.chartArc}.${CLASS.target}.${CLASS.target}-data3`)
.select(`g.${CLASS.shapes}.${CLASS.shapes}-data3.${CLASS.arcs}.${CLASS.arcs}-data3`)
.select(`path.${CLASS.shape}.${CLASS.arc}.${CLASS.arc}-data3`)
data1: chartArc.select(`${selector.arc}-data1`)
.select(`${selector.shapes}-data1`)
.select(`${selector.shape}-data1`),
data2: chartArc.select(`${selector.arc}-data2`)
.select(`${selector.shapes}-data2`)
.select(`${selector.shape}-data2`),
data3: chartArc.select(`${selector.arc}-data3`)
.select(`${selector.shapes}-data3`)
.select(`${selector.shape}-data3`)
};

expect(arcs.data1.size()).to.be.equal(1);
Expand All @@ -41,9 +53,14 @@ describe("ARC", () => {
it("should have correct d", () => {
const main = chart.internal.main;

expect(main.select(`.${CLASS.arc}-data1`).attr("d")).to.match(/M-124\..+,-171\..+A211\..+,211\..+,0,0,1,-3\..+,-211\..+L0,0Z/);
expect(main.select(`.${CLASS.arc}-data2`).attr("d")).to.match(/M1\..+,-211\..+A211\..+,211\..+,0,0,1,1\..+,211\..+L0,0Z/);
expect(main.select(`.${CLASS.arc}-data3`).attr("d")).to.match(/M1\..+,211\..+A211\..+,211\..+,0,0,1,-124\..+,-171\..+L0,0Z/);
expect(main.select(`.${CLASS.arc}-data1`).attr("d"))
.to.match(/M-124\..+,-171\..+A211\..+,211\..+,0,0,1,-3\..+,-211\..+L0,0Z/);

expect(main.select(`.${CLASS.arc}-data2`).attr("d"))
.to.match(/M1\..+,-211\..+A211\..+,211\..+,0,0,1,1\..+,211\..+L0,0Z/);

expect(main.select(`.${CLASS.arc}-data3`).attr("d"))
.to.match(/M1\..+,211\..+A211\..+,211\..+,0,0,1,-124\..+,-171\..+L0,0Z/);
});

it("should have correct d even if data id can be converted to a color", done => {
Expand Down Expand Up @@ -82,15 +99,15 @@ describe("ARC", () => {
it("should have correct d attribute", () => {
const chartArc = chart.internal.main.select(`.${CLASS.chartArcs}`);
const arcs = {
data1: chartArc.select(`.${CLASS.chartArc}.${CLASS.target}.${CLASS.target}-data1`)
.select(`g.${CLASS.shapes}.${CLASS.shapes}-data1.${CLASS.arcs}.${CLASS.arcs}-data1`)
.select(`path.${CLASS.shape}.${CLASS.arc}.${CLASS.arc}-data1`),
data2: chartArc.select(`.${CLASS.chartArc}.${CLASS.target}.${CLASS.target}-data2`)
.select(`g.${CLASS.shapes}.${CLASS.shapes}-data2.${CLASS.arcs}.${CLASS.arcs}-data2`)
.select(`path.${CLASS.shape}.${CLASS.arc}.${CLASS.arc}-data2`),
data3: chartArc.select(`.${CLASS.chartArc}.${CLASS.target}.${CLASS.target}-data3`)
.select(`g.${CLASS.shapes}.${CLASS.shapes}-data3.${CLASS.arcs}.${CLASS.arcs}-data3`)
.select(`path.${CLASS.shape}.${CLASS.arc}.${CLASS.arc}-data3`)
data1: chartArc.select(`${selector.arc}-data1`)
.select(`${selector.shapes}-data1`)
.select(`${selector.shape}-data1`),
data2: chartArc.select(`${selector.arc}-data2`)
.select(`${selector.shapes}-data2`)
.select(`${selector.shape}-data2`),
data3: chartArc.select(`${selector.arc}-data3`)
.select(`${selector.shapes}-data3`)
.select(`${selector.shape}-data3`)
};

expect(arcs.data1.attr("d").indexOf("NaN")).to.be.equal(-1);
Expand Down Expand Up @@ -170,12 +187,14 @@ describe("ARC", () => {
});

const chartArc = chart.internal.main.select(`.${CLASS.chartArcs}`);
const data = chartArc.select(`.${CLASS.chartArc}.${CLASS.target}.${CLASS.target}-data`)
.select(`g.${CLASS.shapes}.${CLASS.shapes}-data.${CLASS.arcs}.${CLASS.arcs}-data`)
.select(`path.${CLASS.shape}.${CLASS.arc}.${CLASS.arc}-data`);
const data = chartArc.select(`${selector.arc}-data`)
.select(`${selector.shapes}-data`)
.select(`${selector.shape}-data`);

setTimeout(() => {
expect(data.attr("d")).to.match(/M-304,-3\..+A304,304,0,0,1,245\..+,-178\..+L237\..+,-172\..+A294,294,0,0,0,-294,-3\..+Z/);
expect(data.attr("d"))
.to.match(/M-304,-3\..+A304,304,0,0,1,245\..+,-178\..+L237\..+,-172\..+A294,294,0,0,0,-294,-3\..+Z/);

expect(chartArc.select(`.${CLASS.gaugeValue}`).attr("dy")).to.be.equal("-.1em");

done();
Expand All @@ -199,13 +218,15 @@ describe("ARC", () => {
});

const chartArc = chart.internal.main.select(`.${CLASS.chartArcs}`);
const data = chartArc.select(`.${CLASS.chartArc}.${CLASS.target}.${CLASS.target}-data`)
.select(`g.${CLASS.shapes}.${CLASS.shapes}-data.${CLASS.arcs}.${CLASS.arcs}-data`)
.select(`path.${CLASS.shape}.${CLASS.arc}.${CLASS.arc}-data`);
const data = chartArc.select(`${selector.arc}-data`)
.select(`${selector.shapes}-data`)
.select(`${selector.shape}-data`);

setTimeout(() => {
// This test has bee updated to make tests pass. @TODO double-check this test is accurate.
expect(data.attr("d")).to.match(/M-221.*?,-2\..+A221.*?,221.*?,0,1,1,-68.*?,210.*?L-65.*?,201.*?A211.*?,211.*?,0,1,0,-211.*?,-2.*?Z/);
expect(data.attr("d"))
.to.match(/M-221.*?,-2\..+A221.*?,221.*?,0,1,1,-68.*?,210.*?L-65.*?,201.*?A211.*?,211.*?,0,1,0,-211.*?,-2.*?Z/);

done();
}, 500);
});
Expand Down
91 changes: 91 additions & 0 deletions spec/shape/shape.radar-spec.js
@@ -0,0 +1,91 @@
/**
* Copyright (c) 2017 NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
/* eslint-disable */
/* global describe, beforeEach, it, expect */
import util from "../assets/util";
import CLASS from "../../src/config/classes";

describe("SHAPE RADAR", () => {
let chart;
let args;

beforeEach(function(){
chart = util.generate(args);
});

describe("default radar", () => {
before(() => {
args = {
data: {
columns: [
["x", "Design", "Price", "Brand"],
["data1", 30, 200, 100]
],
type: "radar"
},
radar: {}
};
});

it("Should render level, axes and data edges", () => {
const radar = chart.internal.main.select(`.${CLASS.chartRadars}`);
const data = chart.data();
const dataLen = data[0].values.length;

const axes = radar.selectAll(`.${CLASS.axis} g`);
const levels = radar.selectAll(`.${CLASS.levels} g`);

expect(axes.size()).to.be.equal(dataLen);
expect(levels.size()).to.be.equal(dataLen);

// check levels and data points
radar.selectAll("polygon").each(function() {
const len = this.getAttribute("points").replace(/[^,]/g,"").length;

expect(len).to.be.equal(dataLen);
});
});

it("set axis options", () => {
args.radar.axis = {
line: {
show: false
},
text: {
show: false
}
};
});

it("check for axis options", () => {
const radar = chart.internal.main.select(`.${CLASS.chartRadars}`);
const axis = radar.selectAll(`.${CLASS.axis}`);

expect(axis.selectAll("line").empty()).to.be.true;
expect(axis.selectAll("text").empty()).to.be.true;
});

it("set level options", () => {
args.radar.level = {
depth: 8,
show: false
};
});

it("check for level options", () => {
const radar = chart.internal.main.select(`.${CLASS.chartRadars}`);
const levels = radar.select(`.${CLASS.levels}`);
const level = levels.selectAll("polygon");

// check for level element depth size
expect(args.radar.level.depth).to.be.equal(level.size());

// level should be hidden
level.each(function() {
expect(this.style.visibility).to.be.equal("hidden");
});
});
});
});
4 changes: 2 additions & 2 deletions src/api/api.load.js
Expand Up @@ -72,8 +72,8 @@ extend(Chart.prototype, {
});

// use cache if exists
if ("cacheIds" in args && $$.hasCaches(args.cacheIds)) {
$$.load($$.getCaches(args.cacheIds), args.done);
if ("cacheIds" in args && $$.hasCaches(args.cacheIds, true)) {
$$.load($$.getCaches(args.cacheIds, true), args.done);
return;
}

Expand Down

0 comments on commit 7d0da65

Please sign in to comment.