Quantcast
Channel: Active questions tagged python - Stack Overflow
Viewing all articles
Browse latest Browse all 17477

Adding interaction for my customed ipywidgets component

$
0
0

I used the ipywidgets to define a customed component in jupyter notebook, but when I adding interaction to my component, it can't work.The component class is:

from __future__ import print_functionimport ipywidgets as widgets# from traitlets import Unicode, validateimport traitletsclass VerticalSliderModel(widgets.DOMWidget):    _view_name = traitlets.Unicode('VerticalSliderView').tag(sync=True)    _view_module = traitlets.Unicode('vertical_slider').tag(sync=True)    value0 = traitlets.Float(250, min=0, max=1000).tag(sync=True)    color0 = traitlets.Unicode('#0000FF').tag(sync=True)    value1 = traitlets.Float(600, min=0, max=1000).tag(sync=True)    color1 = traitlets.Unicode('#0000FF').tag(sync=True)    value2 = traitlets.Float(750, min=0, max=1000).tag(sync=True)    color2 = traitlets.Unicode('#0000FF').tag(sync=True)    _min = traitlets.Float(0.0).tag(sync=True)    _max = traitlets.Float(1000.0).tag(sync=True)    value = 2000

And the View coded by js is (The important part is 'update the value2'):

%%javascriptrequire.undef('vertical_slider');define('vertical_slider', ["@jupyter-widgets/base"], function(widgets) {    var VerticalSliderView = widgets.DOMWidgetView.extend({        initialize: function() {            this.axis = null;            this.sliders = [];            this.valueLabels = [];            this.colorPickers = [];            this.isDragging = [];            this.startY = [];            this.colorPickers = [];            for (var i = 0; i < this.nSliders; i++) {                this.isDragging.push(false);            }        },        render: function() {            this.axis = document.createElement('div');            this.axis.className = 'line';              this.el.appendChild(this.axis);            this.nSliders = 3;            for (var i = 0; i < this.nSliders; i++) {                this.createSlider(i, i*200);            }        createSlider: function(index, initialValue) {            console.log("initialValue:", initialValue);            var slider = document.createElement('div');            slider.id = 'slider'+ index;            slider.className = 'slider';            console.log("slider:this.axis.offsetHeight:", this.axis.offsetHeight);            console.log("slider.offsetHeight:", slider.offsetHeight);            slider.style.top = (initialValue / 1000) * 200 +'px';            console.log("slider.style.top:", slider.style.top);            this.axis.appendChild(slider);            var valueLabel = document.createElement('div');            valueLabel.className = 'value-label';            valueLabel.id = 'value'+ index;            valueLabel.textContent = initialValue;            slider.appendChild(valueLabel);            var colorPicker = document.createElement('input');            colorPicker.type = 'color';            colorPicker.style.display = 'none';            this.el.appendChild(colorPicker);            this.sliders[index] = slider;            this.valueLabels[index] = valueLabel;            this.colorPickers[index] = colorPicker;            slider.addEventListener('mousedown', this.startDrag.bind(this, index));            slider.addEventListener('click', this.changeColor.bind(this, index));        },        startDrag: function(index, e) {            console.log(this.sliders);            console.log("index:", index);            console.log("e:", e);            this.isDragging[index] = true;            this.startY[index] = e.clientY - this.sliders[index].offsetTop;            document.addEventListener("mousemove", this.move.bind(this, index));            document.addEventListener("mouseup", this.up.bind(this, index));        },        move: function(index, e) {            if (!this.isDragging[index]) return;            const minPos =                 index === 0                    ? 0                    : this.sliders[index-1].offsetTop + 10;            const maxPos =                index === this.sliders.length - 1                  ? this.sliders[index].parentNode.offsetHeight - this.sliders[index].offsetHeight                  : this.sliders[index + 1].offsetTop - 10;            if(pos < minPos) pos = minPos;            if(pos > maxPos) pos = maxPos;            let minValue = 0;            let maxValue = 1000;            let valuePerPixel = (maxValue - minValue) / 200;            let newValue = Math.round(minValue + pos * valuePerPixel);            if(newValue > 1000) newValue = 1000;            if(newValue < 0) newValue = 0;            this.sliders[index].style.top = Math.min(Math.max(pos, minPos), maxPos) +'px';            //----------------update the value2--------------------------------            this.model.set('value2', newValue);            console.log("this.model.value+:", this.model);            //-----------------------------------------------------------------            this.valueLabels[index].textContent = newValue;            this.touch();        },        up: function(index, e) {            document.removeEventListener("mousemove", this.move.bind(this, index));            document.removeEventListener("mouseup", this.up.bind(this, index));            this.isDragging[index] = false;            this.colorPickers[index].style.display = 'none';        },        changeColor: function(index) {            event.preventDefault();             event.stopPropagation();             if (this.isDragging[index]) return;            this.colorPickers[index].style.display = "inline";            this.colorPickers[index].value = this.sliders[index].style.backgroundColor;             console.log("colorPicker.value:", this.colorPickers[index].value);            this.colorPickers[index].addEventListener("change", this.applyColor.bind(this, index));        },        applyColor: function(index) {            this.model.set('color'+ index, this.colorPickers[index].value);            console.log('color'+ index, this.colorPickers[index].value);            this.colorPickers[index].style.display = "none";            this.sliders[index].style.backgroundColor = this.colorPickers[index].value;            this.touch();        },    });    return {        VerticalSliderView: VerticalSliderView    };});

Then I adding interaction using 'observe'. What I want is, as the value2 changes, the 'update_plot' function will be excuted, so the plot will be updated. However, when value2 changes(see the js code, update the value2), the plot won't update. When I print, I find the value2 in update_plot is no change.

# out = widgets.Output()def update_plot(change):# with out:    plt.clf()    value = change['new']    print(value)    fig, ax = plt.subplots()    x = np.linspace(0, value * np.pi)    line, = ax.plot(x, np.sin(x))    line.set_ydata(np.sin(2 * x))#     plt.draw() vertical_slider = VerticalSliderModel()vertical_slider.observe(update_plot, names='value2')display(vertical_slider)update_plot({'new': vertical_slider.value2})

I want the plot will be updated when i change the value2.


Viewing all articles
Browse latest Browse all 17477

Latest Images

Trending Articles



Latest Images

<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>