Example #1
0
function mkPieArc(radius, focused = false) {
    if(focused) {
        return arc()
            .outerRadius(radius - 10 + 3)
            .innerRadius(radius / 2.5)
            .padAngle(0.07)
            .cornerRadius(0);
    } else {
        return arc()
            .outerRadius(radius - 10)
            .innerRadius(radius / 2.5)
            .padAngle(0.07)
            .cornerRadius(0);
    }
}
Example #2
0
export default function Arc({
  className,
  data,
  centroid,
  innerRadius,
  outerRadius,
  cornerRadius,
  startAngle,
  endAngle,
  padAngle,
  padRadius,
  ...restProps
}) {
  const arc = d3Arc();
  if (centroid) arc.centroid(centroid);
  if (innerRadius) arc.innerRadius(innerRadius);
  if (outerRadius) arc.outerRadius(outerRadius);
  if (cornerRadius) arc.cornerRadius(cornerRadius);
  if (startAngle) arc.startAngle(startAngle);
  if (endAngle) arc.endAngle(endAngle);
  if (padAngle) arc.padAngle(padAngle);
  if (padRadius) arc.padRadius(padRadius);
  return (
    <path
      className={cx('vx-arc', className)}
      d={arc(data)}
      {...additionalProps(restProps, data)}
    />
  );
}
Example #3
0
export function d3Arc(params, { innerRadius, outerRadius, startAngle, endAngle }) {
  let arcFn = arc().outerRadius(outerRadius).innerRadius(innerRadius);
  if (isPresent(startAngle) && isPresent(endAngle)) {
    arcFn.startAngle(startAngle).endAngle(endAngle);
  }
  return arcFn;
}
    this.$('.js-pie-chart').each(function() {
      const data = [$(this).data('value'), $(this).data('max') - $(this).data('value')];
      const options = { ...defaults, ...$(this).data() };
      const radius = options.size / 2;

      const container = select(this);
      const svg = container
        .append('svg')
        .attr('width', options.size)
        .attr('height', options.size);
      const plot = svg.append('g').attr('transform', trans(radius, radius));
      const arc = d3Arc()
        .innerRadius(radius - options.thickness)
        .outerRadius(radius);
      const pie = d3Pie()
        .sort(null)
        .value(d => d);
      const colors = function(i) {
        return i === 0 ? options.color : options.baseColor;
      };
      const sectors = plot.selectAll('path').data(pie(data));

      sectors
        .enter()
        .append('path')
        .style('fill', (d, i) => colors(i))
        .attr('d', arc);
    });
Example #5
0
            ({
                width,
                height,
                innerRadius: _innerRadius,
                startAngle,
                endAngle,
                fit,
                cornerRadius,
            }) => {
                let radius = Math.min(width, height) / 2
                let innerRadius = radius * Math.min(_innerRadius, 1)

                let centerX = width / 2
                let centerY = height / 2

                let boundingBox
                if (fit === true) {
                    const { points, ...box } = computeArcBoundingBox(
                        centerX,
                        centerY,
                        radius,
                        startAngle - 90,
                        endAngle - 90
                    )
                    const ratio = Math.min(width / box.width, height / box.height)

                    const adjustedBox = {
                        width: box.width * ratio,
                        height: box.height * ratio,
                    }
                    adjustedBox.x = (width - adjustedBox.width) / 2
                    adjustedBox.y = (height - adjustedBox.height) / 2

                    centerX = ((centerX - box.x) / box.width) * box.width * ratio + adjustedBox.x
                    centerY = ((centerY - box.y) / box.height) * box.height * ratio + adjustedBox.y

                    boundingBox = { box, ratio, points }

                    radius = radius * ratio
                    innerRadius = innerRadius * ratio
                }

                const arcGenerator = d3Arc()
                    .outerRadius(radius)
                    .innerRadius(innerRadius)
                    .cornerRadius(cornerRadius)

                return {
                    centerX,
                    centerY,
                    radius,
                    innerRadius,
                    arcGenerator,
                    debug: boundingBox,
                }
            }
