/** * 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'; 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("type") === "memory") { middleValue = Converter.memoryToSimpliedUnit(total); } 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); } 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")); }, didInsertElement: function() { this.initChart(); this.draw(); }, });