2017-02-15 24 views
6

Можно ли использовать D3 с помощью Elm с помощью портов? Я пробовал Elm, но я не могу найти примеры использования Elm с D3 без API-интерфейса обертки. Проблема, с которой я столкнулся, заключается в том, что wrapper и вилки не работают с 0,18. Я также вижу много заявлений, которые предполагают, что создание API вокруг API-интерфейсов javascript является плохой практикой, и вместо этого вы должны использовать порты. Однако я не могу найти примеры этого с D3. Я нашел this example, но часть D3 была сделана на простом javascript, который не подходит.Использование D3 с Elm

Я, вероятно, слишком агрессивен, беря на себя D3 прямо на лету с Elm, но это действительно то, что я хочу с ним делать. Если это не реально использовать D3 с Elm, я, вероятно, сейчас не буду с этим обдумывать. Существует ли фундаментальная проблема с таким взаимодействием или это просто отсутствие интереса к D3 в сообществе Elm, или я просто что-то пропустил?

Например, возьмите этот код вырванные из примера bl.ocks выше:

var t = d3.transition().duration(750); 
var g = d3.select("svg g") 
// JOIN new data with old elements. 
var text = g.selectAll("text") 
    .data(data, function(d) { return d; }); 

// ENTER new elements present in new data. 
text.enter().append("text") 
    .attr("class", "enter") 
    .attr("dy", ".35em") 
    .attr("y", -60) 
    .attr("x", function(d, i) { return i * 24; }) 
    .style("fill-opacity", 1e-6) 
    .text(function(d) { return d; }) 
    .transition(t) 
    .attr("y", 0) 
    .style("fill-opacity", 1); 

Есть ли простой перевод в Элм для такого рода вещи?

+1

Вот пример работы с портами и большой библиотекой JS (Google Maps) HTTP: //simonh1000.github .io/2016/12/elm-ports-google-maps/Это может помочь вам –

+0

@SimonH Спасибо за вашу помощь. Я смотрел на некоторые подобные вещи, но где я боюсь, так это то, что d3 использует множество ссылок на методы. Вам необходимо передать ему функции и вызвать функции, которые возвращают функции (которые также являются объектами). Я не знаю, как это сделать в Вязе, так что я надеюсь найти рабочий (простой) пример для начала. – JimmyJames

+0

Можете ли вы представить пример кода, который вы должны пройти через порт. Разверните свой вопрос, чтобы показать, какую функциональность вы хотите получить в D3 от Elm –

ответ

3

Я знаю только немного о D3. Вам нужно будет поместить всю обработку данных в Elm и просто передать данные в код js, который управляет D3. Это сохранит вашу модель.

Вам также необходимо следить за D3, изменяя DOM, потому что тогда Elm будет пытаться обновить части страницы, за которую он несет ответственность. Лучше всего было бы вырезать страницу с помощью деталей вяза и других деталей с помощью Elm.embed. Но вы могли бы написать Elm всю страницу и позволить D3 мутировать DOM, если вы используете Html.keyed, чтобы помочь Elm отслеживать, что есть в DOM.

Html.keyed.div "d3node" 
    [ ] 
    [ ... ensure that d3 only touches DOM elements inside this node ... ] 

Вы можете передавать функции как таковые через порт, но вы можете передать json. так что вы можете использовать вяз, чтобы создать что-то вроде

{ function_type: "f1", 
    param1: .... 
    param2: ... 
} 

Тогда вы можете в JS сделать

switch (data.function_type) of 
    case "f1: 
    function1 (data.param1, data.param2); 
... 


function1(p1, p2) { 
    // some sort of D3 manipulation 
    var text = g.selectAll(p1) 
    .data(data, p2); 
+0

Так что виды взаимодействия с javascript в примере кода невозможны в Elm? – JimmyJames

+0

проблема в том, что код, который вы предлагаете, мутирует DOM, и что _could_ путают обновление DOM в Elm. Я не уверен наверняка, и это может потребоваться, чтобы быть уверенным.Но использование keyed поможет –

+0

OK, это полезно, но то, что я действительно ищу, это помощь в том, как я могу передавать функции D3 и как извлекать функции/объекты из D3, чтобы передать их обратно в D3. Взаимодополняющая документация для Elm, которую я нашел, кажется, говорит только о простых взаимодействиях. Мое предпочтение (по крайней мере на начальном этапе) - фактически делать все презентации с D3. Он может обрабатывать любые манипуляции с DOM, а не только SVG и т. Д. – JimmyJames

0

Ваша проблема может быть решена с помощью webcomponent как multi-chart.

Импорт компонент внутри index.html и создать узел с атрибутами, которые вы хотите:

Html.node "multi-chart" [ Html.Attributes.attribute "title" "test chart" ] [] 
+0

Я не понимаю, как это отвечает на вопрос. В частности, я ничего не вижу в этом проекте, относящемся к Elm. – JimmyJames

+0

Что я хотел сказать, что в большинстве случаев лучший способ взаимодействия с javascript и Elm - это не использование портов, а использование веб-компонентов. Я узнал от шести месяцев использования Elm в производственных приложениях. Пожалуйста, проверьте этот разговор от rtfeldman: https://www.youtube.com/watch?v=ar3TakwE8o0e – Lisard

+0

Я думаю, я не уверен, как это помогает мне. Я хочу написать весь пользовательский интерфейс с D3. Бизнес-логика будет на сервере. Что осталось, что я буду использовать Элма? – JimmyJames