Решить обещания с D3 - PullRequest
       5

Решить обещания с D3

0 голосов
/ 07 января 2020

Я пытаюсь создать граф с D3, где данные должны быть загружены с контроллера REST. Вот код для узлов, с которыми у меня возникают проблемы:

async function request(partNumber) {
    var response = await fetch(restURL + partNumber)
    var grafic = await response.text()
    return grafic
  }

nodes.selectAll("nodeSvg")
    .data(d => [d])
    .enter()
    .append("g")
    .attr("transform", function(d) { 
        return "translate(" + [offsetX + d.x * scale + svgOffsetX, offsetY + d.y * scale + svgOffsetY] + ") scale(0.1 0.1)"; })
    .html(async (d) => {
        if (d.partNumber === "") {
            return "";
        }
        return await request(d.partNumber);
    });

Как вы видите, я создаю поток для данных. Каждая из записей данных имеет partNumber, который мне нужен, чтобы получить строку HTML из RestApi. Эта строка является строкой SVG, которая при жестком кодировании создает изображение в виде узла. Но если я не закодирую это жестко и не запрашиваю его (который фактически дает мне строку, если я устанавливаю точку останова), узлы не создаются. Как я могу решить эту проблему?

Заранее спасибо!

РЕДАКТИРОВАТЬ: я использую D3v5, который добавил Promises, но я не уверен, если и как это может помочь мне

РЕДАКТИРОВАТЬ2: Сделал вопрос более ясным

РЕДАКТИРОВАТЬ3: Я нашел решение, которое позволяет мне добавить svgs после загрузки остальной части графика, что будет лучше, если есть много svgs для загрузки из ОТДЫХ Api. Вот как я это сделал:

async function request(partNumber) {
    if (partNumber !== "") {
        var response = await fetch(restURL + partNumber)
        return await response.text()
    }
  }

drawing.nodes.forEach((d) => {
    if (d.partNumber === "") {
        d.graphic = "";
    }
    request(d.partNumber).then((e) => {
        d.graphic = e;
        nodes.selectAll("nodeSvg")
            .data(d => [d])
            .enter()
            .append("g")
            .attr("transform", function(d) {
                return translateNode(d); })
            .html((d) => {
                return d.graphic
            });
    });

})

Я только что переместил часть, которая создает узлы, в часть ".then ()". Оказывается, D3 просто обновляет измененные значения вместо того, чтобы перерисовывать его снова и снова, как в al oop.

В любом случае: Спасибо Миккель за ваш ответ!

1 Ответ

1 голос
/ 08 января 2020

Добро пожаловать в переполнение стека.

Здесь происходит несколько вещей, которые могут быть не идеальными.

1) Ваша функция request выполняет 2 ожидания подряд, что не очень хорошо - я бы рекомендовал использовать библиотека ax ios (вместо выборки), которая будет возвращать вам данные без необходимости .then() или await.

2) D3 является декларативным языком и работает немного по-другому. Вы передаете функцию в html(), что, вероятно, нормально, ее объявление выглядит хорошо, и оно вполне может работать. Однако я бы поставил под сомнение необходимость выполнения вызова API для каждого элемента на вашей странице / чертеже - производительность не будет высокой, поэтому я хотел бы подумать о переборе входящих данных и сборке всей информации о детали до Вы начинаете рендеринг.

Это позволит вам гораздо более понятный пользовательский интерфейс, вы сможете отображать счетчик во время загрузки данных, и, как только вы его получите, рендеринг будет быстрым (и не прерывистым)

Может быть, исправление 1) решит проблему, но я бы порекомендовал также решить проблему 2). Удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...