blob: 03b633682f73a4da0c89445319009fc32783fec6 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import Ember from 'ember';
import BaseChartComponent from 'yarn-ui/components/base-chart-component';
import ColorUtils from 'yarn-ui/utils/color-utils';
import Converter from 'yarn-ui/utils/converter';
import {Entities} from 'yarn-ui/constants';
export default BaseChartComponent.extend({
/*
* data = [{label="xx", value=},{...}]
*/
renderDonutChart: function(data, title, showLabels = false,
middleLabel = "Total", middleValue = undefined, suffix = "") {
var g = this.chart.g;
var layout = this.getLayout();
this.renderTitleAndBG(g, title, layout);
var total = 0;
var allZero = true;
for (var i = 0; i < data.length; i++) {
total += data[i].value;
if (data[i].value > 1e-6) {
allZero = false;
}
}
if (!middleValue) {
if (this.get(Entities.Type) === Entities.Memory) {
middleValue = Converter.memoryToSimpliedUnit(total);
} else if (this.get(Entities.Type) === Entities.Resource) {
middleValue = Converter.resourceToSimplifiedUnit(total, this.get(Entities.Unit));
} else {
middleValue = total;
}
}
//Width and height
var h = layout.y2 - layout.y1;
// 50 is for title
var outerRadius = (h - 50 - 2 * layout.margin) / 2;
// Ratio of inner radius to outer radius
var radiusRatio = 0.75;
var innerRadius = outerRadius * radiusRatio;
var arc = d3.svg.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius);
var cx;
var cy = layout.y1 + 50 + layout.margin + outerRadius;
if (showLabels) {
cx = layout.x1 + layout.margin + outerRadius;
} else {
cx = (layout.x1 + layout.x2) / 2;
}
var pie = d3.layout.pie();
pie.sort(null);
pie.value(function(d) {
var v = d.value;
// make sure it > 0
v = Math.max(v, 1e-6);
return v;
});
//Set up groups
var arcs = g
.selectAll("g.arc")
.data(pie(data))
.enter()
.append("g")
.attr("class", "arc")
.attr("transform", "translate(" + cx + "," + cy + ")");
function tweenPie(finish) {
var start = {
startAngle: 0,
endAngle: 0
};
var i = d3.interpolate(start, finish);
return function(d) {
return arc(i(d));
};
}
//Draw arc paths
var path = arcs.append("path")
.attr("fill", function(d, i) {
if (d.value > 1e-6) {
return this.colors[i];
} else {
return "white";
}
}.bind(this))
.attr("d", arc)
.attr("stroke", function(d, i) {
if (allZero) {
return this.colors[i];
}
}.bind(this));
this.bindTooltip(path);
path.on("click", function (d) {
var data = d.data;
if (data.link) {
this.tooltip.remove();
document.location.href = data.link;
}
}.bind(this));
// Show labels
if (showLabels) {
var lx = layout.x1 + layout.margin + outerRadius * 2 + 30;
var squareW = 15;
var margin = 10;
var select = g.selectAll(".rect")
.data(data)
.enter();
select.append("rect")
.attr("fill", function(d, i) {
return this.colors[i];
}.bind(this))
.attr("x", lx)
.attr("y", function(d, i) {
return layout.y1 + 75 + (squareW + margin) * i + layout.margin;
})
.attr("width", squareW)
.attr("height", squareW);
select.append("text")
.attr("x", lx + squareW + margin)
.attr("y", function(d, i) {
return layout.y1 + 80 + (squareW + margin) * i + layout.margin + squareW / 2;
})
.text(function(d) {
var value = d.value;
if (this.get("type") === "memory") {
value = Converter.memoryToSimpliedUnit(value);
} else if (this.get("type") === "resource") {
value = Converter.resourceToSimplifiedUnit(value, this.get(Entities.Unit));
}
return d.label + ' = ' + value + suffix;
}.bind(this));
}
if (middleLabel) {
var highLightColor = this.colors[0];
g.append("text").text(middleLabel).attr("x", cx).attr("y", cy - 10).
attr("class", "donut-highlight-text").attr("fill", highLightColor);
g.append("text").text(middleValue).attr("x", cx).attr("y", cy + 15).
attr("class", "donut-highlight-sub").attr("fill", highLightColor);
}
path.transition()
.duration(500)
.attrTween('d', tweenPie);
},
_dataChange: Ember.observer("data", function() {
this.chart.g.selectAll("*").remove();
if(this.get("data")) {
this.draw();
}
}),
draw: function() {
var colorTargets = this.get("colorTargets");
if (colorTargets) {
var colorTargetReverse = Boolean(this.get("colorTargetReverse"));
var targets = colorTargets.split(" ");
this.colors = ColorUtils.getColors(this.get("data").length, targets, colorTargetReverse);
}
this.renderDonutChart(this.get("data"), this.get("title"), this.get("showLabels"),
this.get("middleLabel"), this.get("middleValue"), this.get("suffix"));
},
didInsertElement: function() {
// When parentIdPrefix is specified, use parentidPrefix + name as new parent
// id
if (this.get("parentIdPrefix")) {
var newParentId = this.get("parentIdPrefix") + this.get("id");
this.set("parentId", newParentId);
console.log(newParentId);
}
this.initChart();
this.draw();
},
});