simple bar plot with mithril.js and d3.js

折月煮酒 提交于 2021-01-29 08:47:07

问题


I am very very new to javascript and mithril.js. I am trying to create a very simple bar plot using mithril.js and d3.js. But, I am not having any luck even getting the axis in place.

Firstly, I created a mithril "svg" component and appended a mithril "g" compent as follows:

var g = m(gView, {transpose:"translate(10, 10)"})
var svg = m(SVGView, {width: 100, height:100}, g)

where gView and SVGView are as follows:

var gView = {
view: function(vnode) {
return m("g", vnode.attrs, [vnode.children]);
    }
}

var SVGView = {
    view: function(vnode) {
    return m("svg", vnode.attrs, [vnode.children]);
    }
}

Now I created a simple axis scale and an axis function as follows:

var xScale = d3.scaleLinear()
        .domain([0, 10])
        .range([0, 40]);

var xAxis = d3.axisBottom(xScale)

How do I add my xAxis to my mithril component svg?

I saw many many examples where they just use .call(xAxis) but this works only with a d3.select(). I don't want to use and cannot use a d3.select() as I have to work with mithril.

If my question/code is stupid or if my approach is totally wrong please excuse me. I searched for a simple bar plot build using mithril and I couldn't find anything. So, any help is appreciated or even a redirection to a source where I can read about plotting graphs in mithril is apprecated. Thanks!


回答1:


As far as I know there is not a great way to perfectly fit d3 into a mithriljs app without just letting d3 run a subtree of the dom by itself.

I created a simple example based off your code above and this mithril js example from the documentation at: bootstrap-fullcalendar-example

Note that the BarChart component always tells mithril that it is only rendering a div inside of its view therefore after its first draw it will never be redrawn again even though d3 is manipulating the dom below that div. This is critical because you don't want to draw something with d3 and then have mithril draw over it or the opposite.

In order to manipulate the bar chart you will have to use d3.select inside the App using the dom element that was saved off in barChartEl. I created a silly example of this that just pushes the bar chart to the right once and then you can reset it with the other button. I don't know enough about d3 sorry but you get the idea. Also note that barChartEl is the div and not the svg node but I can still select down to the g or you could directly select the svg there.

This code was written to use d3 v5 and mithril 2.0.4.

// Assumes that d3 available.


function BarChart() {
  return {
    oncreate: function (vnode) {
      var xScale = d3.scaleLinear()
        .domain([0, 10])
        .range([0, 40]);

      var xAxis = d3.axisBottom(xScale)
      d3.select(vnode.dom).append("svg")
        .attr("width", 100)
        .attr("height", 100)
        .append("g")
        .attr("transform", "translate(10,10)")
        .call(xAxis);
    },
    view: function (vnode) {
      return m('div');
    }
  }
}

function App() {
  
  var barChartEl = null;
  return {
    view: function (vnode) {
      return m('div', [
        m('button[type=button]', {
          onclick: function () { 
           d3.select(barChartEl).select("g").attr('transform', "translate(50,10)");
          }
        }, 'BarChart Right'),
        m('button[type=button]', {
          onclick: function () { 
           d3.select(barChartEl).select("g").attr('transform', "translate(10,10)");
          }
        }, 'BarChart Reset'),
        m(BarChart, {
        oncreate: function (vnode) { 
          // Save off bar chart element in case we need to reference it
          // with d3.select. 
          barChartEl = vnode.dom; 
        }
      })]);
    }
  }
}

m.mount(document.body, App);

Also this example code uses the closure style components as seen in the documentation here in order to store state: closure-component-state.



来源:https://stackoverflow.com/questions/62924959/simple-bar-plot-with-mithril-js-and-d3-js

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!