• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

docinfosci / canvasxpress-python / d22919bd-b9cc-4609-8db6-644e77c67cb3

14 Dec 2024 06:12AM UTC coverage: 78.721%. Remained the same
d22919bd-b9cc-4609-8db6-644e77c67cb3

push

circleci

web-flow
Merge pull request #150 from docinfosci/streamlit-integration-fix

Streamlit integration fix continued

0 of 1 new or added line in 1 file covered. (0.0%)

2031 of 2580 relevant lines covered (78.72%)

0.79 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/canvasxpress/render/streamlit.py
1
import uuid
×
2
from typing import Union, List
×
3

4
from canvasxpress.canvas import CanvasXpress
×
5
import streamlit.components.v1 as components
×
6

7
_cx_iframe_padding = 50
×
8

9
_cx_fx_template = """
×
10
<script type="text/javascript">
11
    @code@
12
</script>
13
"""
14

15
_cx_default_css_url = "https://www.canvasxpress.org/dist/canvasXpress.css"
×
16

17
_cx_versioned_css_url = (
×
18
    "https://cdnjs.cloudflare.com/ajax/libs/canvasXpress/@cx_version@/canvasXpress.css"
19
)
20

21
_cx_default_js_url = "https://www.canvasxpress.org/dist/canvasXpress.min.js"
×
22

23
_cx_versioned_js_url = "https://cdnjs.cloudflare.com/ajax/libs/canvasXpress/@cx_version@/canvasXpress.min.js"
×
24

25
_cx_html_template = """
×
26
<html>
27
    <head>
28
        <meta charset="UTF-8">
29
        <title>CanvasXpress</title>
30

31
        <!-- 1. Include the CanvasXpress library -->
32
        @canvasxpress_license@
33
        <link 
34
                href='@css_url@' 
35
                rel='stylesheet' 
36
                type='text/css'
37
                referrerpolicy='origin-when-cross-origin'
38
        />
39
        <script 
40
                src='@js_url@' 
41
                type='text/javascript'>
42
                referrerpolicy='origin-when-cross-origin'
43
        </script>
44
    </head>
45
    <body>
46
        <!-- 3. DOM element where the visualization will be displayed -->
47
        @canvases@
48
        <!-- 2. Include script to initialize object -->
49
        @js_functions@
50
     </body>
51
</html>
52
"""
53

54

55
def plot(
×
56
    cx: Union[CanvasXpress, List[CanvasXpress]],
57
    columns: int = 1,
58
) -> Union[object, None]:
59
    """
60
    Renders the provided CanvasXpress object(s) for display in a Streamlit application.
61
    :param cx: `Union[CanvasXpress, List[CanvasXpress]]`
62
        The `CanvasXpress` object(s) to be tracked. Charts cannot have the same name,
63
        so render_to will be updated with a uuid for each conflicting chart.
64
    :param columns: `int`
65
        Indicates how many charts should be rendered horizontally in the Streamlit
66
        application if more than one chart is being tracked. Any positive `int` of `1`
67
        or greater is accepted, with a default value of `1`. Values less than `1`
68
        are ignored.
69
    :returns: `None` or raises a `TypeError` exception if `cx` is not a CanvasXpress
70
        object or list of CanvasXpress objects.
71
    """
72

73
    columns = int(columns)
×
74
    columns = columns if columns > 0 else 1
×
75

76
    render_targets = list()
×
77

78
    if cx is None:
×
79
        return None
×
80

81
    elif isinstance(cx, CanvasXpress):
×
82
        render_targets.append(cx)
×
83

84
    else:
85
        render_targets.extend(cx)
×
86

87
    used_render_targets = list()
×
88
    for i, target in enumerate(render_targets):
×
89
        if not isinstance(target, CanvasXpress):
×
90
            raise TypeError(f"Item {i} in argument 'cx' is not a CanvasXpress object")
×
91

92
        original_render_target = target.render_to
×
93
        if original_render_target in used_render_targets:
×
94
            target.render_to = (
×
95
                original_render_target + "_" + str(uuid.uuid4()).replace("-", "_")
96
            )
97

98
        used_render_targets.append(target.render_to)
×
99

100
    render_targets.reverse()
×
101

102
    html_parts = [target.render_to_html_parts() for target in render_targets]
×
103

104
    canvases = [part["cx_canvas"] for part in html_parts]
×
105
    if len(canvases) < columns:
×
106
        columns = len(canvases)
×
107

108
    functions = [part["cx_js"] for part in html_parts]
×
109

110
    cx_license = ""
×
111
    for part in html_parts:
×
112
        if part.get("cx_license"):
×
113
            cx_license = part["cx_license"]
×
114
            break
×
115

116
    iframe_width = 0
×
117
    iframe_height = 0
×
118
    chart_count = len(canvases)
×
119

120
    canvas_table = '<div class="d-flex flex-column">'
×
121

122
    while chart_count > 0:
×
123
        candidate_width = 0
×
124
        candidate_height = 0
×
125

126
        canvas_table += '<div class="d-flex flex-row">'
×
127
        for c in range(columns):
×
128
            canvas_table += '<div class="p-2">'
×
129
            if chart_count > 0:
×
130
                canvas_table += canvases[chart_count - 1]
×
131

132
                candidate_width += render_targets[chart_count - 1].width
×
133
                if render_targets[chart_count - 1].height > candidate_height:
×
134
                    candidate_height = render_targets[chart_count - 1].height
×
135

136
            canvas_table += "</div>"
×
137
            chart_count = chart_count - 1
×
138

139
        canvas_table += "</div>"
×
140

141
        if candidate_width > iframe_width:
×
142
            iframe_width = candidate_width
×
143
        iframe_height += candidate_height
×
144

145
    canvas_table += "</div>"
×
146

147
    iframe_width += _cx_iframe_padding
×
148
    iframe_height += _cx_iframe_padding
×
149

150
    js_functions = "\n".join(
×
151
        [_cx_fx_template.replace("@code@", fx) for fx in functions]
152
    )
153

154
    css_url = _cx_default_css_url
×
155
    js_url = _cx_default_js_url
×
156
    if CanvasXpress.cdn_edition() is not None:
×
157
        css_url = _cx_versioned_css_url.replace(
×
158
            "@cx_version@", CanvasXpress.cdn_edition()
159
        )
160
        js_url = _cx_versioned_js_url.replace(
×
161
            "@cx_version@", CanvasXpress.cdn_edition()
162
        )
163

164
    html = (
×
165
        _cx_html_template.replace("@canvases@", canvas_table)
166
        .replace("@canvasxpress_license@", cx_license)
167
        .replace("@js_functions@", js_functions)
168
        .replace("@css_url@", css_url)
169
        .replace("@js_url@", js_url)
170
    )
171

NEW
172
    components.html(html, width=iframe_width, height=iframe_height)
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc