Code Monkey home page Code Monkey logo

d3-web-component-example's Introduction

d3-web-component-example

d3-web-component-example's People

Contributors

jaysunsyn avatar

Stargazers

Michael Potter avatar

Watchers

 avatar  avatar

d3-web-component-example's Issues

Instead of using d3 to imperatively compute DOM, use lit

const g = svg.append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

in this line, you're using d3's imperative api to define DOM, but Lit gives you a declarative api for this. consider this example, which uses d3 to compute geometry, but Lit to layout the DOM. Uou could extend this example to add lines and labels.

import { pie, arc } from 'd3';
import type { Arc, PieArcDatum, DefaultArcObject } from 'd3';

export type LabeledData = LabeledDatum[]

type ArcSlice = DefaultArcObject & PieArcDatum<LabeledDatum>;

@customElement('donut-chart')
export class DonutChart extends LitElement {
  @property({ attribute: false }) arcRatio = 0.8;

  @property({ attribute: false }) data: LabeledData[] = [];

  width = 100;

  get height(): number {
    return (this.width * (4 / 5));
  }

  get arcScale(): number {
    return 0.9;
  }

  constructor() {
    super();
    this.updateScalingFactor(this.getBoundingClientRect().width);
  }

  get radius(): number {
    return Math.min(this.width, this.height) / 2;
  }

  render(): TemplateResult {
    const { height, width } = this;
    const { arcRatio, arcScale, radius, scalingFactor } = this;

    const slices = pie<LabeledDatum>()
      .value(d => d.value)
      .sort(null)
      .sortValues(null)(this.data);

    const donutArc = arc()
      .innerRadius(radius * arcScale)
      .outerRadius(radius * arcScale * arcRatio);

    const xOffset = width / 2;
    const yOffset = height / 2;

    return svg`
      <svg id="pie" part="pie" viewBox="-${xOffset} -${yOffset} ${width} ${height}">
        ${slices.map((d: ArcSlice, i: number) => svg`
          <path data-slice="${d.data.key}"
                data-index="${i}"
                part="slice ${d.data.key}"
                vector-effect="non-scaling-stroke"
                d="${donutArc(d)}"
                title="${d.data.label ?? d.data.key} - ${d.data.value}"
          ></path>
        `)}
      </svg>
    `;
  }

  updated(changed: PropertyValues<this>): void {
    if (changed.has('width'))
      this.updateScalingFactor(this.getBoundingClientRect().width);
  }

  updateScalingFactor(width: number): void {
    this.scalingFactor = 2 * this.width / (width === 0 ? this.width : width);
  }
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.