svgsimplegraph


Namesvgsimplegraph JSON
Version 2.0.3 PyPI version JSON
download
home_pageNone
SummarySimple SVG graphing package
upload_time2024-07-16 22:12:47
maintainerNone
docs_urlNone
authorGarrett M. Petersen
requires_pythonNone
licenseMIT
keywords graph svg base64 svg simple graph
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # svgsimplegraph

This is a simple little graphing package for making graphs and exporting them as raw or base64-encoded SVGs.

You can also upload the SVGs to your GitHub account as Gists, so they may be embedded in any website!

## Installing svgsimplegraph

Install svgsimplegraph by typing

```
pip install svgsimplegraph
```

in your terminal.

## Graph Types

### Categorical Graph

The categorical graph is for data that comes in distinct categories. It can generate a bar chart, a stacked bar chart, dots, or lines.

Here is an example of how to make a graph:

```
from svgsimplegraph import CategoricalGraph

graph = CategoricalGraph(
        width=600,
        height=400,
        bar_width=30,
        stacked=False,
        background_color="#404040",
        title="Categorical Graph",
    )

graph.x_labels = ["A", "B", "C", "D", "E"]
graph.x_axis_label = "X Axis"
graph.primary_y_axis_label = "Primary Y Axis"

# Skip adding a legend_label to exclude a series from the legend
graph.add_series([10, 20, 30, 40, 50], legend_label="Series 1")
graph.add_series([15, 25, 5, 44, 56], legend_label="Series 2")
graph.add_series([5, 35, 10, 33, 40], legend_label="Series 3", series_type="line")
graph.add_series([35, 56, 25, 5, 44], legend_label="Series 4", series_type="dot")

# You can use vertical or horizontal lines to mark specific values
graph.add_vertical_line(
    x=2.5,
    label="Vertical Line",
    label_x_position="right",
    label_y_position="top",
    rotate_label=True,
)

# Get the SVG string in base64 format
svg_base64 = graph.to_base64_src()

# Print the SVG string in an img tag so your browser can display it
print(f"\n<img src='{svg_base64}' />")

# Alternatively, you can get the raw SVG code with render()
raw_svg = graph.render()
print(raw_svg)
```