Example #6
0
 PieArcComponent.prototype.calculateArc = function () {
     var outerRadius = this.outerRadius;
     if (this.explodeSlices && this.innerRadius === 0) {
         outerRadius = (this.outerRadius * this.value) / this.max;
     }
     return arc()
         .innerRadius(this.innerRadius)
         .outerRadius(outerRadius)
         .cornerRadius(this.cornerRadius);
 };
 const getPath = edge => {
     const pathFunction = d3Shape
         .arc()
         .innerRadius(r1)
         .outerRadius(r2)
         .startAngle(transformAngle(start))
         .endAngle(transformAngle(end))
         .cornerRadius(cornerRadius[edge]);
     return pathFunction();
 };
Example #8
0
 generateArcs = memoize(function(classificationRatioPairs){
     const { innerRadius, classificationColorMap, size } = this.props;
     const outerRadius = size / 2;
     const pieChartDims = this.pieGenerator(  _.pluck(classificationRatioPairs, 1)   );
     const arcGenerator = arc().innerRadius(innerRadius).outerRadius(outerRadius);
     return _.map(classificationRatioPairs, function([ classificationTitle, classificationRatio ], idx){
         return (
             <path d={arcGenerator(pieChartDims[idx])} className={"path-for-" + classificationTitle}
                 style={{ 'fill' : classificationColorMap[classificationTitle] || '#ccc' }} />
         );
     });
 });
Example #9
0
  render() {

    let {outerRadius, innerRadius, fillColor, arcDescriptor, title, onClick, className} = this.props;

    let arcPath = arc().outerRadius(outerRadius).innerRadius(innerRadius);

    return (
      <g className={className} style={{fill: fillColor}} onClick={onClick}>
        <title>{title}</title>
        <path d={arcPath(arcDescriptor)}></path>
      </g>
    );
  }
Example #10
0
export const computeChordGenerators = ({ width, height, innerRadiusRatio, innerRadiusOffset }) => {
    const center = [width / 2, height / 2]
    const radius = Math.min(width, height) / 2
    const innerRadius = radius * innerRadiusRatio
    const ribbonRadius = radius * (innerRadiusRatio - innerRadiusOffset)

    const arcGenerator = d3Arc()
        .outerRadius(radius)
        .innerRadius(innerRadius)

    const ribbonGenerator = d3Ribbon().radius(ribbonRadius)

    return { center, radius, innerRadius, arcGenerator, ribbonGenerator }
}
Example #11
0
 const getPath = (edge) => {
   const pathFunction = d3Shape.arc()
   .innerRadius(r1)
   .outerRadius(r2)
   .startAngle(this.transformAngle(start))
   .endAngle(this.transformAngle(end))
   .cornerRadius(cornerRadius[edge]);
   const path = pathFunction();
   const moves = path.match(/[A-Z]/g);
   const middle = moves.indexOf("L");
   const coords = path.split(/[A-Z]/).slice(1);
   const subMoves = edge === "top" ? moves.slice(0, middle) : moves.slice(middle);
   const subCoords = edge === "top" ? coords.slice(0, middle) : coords.slice(middle);
   return subMoves.map((m, i) => ({ command: m, coords: subCoords[i].split(",") }));
 };
 renderDatum (parentElement, conf, layout) {
   return parentElement
     .selectAll('tile')
       .data((d) => d.values)
     .enter()
     .append('path')
       .attr('class', 'tile')
       .attr('opacity', conf.opacity)
       .attr('d', arc()
         .innerRadius(conf.innerRadius)
         .outerRadius(conf.outerRadius)
         .startAngle((d, i) => this.theta(d.start, layout.blocks[d.block_id]))
         .endAngle((d, i) => this.theta(d.end, layout.blocks[d.block_id]))
       )
       .attr('fill', conf.colorValue)
 }
 PieLabelComponent.prototype.update = function () {
     var startRadius = this.radius;
     if (this.explodeSlices) {
         startRadius = this.radius * this.value / this.max;
     }
     var innerArc = arc()
         .innerRadius(startRadius)
         .outerRadius(startRadius);
     // Calculate innerPos then scale outer position to match label position
     var innerPos = innerArc.centroid(this.data);
     var scale = this.data.pos[1] / innerPos[1];
     if (this.data.pos[1] === 0 || innerPos[1] === 0) {
         scale = 1;
     }
     var outerPos = [scale * innerPos[0], scale * innerPos[1]];
     this.line = "M" + innerPos + "L" + outerPos + "L" + this.data.pos;
 };
  renderBlock (parentElement, data, layout, conf) {
    const block = parentElement.selectAll('.block')
      .data(data)
      .enter().append('g')
      .attr('class', 'block')
      .attr(
        'transform',
        (d) => `rotate(${layout.blocks[d.key].start * 360 / (2 * Math.PI)})`
      )

    if (conf.backgrounds) {
      block.selectAll('.background')
        .data((d) => {
          return conf.backgrounds.map((background) => {
            return {
              start: background.start || conf.cmin,
              end: background.end || conf.cmax,
              angle: layout.blocks[d.key].end - layout.blocks[d.key].start,
              color: background.color,
              opacity: background.opacity
            }
          })
        })
        .enter().append('path')
        .attr('class', 'background')
        .attr('fill', (background) => background.color)
        .attr('opacity', (background) => background.opacity || 1)
        .attr('d', arc()
          .innerRadius((background) => {
            return conf.direction === 'in'
              ? conf.outerRadius - this.scale(background.start)
              : conf.innerRadius + this.scale(background.start)
          })
          .outerRadius((background) => {
            return conf.direction === 'in'
              ? conf.outerRadius - this.scale(background.end)
              : conf.innerRadius + this.scale(background.end)
          })
          .startAngle(0)
          .endAngle((d) => d.angle)
        )
    }

    return block
  }
