Изучение D3 Js с помощью Observablehq - PullRequest
0 голосов
/ 14 июля 2020

Я пытаюсь создать сгруппированную гистограмму с angular 9. Я имею в виду

https://observablehq.com/@d3 / grouped-bar-chart

и i получить вывод для приведенного ниже кода.

Пример кода для подтверждения работы d3 js

const svg = d3.select(this.svg.nativeElement)
          .attr('width', '100%')
          .attr('height', '500px');

svg.selectAll("rect")
.data(this.data)
.enter().append("rect")
      .attr("height","250")
      .attr("width","40")
      .attr("x", function(d, i) {return (i * 60) + 25})
      .attr("y","50");

код для создания сгруппированной гистограммы

draw(){
  const svg = d3.select(this.svg.nativeElement)
          .attr('width', '100%')
          .attr('height', '500px');
  svg.append("g")
    .selectAll("g")
    .data(data)
    .join("g")
      .attr("transform", d => `translate(${x0(d[groupKey])},0)`) // referring to x0 function, it takes a param d[groupKey]
    .selectAll("rect")
    .data(d => keys.map(key => ({key, value: d[key]})))
    .join("rect")
      .attr("x", d => x1(d.key))
      .attr("y", d => y(d.value))
      .attr("width", x1.bandwidth())
      .attr("height", d => y(0) - y(d.value))
      .attr("fill", d => color(d.key)); //pass param key to color function

  svg.append("g")
      .call(xAxis);

  svg.append("g")
      .call(yAxis);

  svg.append("g")
      .call(legend);
}

Обращаясь к функции x0

x0(??){ // what is the arg that is received here? and where is it used inside this function What is the return value?
 d3.scaleBand()
    .domain(data.map(d => d[groupKey]))
    .rangeRound([margin.left, width - margin.right])
    .paddingInner(0.1)
}

Обращаясь к функции цвета

color(??){  // what is the arg that is received here? and where is it used inside this function? What is the return value?

d3.scaleOrdinal()
    .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"])

}

Обращаясь к Legend / Xaxis / Yaxis вопрос остается тем же.

Я ищу ответ, как преобразовать observablehq в машинописный текст.

edit 1 - обновленный код

draw(){

const svg = d3.select(this.chart.nativeElement)
      .append('svg')
      .attr('width', '100%')
      .attr('height', '500px');
    const color = d3.scaleOrdinal()
      .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"])
    const legend = svg => {
      const g = svg
        .attr("transform", `translate(${this.width},0)`)
        .attr("text-anchor", "end")
        .attr("font-family", "sans-serif")
        .attr("font-size", 10)
        .selectAll("g")
        .data(color.domain().slice().reverse())
        .join("g")
        .attr("transform", (d, i) => `translate(0,${i * 20})`);

      g.append("rect")
        .attr("x", -19)
        .attr("width", 19)
        .attr("height", 19)
        .attr("fill", color);

      g.append("text")
        .attr("x", -24)
        .attr("y", 9.5)
        .attr("dy", "0.35em")
        .text(d => d);
    }

    const x0 = d3.scaleBand()
      .domain(this.data.map(d => d[this.groupKey]))
      .rangeRound([this.margin.left, this.width - this.margin.right])
      .paddingInner(0.1);
    const x1 = d3.scaleBand()
      .domain(this.keys)
      .rangeRound([0, x0.bandwidth()])
      .padding(0.05)
    const y = d3.scaleLinear()
      .domain([0, d3.max(this.data, d => d3.max(this.keys, key => d[key]))]).nice()
      .rangeRound([this.height - this.margin.bottom, this.margin.top])
    const xAxis = g => g
      .attr("transform", `translate(0,${this.height - this.margin.bottom})`)
      .call(d3.axisBottom(x0).tickSizeOuter(0))
      .call(g => g.select(".domain").remove());
    const yAxis = g => g
      .attr("transform", `translate(${this.margin.left},0)`)
      .call(d3.axisLeft(y).ticks(null, "s"))
      .call(g => g.select(".domain").remove())
      .call(g => g.select(".tick:last-of-type text").clone()
        .attr("x", 3)
        .attr("text-anchor", "start")
        .attr("font-weight", "bold")
        .text(this.data.y))

    svg.append("g")
      .selectAll("g")
      .data(this.records)
      .join("g")
      .attr("transform", d => {
        console.log(x0(d[this.groupKey]));  // output is undefined
       return `translate(${x0(d[this.groupKey])},0)`
      })
      .selectAll("rect")
      .data(d => this.keys.map(key => ({ key, value: d[key] })))
      .join("rect")
      .attr("x", d => x1(d.key))
      .attr("y", d => y(d.value))
      .attr("width", x1.bandwidth())
      .attr("height", d => y(0) - y(d.value))
      .attr("fill", d => color(d.key));

    svg.append("g")
      .call(xAxis);

    svg.append("g")
      .call(yAxis);

    svg.append("g")
      .call(legend);

}

1 Ответ

0 голосов
/ 14 июля 2020

Observable не Javascript. Что касается того, о чем вы спрашиваете, я думаю, у вас возникает путаница по этому поводу:

color = ƒ(i) // 1
color = d3.scaleOrdinal()
        .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]) // 2

Второе объявление - это фактическое объявление оператора. scaleOrdinal () возвращает функцию, которая принимает один параметр. Первый оператор - это не присвоение, а представление значения внутри color.

Здесь значение color - это функция (возвращаемая scaleOrdinal), которая принимает один параметр, и он представлен как f(t). Нет закрывающей функции.

Итак, в вашем коде вы можете использовать:

color = d3.scaleOrdinal()
        .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...