![Example categorical graph](https://github.com/GarrettPetersen/svgsimplegraph/blob/master/images/example_categorical.svg)

### Toggle Graph

You can combine multiple CategoricalGraphs into a ToggleGraph with interactive buttons.

```
from svgsimplegraph import ToggleGraph
from svgsimplegraph import CategoricalGraph

# Let's make some categorical graphs to put in our ToggleGraph
graph1 = CategoricalGraph(
    width=600,
    height=400,
    bar_width=30,
    title="Categorical Graph 1",
    watermark="<rect x='250' y='150' width='100' height='100' fill='rgba(255, 0, 0, 0.5)' />",
    primary_tick_prefix="$",
    background_color="#404040",
)

graph1.x_labels = ["A", "B", "C", "D", "E"]
graph1.x_axis_label = "X Axis"
graph1.primary_y_axis_label = "Primary Y Axis"

graph1.add_series([10, 20, -30, 40, 50])

graph2 = CategoricalGraph(
    width=600,
    height=400,
    bar_width=30,
    title="Categorical Graph 2",
    watermark="<rect x='250' y='150' width='100' height='100' fill='rgba(255, 0, 0, 0.5)' />",
    primary_tick_prefix="$",
    background_color="#404040",
)

graph2.x_labels = ["A", "B", "C", "D", "E"]
graph2.x_axis_label = "X Axis"
graph2.primary_y_axis_label = "Primary Y Axis"

graph2.add_series([20, 10, 30, 50, 10], legend_label="Legend Label")

graph3 = CategoricalGraph(
    width=600,
    height=400,
    bar_width=30,
    title="Categorical Graph 3",
    watermark="<rect x='250' y='150' width='100' height='100' fill='rgba(255, 0, 0, 0.5)' />",
    primary_tick_prefix="$",
    background_color="#404040",
)

graph3.x_labels = ["A", "B", "C", "D", "E"]
graph3.x_axis_label = "X Axis"
graph3.primary_y_axis_label = "Primary Y Axis"

graph3.add_series([10, 25, 30, 40, 50])

graph4 = CategoricalGraph(
    width=600,
    height=400,
    bar_width=30,
    title="Categorical Graph 4",
    watermark="<rect x='250' y='150' width='100' height='100' fill='rgba(255, 0, 0, 0.5)' />",
    primary_tick_prefix="$",
    background_color="#404040",
)

graph4.x_labels = ["A", "B", "C", "D", "E"]
graph4.x_axis_label = "X Axis"
graph4.primary_y_axis_label = "Primary Y Axis"

graph4.add_series([10, 10, 10, 50, 5])

toggle = ToggleGraph()

toggle.add_graph(graph1, label="Graph 1")
toggle.add_graph(graph2, label="Graph 2")
toggle.add_graph(graph3, label="Graph 3")
toggle.add_graph(graph4, label="Graph 4")

# You can't put this in the src of an image tag, because it implicitly contains
# JavaScript, which cannot execute from within an image. So we include it as the
# data within an object.
svg_base64 = toggle.to_base64_src()

print(f"\n<object type='image/svg+xml' data='{svg_base64}' />")

# Alternatively we can just print the SVG code
print(toggle.render())
```

![Toggle graph example](https://github.com/GarrettPetersen/svgsimplegraph/blob/master/images/example_toggle_graph.svg)

The interactive elements of the above graph are not useable in this Markdown doc.

### Ribbon Graph

The ribbon graph is for comparing two numbers on the same scale and a third number on a different scale (represented through color).

The three series must be added in order, with the first representing the back of the ribbon, the second representing the point, and the (optional) third representing the color.

Here's an example:

```
from svgsimplegraph import RibbonGraph

graph = RibbonGraph(
    width=600,
    height=400,
    bar_width=30,
    background_color="#404040",
    title="Ribbon Graph",
)

graph.x_labels = ["A", "B", "C", "D", "E"]
graph.x_axis_label = "X Axis"
graph.primary_y_axis_label = "Primary Y Axis"

graph.add_series([10, 20, 30, 40, 50], legend_label="Series 1", print_values=True)
graph.add_series([20, 30, 40, 30, 20], legend_label="Series 2", print_values=True)
graph.add_series(
    [-10, -20, 30, 20, 10], legend_label="Color Series", print_values=True
)

# Get the SVG string in base64 format
svg_base64 = graph.to_base64_src()

# Print the SVG string in an img tag so your browser can display it
print(f"\n<img src='{svg_base64}' />")

# Alternatively, you can get the raw SVG code with render()
raw_svg = graph.render()
print(raw_svg)
```

![Example ribbon graph](https://github.com/GarrettPetersen/svgsimplegraph/blob/master/images/example_ribbon.svg)

### Bubble and Arrow Graph

The bubble and arrow graph is for displaying relationships between nodes in a network.

The user adds bubbles, which are displayed in clockwise order around a larger circle. Then the user can add arrows that exit from one bubble and enter another. Arrow width is scaled to show more important connections.

Here's an example:

```
from svgsimplegraph import BubbleAndArrowGraph

graph = BubbleAndArrowGraph(
    width=400,
    height=400,
    background_color="#ffffff",
    title="Bubble and Arrow Graph",
)

# Optional str label param can be referred to later when defining arrows
graph.add_bubble(100, None, "Bubble 0", label="big_bubble")

# Otherwise bubbles must be referred to by their index number
graph.add_bubble(50, 25, "Bubble 1")
graph.add_bubble(25, 12.5, "Bubble 2")

graph.add_arrow(
    origin="big_bubble",
    destination=1,
    size=60,
)
graph.add_arrow(
    origin="big_bubble",
    destination=2,
    size=40,
)
graph.add_arrow(
    origin=1,
    destination=2,
    size=30,
)

# Arrows pointing to their origin will loop around
graph.add_arrow(
    origin=2,
    destination=2,
    size=20,
)

# Get the SVG string in base64 format
svg_base64 = graph.to_base64_src()

# Print the SVG string in an img tag so your browser can display it
print(f"\n<img src='{svg_base64}' />")

# Alternatively, you can get the raw SVG code with render()
raw_svg = graph.render()
print(raw_svg)
```

![Example bubble and arrow graph](https://github.com/GarrettPetersen/svgsimplegraph/blob/master/images/example_bubble_and_arrow.svg)

## GitHub Gist integration

The `upload_to_github_gist` function allows you to render your graph and upload it to your GitHub account as a Gist.

To do this, you'll need an access token. Go to your github account and navigate to settings. Then click on Developer settings > Personal access tokens > Fine-grained tokens.

Click the Generate new token button in the top right of the screen. GitHub will prompt you to login. Set a token name (something like "gist-access-token") and an expiration.

Scroll down to Permissions and expand the Account permissions box. Then turn on read and write access for Gists only (you should not use this token for anything else). Finally, click the gree Generate token button at the bottom of the screen.

Now you should see a screen showing your token. This is the only time Github will show you this token, so save it somewhere safe.

Assuming you've done all that, you can use the token to turn your graphs into gists.

```
from svgsimplegraph import CategoricalGraph

GITHUB_ACCESS_TOKEN = "your_token_goes_here"

# Create an instance of a graph
graph = CategoricalGraph(
    width=600,
    height=400,
    bar_width=30,
    stacked=False,
    background_color="#404040",
)

graph.x_labels = ["A", "B", "C", "D", "E"]
graph.x_axis_label = "X Axis"
graph.primary_y_axis_label = "Primary Y Axis"

graph.add_series([10, 20, 30, 40, 50], legend_label="Series 1")

svg_url = graph.upload_to_github_gist(GITHUB_ACCESS_TOKEN, "my_categorical_graph")
```

The `svg_url` variable now contains a string with the url of your new SVG, ready to be embedded in any website!

## Watermarks

When you initialize a graph, you can use the watermark variable to add arbitrary svg code to the graph. It is recommended to make your watermark partially transparent, as it will be placed on top of your graph.



            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "svgsimplegraph",
    "maintainer": null,
    "docs_url": null,
    "requires_python": null,
    "maintainer_email": null,
    "keywords": "graph, svg, base64, svg simple graph",
    "author": "Garrett M. Petersen",
    "author_email": "garrett.m.petersen@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/dc/6f/3753eb8b3276e7e0c88a396e59c5f8e804f4e173ef1d16f7a7859b5c36cb/svgsimplegraph-2.0.3.tar.gz",
    "platform": null,
    "description": "# svgsimplegraph\n\nThis is a simple little graphing package for making graphs and exporting them as raw or base64-encoded SVGs.\n\nYou can also upload the SVGs to your GitHub account as Gists, so they may be embedded in any website!\n\n## Installing svgsimplegraph\n\nInstall svgsimplegraph by typing\n\n```\npip install svgsimplegraph\n```\n\nin your terminal.\n\n## Graph Types\n\n### Categorical Graph\n\nThe categorical graph is for data that comes in distinct categories. It can generate a bar chart, a stacked bar chart, dots, or lines.\n\nHere is an example of how to make a graph:\n\n```\nfrom svgsimplegraph import CategoricalGraph\n\ngraph = CategoricalGraph(\n        width=600,\n        height=400,\n        bar_width=30,\n        stacked=False,\n        background_color=\"#404040\",\n        title=\"Categorical Graph\",\n    )\n\ngraph.x_labels = [\"A\", \"B\", \"C\", \"D\", \"E\"]\ngraph.x_axis_label = \"X Axis\"\ngraph.primary_y_axis_label = \"Primary Y Axis\"\n\n# Skip adding a legend_label to exclude a series from the legend\ngraph.add_series([10, 20, 30, 40, 50], legend_label=\"Series 1\")\ngraph.add_series([15, 25, 5, 44, 56], legend_label=\"Series 2\")\ngraph.add_series([5, 35, 10, 33, 40], legend_label=\"Series 3\", series_type=\"line\")\ngraph.add_series([35, 56, 25, 5, 44], legend_label=\"Series 4\", series_type=\"dot\")\n\n# You can use vertical or horizontal lines to mark specific values\ngraph.add_vertical_line(\n    x=2.5,\n    label=\"Vertical Line\",\n    label_x_position=\"right\",\n    label_y_position=\"top\",\n    rotate_label=True,\n)\n\n# Get the SVG string in base64 format\nsvg_base64 = graph.to_base64_src()\n\n# Print the SVG string in an img tag so your browser can display it\nprint(f\"\\n<img src='{svg_base64}' />\")\n\n# Alternatively, you can get the raw SVG code with render()\nraw_svg = graph.render()\nprint(raw_svg)\n```\n\n![Example categorical graph](https://github.com/GarrettPetersen/svgsimplegraph/blob/master/images/example_categorical.svg)\n\n### Toggle Graph\n\nYou can combine multiple CategoricalGraphs into a ToggleGraph with interactive buttons.\n\n```\nfrom svgsimplegraph import ToggleGraph\nfrom svgsimplegraph import CategoricalGraph\n\n# Let's make some categorical graphs to put in our ToggleGraph\ngraph1 = CategoricalGraph(\n    width=600,\n    height=400,\n    bar_width=30,\n    title=\"Categorical Graph 1\",\n    watermark=\"<rect x='250' y='150' width='100' height='100' fill='rgba(255, 0, 0, 0.5)' />\",\n    primary_tick_prefix=\"$\",\n    background_color=\"#404040\",\n)\n\ngraph1.x_labels = [\"A\", \"B\", \"C\", \"D\", \"E\"]\ngraph1.x_axis_label = \"X Axis\"\ngraph1.primary_y_axis_label = \"Primary Y Axis\"\n\ngraph1.add_series([10, 20, -30, 40, 50])\n\ngraph2 = CategoricalGraph(\n    width=600,\n    height=400,\n    bar_width=30,\n    title=\"Categorical Graph 2\",\n    watermark=\"<rect x='250' y='150' width='100' height='100' fill='rgba(255, 0, 0, 0.5)' />\",\n    primary_tick_prefix=\"$\",\n    background_color=\"#404040\",\n)\n\ngraph2.x_labels = [\"A\", \"B\", \"C\", \"D\", \"E\"]\ngraph2.x_axis_label = \"X Axis\"\ngraph2.primary_y_axis_label = \"Primary Y Axis\"\n\ngraph2.add_series([20, 10, 30, 50, 10], legend_label=\"Legend Label\")\n\ngraph3 = CategoricalGraph(\n    width=600,\n    height=400,\n    bar_width=30,\n    title=\"Categorical Graph 3\",\n    watermark=\"<rect x='250' y='150' width='100' height='100' fill='rgba(255, 0, 0, 0.5)' />\",\n    primary_tick_prefix=\"$\",\n    background_color=\"#404040\",\n)\n\ngraph3.x_labels = [\"A\", \"B\", \"C\", \"D\", \"E\"]\ngraph3.x_axis_label = \"X Axis\"\ngraph3.primary_y_axis_label = \"Primary Y Axis\"\n\ngraph3.add_series([10, 25, 30, 40, 50])\n\ngraph4 = CategoricalGraph(\n    width=600,\n    height=400,\n    bar_width=30,\n    title=\"Categorical Graph 4\",\n    watermark=\"<rect x='250' y='150' width='100' height='100' fill='rgba(255, 0, 0, 0.5)' />\",\n    primary_tick_prefix=\"$\",\n    background_color=\"#404040\",\n)\n\ngraph4.x_labels = [\"A\", \"B\", \"C\", \"D\", \"E\"]\ngraph4.x_axis_label = \"X Axis\"\ngraph4.primary_y_axis_label = \"Primary Y Axis\"\n\ngraph4.add_series([10, 10, 10, 50, 5])\n\ntoggle = ToggleGraph()\n\ntoggle.add_graph(graph1, label=\"Graph 1\")\ntoggle.add_graph(graph2, label=\"Graph 2\")\ntoggle.add_graph(graph3, label=\"Graph 3\")\ntoggle.add_graph(graph4, label=\"Graph 4\")\n\n# You can't put this in the src of an image tag, because it implicitly contains\n# JavaScript, which cannot execute from within an image. So we include it as the\n# data within an object.\nsvg_base64 = toggle.to_base64_src()\n\nprint(f\"\\n<object type='image/svg+xml' data='{svg_base64}' />\")\n\n# Alternatively we can just print the SVG code\nprint(toggle.render())\n```\n\n![Toggle graph example](https://github.com/GarrettPetersen/svgsimplegraph/blob/master/images/example_toggle_graph.svg)\n\nThe interactive elements of the above graph are not useable in this Markdown doc.\n\n### Ribbon Graph\n\nThe ribbon graph is for comparing two numbers on the same scale and a third number on a different scale (represented through color).\n\nThe three series must be added in order, with the first representing the back of the ribbon, the second representing the point, and the (optional) third representing the color.\n\nHere's an example:\n\n```\nfrom svgsimplegraph import RibbonGraph\n\ngraph = RibbonGraph(\n    width=600,\n    height=400,\n    bar_width=30,\n    background_color=\"#404040\",\n    title=\"Ribbon Graph\",\n)\n\ngraph.x_labels = [\"A\", \"B\", \"C\", \"D\", \"E\"]\ngraph.x_axis_label = \"X Axis\"\ngraph.primary_y_axis_label = \"Primary Y Axis\"\n\ngraph.add_series([10, 20, 30, 40, 50], legend_label=\"Series 1\", print_values=True)\ngraph.add_series([20, 30, 40, 30, 20], legend_label=\"Series 2\", print_values=True)\ngraph.add_series(\n    [-10, -20, 30, 20, 10], legend_label=\"Color Series\", print_values=True\n)\n\n# Get the SVG string in base64 format\nsvg_base64 = graph.to_base64_src()\n\n# Print the SVG string in an img tag so your browser can display it\nprint(f\"\\n<img src='{svg_base64}' />\")\n\n# Alternatively, you can get the raw SVG code with render()\nraw_svg = graph.render()\nprint(raw_svg)\n```\n\n![Example ribbon graph](https://github.com/GarrettPetersen/svgsimplegraph/blob/master/images/example_ribbon.svg)\n\n### Bubble and Arrow Graph\n\nThe bubble and arrow graph is for displaying relationships between nodes in a network.\n\nThe user adds bubbles, which are displayed in clockwise order around a larger circle. Then the user can add arrows that exit from one bubble and enter another. Arrow width is scaled to show more important connections.\n\nHere's an example:\n\n```\nfrom svgsimplegraph import BubbleAndArrowGraph\n\ngraph = BubbleAndArrowGraph(\n    width=400,\n    height=400,\n    background_color=\"#ffffff\",\n    title=\"Bubble and Arrow Graph\",\n)\n\n# Optional str label param can be referred to later when defining arrows\ngraph.add_bubble(100, None, \"Bubble 0\", label=\"big_bubble\")\n\n# Otherwise bubbles must be referred to by their index number\ngraph.add_bubble(50, 25, \"Bubble 1\")\ngraph.add_bubble(25, 12.5, \"Bubble 2\")\n\ngraph.add_arrow(\n    origin=\"big_bubble\",\n    destination=1,\n    size=60,\n)\ngraph.add_arrow(\n    origin=\"big_bubble\",\n    destination=2,\n    size=40,\n)\ngraph.add_arrow(\n    origin=1,\n    destination=2,\n    size=30,\n)\n\n# Arrows pointing to their origin will loop around\ngraph.add_arrow(\n    origin=2,\n    destination=2,\n    size=20,\n)\n\n# Get the SVG string in base64 format\nsvg_base64 = graph.to_base64_src()\n\n# Print the SVG string in an img tag so your browser can display it\nprint(f\"\\n<img src='{svg_base64}' />\")\n\n# Alternatively, you can get the raw SVG code with render()\nraw_svg = graph.render()\nprint(raw_svg)\n```\n\n![Example bubble and arrow graph](https://github.com/GarrettPetersen/svgsimplegraph/blob/master/images/example_bubble_and_arrow.svg)\n\n## GitHub Gist integration\n\nThe `upload_to_github_gist` function allows you to render your graph and upload it to your GitHub account as a Gist.\n\nTo do this, you'll need an access token. Go to your github account and navigate to settings. Then click on Developer settings > Personal access tokens > Fine-grained tokens.\n\nClick the Generate new token button in the top right of the screen. GitHub will prompt you to login. Set a token name (something like \"gist-access-token\") and an expiration.\n\nScroll down to Permissions and expand the Account permissions box. Then turn on read and write access for Gists only (you should not use this token for anything else). Finally, click the gree Generate token button at the bottom of the screen.\n\nNow you should see a screen showing your token. This is the only time Github will show you this token, so save it somewhere safe.\n\nAssuming you've done all that, you can use the token to turn your graphs into gists.\n\n```\nfrom svgsimplegraph import CategoricalGraph\n\nGITHUB_ACCESS_TOKEN = \"your_token_goes_here\"\n\n# Create an instance of a graph\ngraph = CategoricalGraph(\n    width=600,\n    height=400,\n    bar_width=30,\n    stacked=False,\n    background_color=\"#404040\",\n)\n\ngraph.x_labels = [\"A\", \"B\", \"C\", \"D\", \"E\"]\ngraph.x_axis_label = \"X Axis\"\ngraph.primary_y_axis_label = \"Primary Y Axis\"\n\ngraph.add_series([10, 20, 30, 40, 50], legend_label=\"Series 1\")\n\nsvg_url = graph.upload_to_github_gist(GITHUB_ACCESS_TOKEN, \"my_categorical_graph\")\n```\n\nThe `svg_url` variable now contains a string with the url of your new SVG, ready to be embedded in any website!\n\n## Watermarks\n\nWhen you initialize a graph, you can use the watermark variable to add arbitrary svg code to the graph. It is recommended to make your watermark partially transparent, as it will be placed on top of your graph.\n\n\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Simple SVG graphing package",
    "version": "2.0.3",
    "project_urls": {
        "Source Code": "https://github.com/GarrettPetersen/svgsimplegraph"
    },
    "split_keywords": [
        "graph",
        " svg",
        " base64",
        " svg simple graph"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "6193e6344124a2db60e18dc873d85b93345e4cb11bdf149ac1a41b28296c855e",
                "md5": "be227b9c98f8aee07d64d97d3c5f7faf",
                "sha256": "8c85ba39e56163ecb24ca72464feb40272fe166fa2612be4c87e0562b6b46ec3"
            },
            "downloads": -1,
            "filename": "svgsimplegraph-2.0.3-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "be227b9c98f8aee07d64d97d3c5f7faf",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 36225,
            "upload_time": "2024-07-16T22:12:44",
            "upload_time_iso_8601": "2024-07-16T22:12:44.779666Z",
            "url": "https://files.pythonhosted.org/packages/61/93/e6344124a2db60e18dc873d85b93345e4cb11bdf149ac1a41b28296c855e/svgsimplegraph-2.0.3-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "dc6f3753eb8b3276e7e0c88a396e59c5f8e804f4e173ef1d16f7a7859b5c36cb",
                "md5": "6af66ef969c1a01bff5a2632157f67db",
                "sha256": "95bd1397a6d18383b0013eed719191a88b21a770d64edc8022ae7ae423c1a8b5"
            },
            "downloads": -1,
            "filename": "svgsimplegraph-2.0.3.tar.gz",
            "has_sig": false,
            "md5_digest": "6af66ef969c1a01bff5a2632157f67db",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 33408,
            "upload_time": "2024-07-16T22:12:47",
            "upload_time_iso_8601": "2024-07-16T22:12:47.674463Z",
            "url": "https://files.pythonhosted.org/packages/dc/6f/3753eb8b3276e7e0c88a396e59c5f8e804f4e173ef1d16f7a7859b5c36cb/svgsimplegraph-2.0.3.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-07-16 22:12:47",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "GarrettPetersen",
    "github_project": "svgsimplegraph",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "svgsimplegraph"
}
        
Elapsed time: 0.56052s