Example #15
0
export const Pie = () => {
  const data = [1, 1, 2, 3, 5, 8, 13, 21];
  const arcs = pie()(data);

  const arcGen = arc()
    .innerRadius(0)
    .outerRadius(100);

  const col = lab('darkgray', 'yellow');

  return (<g>
    {arcs.map((a, i) => {
      const ratio = Math.abs(a.startAngle - a.endAngle) / 2 / Math.PI;
      return (<path
        key={'arc' + i}
        fill={col(ratio)}
        stroke={'white'}
        d={arcGen(a)}/>);
    })}
  </g>);
};
  renderDatum (parentElement, conf, layout) {
    const that = this

    return parentElement.selectAll('.tile')
      .data((d) => {
        return d.values.map((datum) => {
          const radius = that.datumRadialPosition(datum)
          return assign(datum, {
            innerRadius: radius[0],
            outerRadius: radius[1],
            startAngle: this.theta(datum.start, layout.blocks[datum.block_id]),
            endAngle: this.theta(datum.end, layout.blocks[datum.block_id])
          })
        })
      })
      .enter().append('path')
      .attr('class', 'tile')
      .attr('d', arc())
      .attr('opacity', conf.opacity)
      .attr('stroke-width', conf.strokeWidth)
      .attr('stroke', conf.strokeColor)
      .attr('fill', conf.colorValue)
  }
Example #17
0
function transformData( data ) {
	const sortedData = sortBy( data, datum => datum.value )
		.reverse()
		.map( ( datum, index ) => ( {
			...datum,
			sectionNum: index % NUM_COLOR_SECTIONS,
		} ) );

	const arcs = d3Pie()
		.startAngle( -Math.PI )
		.value( datum => datum.value )( sortedData );

	const arcGen = d3Arc()
		.innerRadius( 0 )
		.outerRadius( SVG_SIZE / 2 );

	const paths = arcs.map( arc => arcGen( arc ) );

	return sortedData.map( ( datum, index ) => ( {
		...datum,
		path: paths[ index ],
	} ) );
}
Example #18
0
  render() {
    const {
      data,
      radius = RADIUS,
    } = this.props

    const pieData = d3Shape.pie()
      .value(function (d) { return d.value; })(data)

    const arcGenerator = d3Shape.arc()
      .innerRadius(0)
      .outerRadius(RADIUS);

    const arcs = pieData.map((arc, i) => {
      const d = arcGenerator({
        startAngle: arc.startAngle,
        endAngle: arc.endAngle,
      })

      const style = {
        fill: arc.data.color,
        strokeWidth: 0,
      }
      return (
        <path key={i} d={d} style={style} />
      )
    })

    return (
      <svg width={radius * 2} height={radius * 2}>
        <g transform={`translate(${radius}, ${radius})`}>
          {arcs}
        </g>
      </svg>
    )
  }
Example #19
0
function Sector(props) {
  const arc = d3Arc()
    .outerRadius(props.radius)
    .innerRadius(props.radius - props.thickness);
  return <path d={arc(props.data)} style={{ fill: props.fill }} />;
}
  render() {
    try {
      var degreesScale = scaleLinear()
        .domain([this.state.minValue, this.state.maxValue])
        .range([10, 170]).clamp(true);

      var radianScale = scaleLinear()
        .domain([this.state.minValue, this.state.maxValue])
        .range([-80, 80]);

      var arcInset = 30;

      var arc = d3arc()
        .startAngle(deg2rad(-80))
        .endAngle(deg2rad(80))
        .innerRadius(half  - strokeWidth - arcInset)
        .outerRadius(half - arcInset)
        .cornerRadius(strokeWidth/4);

      var redArc = d3arc()
        .startAngle(deg2rad(radianScale(this.state.redLine)))
        .endAngle(deg2rad(radianScale(this.state.maxValue)))
        .innerRadius(half  - strokeWidth - arcInset)
        .outerRadius(half - arcInset)
        .cornerRadius(strokeWidth/4);

      var innerArc = d3arc()
        .startAngle(deg2rad(-80))
        .endAngle(deg2rad(80))
        .outerRadius(half  - strokeWidth - arcInset)
        .innerRadius(half / 20);

      var ticks = degreesScale.ticks([5]).slice(1,5);

      return (
        <svg height="100%" width="100%" viewBox="0 -20 400 240">
          <svg dangerouslySetInnerHTML={getShadow()} />
          <g transform={'translate(' + half + ',' + half + ' )'} stroke="black">

          {ticks.map(function(i){
            return (
              <path key={"tick-" + i}
                    d={"M -180 0 L -176 0"}
                    strokeWidth={2}
                    transform={'rotate(' + degreesScale(i) + ')'}
                    stroke="black"/>
            )
          })}

          <path d={arc()} stroke="black" strokeWidth="5" fill="white" />

          <path d={redArc()} stroke="black" strokeWidth="5" fill="red" />

          {getHand(200 - arcInset/2, degreesScale(this.state.value)-90)}

          <path d={innerArc()} stroke="none" strokeWidth="5" fill="#efefef" opacity="0.8" />

          {this.renderTicks(degreesScale)}

          <text  y="-75" textAnchor="middle" fontSize="70" dominantBaseline="middle">
            <tspan x="0">{BaseWidget.prototype.displayValue(this.state.value)}</tspan>
            <tspan x="0" dy="45" fontSize="30">{this.props.options.convertTo ? this.props.options.convertTo : (this.props.options.unit||' ')}</tspan>
            <tspan x="0" dy="32" fontSize="30">{this.props.options.label}</tspan>
          </text>

          </g>
        </svg>
      )
    } catch (ex) {
      console.log(ex)
    }
    return (<div>failsafe</div>)
  }
Example #21
0
} from 'd3-shape';

function x(item)     { return item.x || 0; }
function y(item)     { return item.y || 0; }
function w(item)     { return item.width || 0; }
function wh(item)    { return item.width || item.height || 1; }
function h(item)     { return item.height || 0; }
function xw(item)    { return (item.x || 0) + (item.width || 0); }
function yh(item)    { return (item.y || 0) + (item.height || 0); }
function cr(item)    { return item.cornerRadius || 0; }
function pa(item)    { return item.padAngle || 0; }
function def(item)   { return !(item.defined === false); }
function size(item)  { return item.size == null ? 64 : item.size; }
function type(item) { return symbols(item.shape || 'circle'); }

