问题
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