var arcShape    = d3_arc().cornerRadius(cr).padAngle(pa),
    areavShape  = d3_area().x(x).y1(y).y0(yh).defined(def),
    areahShape  = d3_area().y(y).x1(x).x0(xw).defined(def),
    lineShape   = d3_line().x(x).y(y).defined(def),
    trailShape  = vg_trail().x(x).y(y).defined(def).size(wh),
    rectShape   = vg_rect().x(x).y(y).width(w).height(h).cornerRadius(cr),
    symbolShape = d3_symbol().type(type).size(size);

export function arc(context, item) {
  return arcShape.context(context)(item);
}

export function area(context, items) {
  var item = items[0],
      interp = item.interpolate || 'linear';
  return (interp === 'trail' ? trailShape
Example #22
0
    return arc(i(t));
  };
}

const DonutComponent = Ember.Component.extend(GroupElement, {
  layout,

  innerRadius: 0,
  outerRadius: 200,

  pieFn() {
    return pie().padAngle(5 / 360);
  },

  arcFn() {
    return arc()
      .cornerRadius(8)
      .innerRadius(this.get('innerRadius'))
      .outerRadius(this.get('outerRadius'));
  },

  draw() {
    let values = this.get('values');
    let arcs = this.pieFn()(values);
    let arc = this.arcFn();
    let colorScale = this.get('colorScale');

    let plot = this.selection;

    let join = plot.selectAll('path').data(arcs);
    join.enter().append('path')
Example #23
0
import React from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';
import { arc } from 'd3-shape';

import AnimationComponent from '../Animation';

const radians = degress => (degress * Math.PI) / 180;
const createArc = arc();

const Aux = ({ children }) => children;
const createArcLight = (details, classes, ...props) => (
  <Aux>
    <path
      {...props}
      className={cx(classes.light, classes.elementFilter, props.className)}
      d={createArc(details)}
    />
    <path
      {...props}
      className={cx(classes.light, props.className)}
      d={createArc(details)}
    />
  </Aux>
);

export default function Logo (props) {

  const {
    theme,
    classes,
Example #24
0
 return function(t) {
   return arc(i(t));
 };
Example #25
0
 arcFn: function() {
   return arc()
     .cornerRadius(8)
     .innerRadius(this.get('innerRadius'))
     .outerRadius(this.get('outerRadius'));
 },
Example #26
0
 *
 * (c) 2016 Raphaël Benitte
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
import React from 'react'
import { arc as Arc } from 'd3-shape'
import { degreesToRadians } from '@nivo/core'
import sunburstLightNeutralImg from '../../assets/icons/sunburst-grey.png'
import sunburstLightColoredImg from '../../assets/icons/sunburst-red.png'
import sunburstDarkNeutralImg from '../../assets/icons/sunburst-dark-neutral.png'
import sunburstDarkColoredImg from '../../assets/icons/sunburst-dark-colored.png'
import { ICON_SIZE, Icon, colors, IconImg } from './styled'

const arc = Arc().padAngle(degreesToRadians(2))

const SunburstIconItem = ({ type }) => (
    <Icon id={`sunburst-${type}`} type={type}>
        <svg width={ICON_SIZE} height={ICON_SIZE}>
            <g transform={`translate(${ICON_SIZE / 2},${ICON_SIZE / 2})`}>
                <path
                    fill={colors[type].colors[4]}
                    d={arc({
                        innerRadius: ICON_SIZE * 0.26,
                        outerRadius: ICON_SIZE * 0.36,
                        startAngle: 0,
                        endAngle: degreesToRadians(120),
                    })}
                />
                <path
Example #27
0
const createSvg = ({ container, margins, width, height, parkSize }) => {

	// dimensions are coming in doubled, for canvas. we need to halve them.
	let { top, right, bottom, left } = margins
	top = top / 2
	right = right / 2
	bottom = bottom / 2
	left = left / 2
	const newWidth = width / 2
	const newHeight = height / 2

	// create svg
	const svg = select(container).append('svg')
		.attr('width', newWidth + left + right)
		.attr('height', newHeight + top + bottom)
		.attr('viewBox',
			[0, 0, newWidth + left + right, newHeight + top + bottom].join(' '))
		.attr('preserveAspectRatio', 'xMidYMid')

	const g = svg.append('g')
		.attr('class', 'root')
		.attr('transform', `translate(${newWidth / 2 + left}, ${newHeight + top})`)

	// create parkScale
	const parkScale = scaleLinear()
		.domain([0, parkSize])
		.range([0, newHeight])

	// create arc generator
	const arcGenerator = arc()
		.innerRadius(0)
		.outerRadius(parkScale(parkSize))
		.startAngle(-π / 4)
		.endAngle(π / 4)

	// make ballpark
	g.append('path')
		.attr('class', 'ballpark')
		.attr('d', arcGenerator)

	// make ballpark clip
	g.append('clipPath')
		.attr('id', 'ballpark-clip')
	.append('path')
		.attr('d', arcGenerator)

	// make grid
	g.selectAll('.grid')
		.data([200, 300, 400])
	.enter().append('circle')
		.attr('class', 'grid')
		.attr('r', parkScale)
		.attr('cx', 0)
		.attr('cy', 0)

	// make grid ticks
	g.selectAll('.tick')
		.data([200, 300, 400])
	.enter().append('text')
		.attr('class', 'tick benton-cond-regular')
		.attr('x', d => parkScale(Math.cos(-π / 4) * d))
		.attr('y', d => parkScale(Math.sin(-π / 4) * d))
		.attr('dx', 0)
		.attr('dy', 10)
		.text((d, i) => i === 0 ? `${d}ft` : d)

	// make infield
	g.append('circle')
		.attr('class', 'infield')
		.attr('clip-path', 'url(#ballpark-clip)')
		.attr('r', parkScale(95))
		.attr('cx', 0)
		.attr('cy', -parkScale(Math.sqrt(2 * Math.pow(90, 2)) / 2))

	// make diamond
	g.append('rect')
		.attr('class', 'diamond')
		.attr('width', parkScale(90))
		.attr('height', parkScale(90))
		.attr('x', 0)
		.attr('y', -parkScale(90))
		.attr('transform',
			`rotate(-45) translate(${parkScale(10)}, -${parkScale(10)})`)

	return svg

}
Example #28
0
function w(item)    { return item.width || 0; }
function ts(item)   { return item.size || 1; }
function h(item)    { return item.height || 0; }
function xw(item)   { return (item.x || 0) + (item.width || 0); }
function yh(item)   { return (item.y || 0) + (item.height || 0); }
function sa(item)   { return item.startAngle || 0; }
function ea(item)   { return item.endAngle || 0; }
function pa(item)   { return item.padAngle || 0; }
function ir(item)   { return item.innerRadius || 0; }
function or(item)   { return item.outerRadius || 0; }
function cr(item)   { return item.cornerRadius || 0; }
function def(item)  { return !(item.defined === false); }
function size(item) { return item.size == null ? 64 : item.size; }
function type(item) { return symbols(item.shape || 'circle'); }

var arcShape    = d3_arc().startAngle(sa).endAngle(ea).padAngle(pa)
                          .innerRadius(ir).outerRadius(or).cornerRadius(cr),
    areavShape  = d3_area().x(x).y1(y).y0(yh).defined(def),
    areahShape  = d3_area().y(y).x1(x).x0(xw).defined(def),
    lineShape   = d3_line().x(x).y(y).defined(def),
    rectShape   = vg_rect().x(x).y(y).width(w).height(h).cornerRadius(cr),
    symbolShape = d3_symbol().type(type).size(size),
    trailShape  = vg_trail().x(x).y(y).defined(def).size(ts);

export function arc(context, item) {
  return arcShape.context(context)(item);
}

export function area(context, items) {
  var item = items[0],
      interp = item.interpolate || 'linear';
Example #29
0
File: Pie.js Project: lineCode/vx
export default function Pie({
  className = '',
  top = 0,
  left = 0,
  data,
  centroid,
  innerRadius = 0,
  outerRadius,
  cornerRadius,
  startAngle = 0,
  endAngle,
  padAngle,
  padRadius,
  pieSort,
  pieSortValues,
  pieValue,
  children,
  ...restProps
}) {
  const path = d3Arc();
  path.innerRadius(innerRadius);
  if (outerRadius) path.outerRadius(outerRadius);
  if (cornerRadius) path.cornerRadius(cornerRadius);
  if (padRadius) path.padRadius(padRadius);
  const pie = d3Pie();
  if (pieSort) pie.sort(pieSort);
  if (pieSortValues) pie.sortValues(pieSortValues);
  if (pieValue) pie.value(pieValue);
  if (padAngle != null) pie.padAngle(padAngle);
  if (startAngle != null) pie.startAngle(startAngle);
  if (endAngle != null) pie.endAngle(endAngle);
  const arcs = pie(data);
  const renderFunctionArg = {
    arcs,
    generatePathProps: (arc, index) => ({
      className: cx('vx-pie-arc', className),
      d: path(arc),
      ...additionalProps(restProps, {
        ...arc,
        index,
        centroid: centroid ? path.centroid(arc) : undefined
      })
    }),
    generateCentroid: arc => centroid && centroid(path.centroid(arc), arc)
  };
  return (
    <Group className='vx-pie-arcs-group' top={top} left={left}>
      {children
        ? children(renderFunctionArg)
        : arcs.map((arc, i) => {
            const pathProps = renderFunctionArg.generatePathProps(arc, i);
            return (
              <g key={`pie-arc-${i}`}>
                <path {...pathProps} />
                {renderFunctionArg.generateCentroid(arc)}
              </g>
            );
          })}
    </Group>
  );
}
Example #30
0
function NutritionRatioChart({ radius, foods, db, weight }) {
  var totalCalories = foods
    .map(([name, amount]) => amount * kcal(db, name))
    .reduce((a, b) => a + b, 0);

  var totalProtein = foods
    .map(([name, amount]) => amount * protein(db, name))
    .reduce((a, b) => a + b, 0);

  var totalFat = foods
    .map(([name, amount]) => amount * fat(db, name))
    .reduce((a, b) => a + b, 0);

  var totalCarbs = foods
    .map(([name, amount]) => amount * carbs(db, name))
    .reduce((a, b) => a + b, 0);

  var total = totalProtein * 4 + totalCarbs * 4 + totalFat * 9;

  var size = radius * 2;

  var a = arc()
    .outerRadius(radius)
    .innerRadius(radius - 4)
    .padAngle(Math.PI / 135);

  var outerArc = arc()
    .innerRadius(radius * 1.5)
    .outerRadius(radius * 1.5);

  return (
    <NutritionPie
      totalProtein={totalProtein}
      totalFat={totalFat}
      totalCarbs={totalCarbs}
    >
      {p => (
        <svg
          width={size}
          height={size}
          viewBox={`0 0 ${size} ${size}`}
          style={{ display: "block", margin: "auto", overflow: "visible" }}
        >
          <g textAnchor="middle">
            <Motion
              style={{
                value: spring(totalCalories, {
                  stiffness: 210,
                  damping: 20,
                  precision: 0.01
                })
              }}
            >
              {({ value }) => (
                <text x="50%" y="50%" dx="10">
                  <tspan
                    alignmentBaseline="central"
                    fontSize="3rem"
                    fill="#555"
                  >
                    {toFixed(value, 0)}
                  </tspan>
                  <tspan dy="1.15rem" fontSize="0.8rem" fill="#777">
                    ккал
                  </tspan>
                </text>
              )}
            </Motion>

            <g transform={`translate(${radius}, ${radius})`}>
              {p.map((d, i) => (
                <g key={i}>
                  <path d={a(d)} fill={d.data.color} />
                  <text
                    fill={d.data.textColor || d.data.color}
                    value={d.data.value}
                    x={outerArc.centroid(d)[0]}
                    y={outerArc.centroid(d)[1]}
                    dy={annotationOffset(d)}
                    textAnchor="middle"
                    fontSize="0.9rem"
                    alignmentBaseline="central"
                  >
                    {`${toFixed(d.data.value, 0)}г / ${toFixed(
                      (d.data.calories / total) * 100,
                      0
                    )}% / ${toFixed(d.data.value / weight, 1)}`}
                  </text>
                </g>
              ))}
            </g>
          </g>
        </svg>
      )}
    </NutritionPie>
  );
}